bcm63xx: remove 3.3 support
[openwrt/svn-archive/archive.git] / target / linux / brcm63xx / patches-3.3 / 013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch
diff --git a/target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch b/target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch
deleted file mode 100644 (file)
index 7d4d951..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-From cde4384e1037c15e5dd04c68d19c75798b6281dd Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <florian@openwrt.org>
-Date: Fri, 20 Apr 2012 15:37:33 +0200
-Subject: [PATCH] spi/bcm63xx: convert to the pump message infrastructure
-
-This patch converts the bcm63xx SPI driver to use the SPI infrastructure
-pump message queue. Since we were previously sleeping in the SPI
-driver's transfer() function (which is not allowed) this is now fixed as well.
-
-To complete that conversion a certain number of changes have been made:
-- the transfer len is split into multiple hardware transfers in case its
-  size is bigger than the hardware FIFO size
-- the FIFO refill is no longer done in the interrupt context, which was a
-  bad idea leading to quick interrupt handler re-entrancy
-
-Tested-by: Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
-Signed-off-by: Florian Fainelli <florian@openwrt.org>
-Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
----
- drivers/spi/spi-bcm63xx.c |  149 +++++++++++++++++++++++++++------------------
- 1 file changed, 89 insertions(+), 60 deletions(-)
-
---- a/drivers/spi/spi-bcm63xx.c
-+++ b/drivers/spi/spi-bcm63xx.c
-@@ -1,7 +1,7 @@
- /*
-  * Broadcom BCM63xx SPI controller support
-  *
-- * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
-+ * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
-  * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
-  *
-  * This program is free software; you can redistribute it and/or
-@@ -30,6 +30,8 @@
- #include <linux/spi/spi.h>
- #include <linux/completion.h>
- #include <linux/err.h>
-+#include <linux/workqueue.h>
-+#include <linux/pm_runtime.h>
- #include <bcm63xx_dev_spi.h>
-@@ -96,17 +98,12 @@ static const unsigned bcm63xx_spi_freq_t
-       {   391000, SPI_CLK_0_391MHZ }
- };
--static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
--                                    struct spi_transfer *t)
-+static int bcm63xx_spi_check_transfer(struct spi_device *spi,
-+                                      struct spi_transfer *t)
- {
--      struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
-       u8 bits_per_word;
--      u8 clk_cfg, reg;
--      u32 hz;
--      int i;
-       bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
--      hz = (t) ? t->speed_hz : spi->max_speed_hz;
-       if (bits_per_word != 8) {
-               dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
-                       __func__, bits_per_word);
-@@ -119,6 +116,19 @@ static int bcm63xx_spi_setup_transfer(st
-               return -EINVAL;
-       }
-+      return 0;
-+}
-+
-+static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
-+                                    struct spi_transfer *t)
-+{
-+      struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
-+      u32 hz;
-+      u8 clk_cfg, reg;
-+      int i;
-+
-+      hz = (t) ? t->speed_hz : spi->max_speed_hz;
-+
-       /* Find the closest clock configuration */
-       for (i = 0; i < SPI_CLK_MASK; i++) {
-               if (hz >= bcm63xx_spi_freq_table[i][0]) {
-@@ -139,8 +149,6 @@ static int bcm63xx_spi_setup_transfer(st
-       bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
-       dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
-               clk_cfg, hz);
--
--      return 0;
- }
- /* the spi->mode bits understood by this driver: */
-@@ -165,7 +173,7 @@ static int bcm63xx_spi_setup(struct spi_
-               return -EINVAL;
-       }
--      ret = bcm63xx_spi_setup_transfer(spi, NULL);
-+      ret = bcm63xx_spi_check_transfer(spi, NULL);
-       if (ret < 0) {
-               dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
-                       spi->mode & ~MODEBITS);
-@@ -190,28 +198,29 @@ static void bcm63xx_spi_fill_tx_fifo(str
-       bs->remaining_bytes -= size;
- }
--static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
-+static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
-+                                      struct spi_transfer *t)
- {
-       struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
-       u16 msg_ctl;
-       u16 cmd;
-+      /* Disable the CMD_DONE interrupt */
-+      bcm_spi_writeb(bs, 0, SPI_INT_MASK);
-+
-       dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
-               t->tx_buf, t->rx_buf, t->len);
-       /* Transmitter is inhibited */
-       bs->tx_ptr = t->tx_buf;
-       bs->rx_ptr = t->rx_buf;
--      init_completion(&bs->done);
-       if (t->tx_buf) {
-               bs->remaining_bytes = t->len;
-               bcm63xx_spi_fill_tx_fifo(bs);
-       }
--      /* Enable the command done interrupt which
--       * we use to determine completion of a command */
--      bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
-+      init_completion(&bs->done);
-       /* Fill in the Message control register */
-       msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
-@@ -230,33 +239,76 @@ static int bcm63xx_txrx_bufs(struct spi_
-       cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
-       cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
-       bcm_spi_writew(bs, cmd, SPI_CMD);
--      wait_for_completion(&bs->done);
--      /* Disable the CMD_DONE interrupt */
--      bcm_spi_writeb(bs, 0, SPI_INT_MASK);
-+      /* Enable the CMD_DONE interrupt */
-+      bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
-       return t->len - bs->remaining_bytes;
- }
--static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m)
-+static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
- {
--      struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
--      struct spi_transfer *t;
--      int ret = 0;
-+      struct bcm63xx_spi *bs = spi_master_get_devdata(master);
--      if (unlikely(list_empty(&m->transfers)))
--              return -EINVAL;
-+      pm_runtime_get_sync(&bs->pdev->dev);
--      if (bs->stopping)
--              return -ESHUTDOWN;
-+      return 0;
-+}
-+
-+static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
-+{
-+      struct bcm63xx_spi *bs = spi_master_get_devdata(master);
-+
-+      pm_runtime_put(&bs->pdev->dev);
-+
-+      return 0;
-+}
-+
-+static int bcm63xx_spi_transfer_one(struct spi_master *master,
-+                                      struct spi_message *m)
-+{
-+      struct bcm63xx_spi *bs = spi_master_get_devdata(master);
-+      struct spi_transfer *t;
-+      struct spi_device *spi = m->spi;
-+      int status = 0;
-+      unsigned int timeout = 0;
-       list_for_each_entry(t, &m->transfers, transfer_list) {
--              ret += bcm63xx_txrx_bufs(spi, t);
--      }
-+              unsigned int len = t->len;
-+              u8 rx_tail;
--      m->complete(m->context);
-+              status = bcm63xx_spi_check_transfer(spi, t);
-+              if (status < 0)
-+                      goto exit;
-+
-+              /* configure adapter for a new transfer */
-+              bcm63xx_spi_setup_transfer(spi, t);
-+
-+              while (len) {
-+                      /* send the data */
-+                      len -= bcm63xx_txrx_bufs(spi, t);
-+
-+                      timeout = wait_for_completion_timeout(&bs->done, HZ);
-+                      if (!timeout) {
-+                              status = -ETIMEDOUT;
-+                              goto exit;
-+                      }
-+
-+                      /* read out all data */
-+                      rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
-+
-+                      /* Read out all the data */
-+                      if (rx_tail)
-+                              memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
-+              }
-+
-+              m->actual_length += t->len;
-+      }
-+exit:
-+      m->status = status;
-+      spi_finalize_current_message(master);
--      return ret;
-+      return 0;
- }
- /* This driver supports single master mode only. Hence
-@@ -267,39 +319,15 @@ static irqreturn_t bcm63xx_spi_interrupt
-       struct spi_master *master = (struct spi_master *)dev_id;
-       struct bcm63xx_spi *bs = spi_master_get_devdata(master);
-       u8 intr;
--      u16 cmd;
-       /* Read interupts and clear them immediately */
-       intr = bcm_spi_readb(bs, SPI_INT_STATUS);
-       bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
-       bcm_spi_writeb(bs, 0, SPI_INT_MASK);
--      /* A tansfer completed */
--      if (intr & SPI_INTR_CMD_DONE) {
--              u8 rx_tail;
--
--              rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
--
--              /* Read out all the data */
--              if (rx_tail)
--                      memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
--
--              /* See if there is more data to send */
--              if (bs->remaining_bytes > 0) {
--                      bcm63xx_spi_fill_tx_fifo(bs);
--
--                      /* Start the transfer */
--                      bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT,
--                                     SPI_MSG_CTL);
--                      cmd = bcm_spi_readw(bs, SPI_CMD);
--                      cmd |= SPI_CMD_START_IMMEDIATE;
--                      cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
--                      bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
--                      bcm_spi_writew(bs, cmd, SPI_CMD);
--              } else {
--                      complete(&bs->done);
--              }
--      }
-+      /* A transfer completed */
-+      if (intr & SPI_INTR_CMD_DONE)
-+              complete(&bs->done);
-       return IRQ_HANDLED;
- }
-@@ -345,7 +373,6 @@ static int __devinit bcm63xx_spi_probe(s
-       }
-       bs = spi_master_get_devdata(master);
--      init_completion(&bs->done);
-       platform_set_drvdata(pdev, master);
-       bs->pdev = pdev;
-@@ -379,7 +406,9 @@ static int __devinit bcm63xx_spi_probe(s
-       master->bus_num = pdata->bus_num;
-       master->num_chipselect = pdata->num_chipselect;
-       master->setup = bcm63xx_spi_setup;
--      master->transfer = bcm63xx_transfer;
-+      master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
-+      master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
-+      master->transfer_one_message = bcm63xx_spi_transfer_one;
-       bs->speed_hz = pdata->speed_hz;
-       bs->stopping = 0;
-       bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));