s3c2442: R.I.P.
[openwrt/svn-archive/archive.git] / target / linux / s3c24xx / patches-2.6.30 / 060-spi-gpio-non-blocking.patch
diff --git a/target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch b/target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch
deleted file mode 100644 (file)
index 3dcf9c0..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
---- a/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
-+++ b/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
-@@ -21,7 +21,8 @@ struct s3c2410_spigpio_info {
-       int                      num_chipselect;
-       int                      bus_num;
--      void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs);
-+      int                      non_blocking_transfer;
-+      void (*chip_select)(struct s3c2410_spigpio_info *spi, int csid, int cs);
- };
---- a/drivers/spi/spi_bitbang.c
-+++ b/drivers/spi/spi_bitbang.c
-@@ -264,6 +264,123 @@ static int spi_bitbang_bufs(struct spi_d
-  * Drivers can provide word-at-a-time i/o primitives, or provide
-  * transfer-at-a-time ones to leverage dma or fifo hardware.
-  */
-+
-+/* Synchronous non blocking transfer */ 
-+int
-+spi_bitbang_transfer_sync(struct spi_device *spi, struct spi_message *m)
-+{
-+      struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master);
-+      struct spi_transfer *t;
-+      unsigned long flags;
-+      int cs_change = 1;
-+      int status;
-+      int nsecs;
-+      int (*setup_transfer)(struct spi_device *, struct spi_transfer *);
-+
-+      /* FIXME this is made-up ... the correct value is known to
-+       * word-at-a-time bitbang code, and presumably chipselect()
-+       * should enforce these requirements too?
-+       */
-+      nsecs = 100;
-+      cs_change = 1;
-+      status = 0;
-+      setup_transfer = NULL;
-+
-+      local_irq_save(flags);
-+      list_for_each_entry (t, &m->transfers, transfer_list) {
-+              /* override or restore speed and wordsize */
-+              if (t->speed_hz || t->bits_per_word) {
-+                      setup_transfer = bitbang->setup_transfer;
-+                      if (!setup_transfer) {
-+                              status = -ENOPROTOOPT;
-+                              break;
-+                      }
-+              }
-+              if (setup_transfer) {
-+                      status = setup_transfer(spi, t);
-+                      if (status < 0)
-+                              break;
-+              }
-+              
-+              /* set up default clock polarity, and activate chip;
-+               * this implicitly updates clock and spi modes as
-+               * previously recorded for this device via setup().
-+               * (and also deselects any other chip that might be
-+               * selected ...)
-+               */
-+              
-+              if (cs_change) {
-+                      bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
-+                      ndelay(nsecs);
-+              }
-+
-+              cs_change = t->cs_change;
-+              if (!t->tx_buf && !t->rx_buf && t->len) {
-+                      status = -EINVAL;
-+                      break;
-+              }
-+              
-+              /* transfer data.  the lower level code handles any
-+               * new dma mappings it needs. our caller always gave
-+               * us dma-safe buffers.
-+               */
-+              if (t->len) {
-+                      /* REVISIT dma API still needs a designated
-+                       * DMA_ADDR_INVALID; ~0 might be better.
-+                       */
-+                      if (!m->is_dma_mapped)
-+                              t->rx_dma = t->tx_dma = 0;
-+                      status = bitbang->txrx_bufs(spi, t);
-+              }
-+
-+              if (status > 0)
-+                      m->actual_length += status;
-+              if (status != t->len) {
-+                      /* always report some kind of error */
-+                      if (status >= 0)
-+                              status = -EREMOTEIO;
-+                      break;
-+              }
-+              status = 0;
-+                      /* protocol tweaks before next transfer */
-+              if (t->delay_usecs)
-+                      udelay(t->delay_usecs);
-+                      if (!cs_change)
-+                      continue;
-+              if (t->transfer_list.next == &m->transfers)
-+                      break;
-+                      /* sometimes a short mid-message deselect of the chip
-+               * may be needed to terminate a mode or command
-+               */
-+              ndelay(nsecs);
-+              bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
-+              ndelay(nsecs);
-+      }
-+      
-+      m->status = status;
-+      if (m->complete)
-+              m->complete(m->context);
-+
-+      /* restore speed and wordsize */
-+      if (setup_transfer)
-+              setup_transfer(spi, NULL);
-+
-+      /* normally deactivate chipselect ... unless no error and
-+       * cs_change has hinted that the next message will probably
-+       * be for this chip too.
-+       */
-+      if (!(status == 0 && cs_change)) {
-+              ndelay(nsecs);
-+              bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
-+              ndelay(nsecs);
-+      }
-+
-+      local_irq_restore(flags);
-+
-+      return status;
-+}
-+EXPORT_SYMBOL_GPL(spi_bitbang_transfer_sync);
-+
- static void bitbang_work(struct work_struct *work)
- {
-       struct spi_bitbang      *bitbang =
-@@ -274,120 +391,13 @@ static void bitbang_work(struct work_str
-       bitbang->busy = 1;
-       while (!list_empty(&bitbang->queue)) {
-               struct spi_message      *m;
--              struct spi_device       *spi;
--              unsigned                nsecs;
--              struct spi_transfer     *t = NULL;
--              unsigned                tmp;
--              unsigned                cs_change;
--              int                     status;
--              int                     (*setup_transfer)(struct spi_device *,
--                                              struct spi_transfer *);
-               m = container_of(bitbang->queue.next, struct spi_message,
-                               queue);
-               list_del_init(&m->queue);
--              spin_unlock_irqrestore(&bitbang->lock, flags);
--
--              /* FIXME this is made-up ... the correct value is known to
--               * word-at-a-time bitbang code, and presumably chipselect()
--               * should enforce these requirements too?
--               */
--              nsecs = 100;
--
--              spi = m->spi;
--              tmp = 0;
--              cs_change = 1;
--              status = 0;
--              setup_transfer = NULL;
--
--              list_for_each_entry (t, &m->transfers, transfer_list) {
--
--                      /* override or restore speed and wordsize */
--                      if (t->speed_hz || t->bits_per_word) {
--                              setup_transfer = bitbang->setup_transfer;
--                              if (!setup_transfer) {
--                                      status = -ENOPROTOOPT;
--                                      break;
--                              }
--                      }
--                      if (setup_transfer) {
--                              status = setup_transfer(spi, t);
--                              if (status < 0)
--                                      break;
--                      }
--
--                      /* set up default clock polarity, and activate chip;
--                       * this implicitly updates clock and spi modes as
--                       * previously recorded for this device via setup().
--                       * (and also deselects any other chip that might be
--                       * selected ...)
--                       */
--                      if (cs_change) {
--                              bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
--                              ndelay(nsecs);
--                      }
--                      cs_change = t->cs_change;
--                      if (!t->tx_buf && !t->rx_buf && t->len) {
--                              status = -EINVAL;
--                              break;
--                      }
--
--                      /* transfer data.  the lower level code handles any
--                       * new dma mappings it needs. our caller always gave
--                       * us dma-safe buffers.
--                       */
--                      if (t->len) {
--                              /* REVISIT dma API still needs a designated
--                               * DMA_ADDR_INVALID; ~0 might be better.
--                               */
--                              if (!m->is_dma_mapped)
--                                      t->rx_dma = t->tx_dma = 0;
--                              status = bitbang->txrx_bufs(spi, t);
--                      }
--                      if (status > 0)
--                              m->actual_length += status;
--                      if (status != t->len) {
--                              /* always report some kind of error */
--                              if (status >= 0)
--                                      status = -EREMOTEIO;
--                              break;
--                      }
--                      status = 0;
--
--                      /* protocol tweaks before next transfer */
--                      if (t->delay_usecs)
--                              udelay(t->delay_usecs);
--
--                      if (!cs_change)
--                              continue;
--                      if (t->transfer_list.next == &m->transfers)
--                              break;
--
--                      /* sometimes a short mid-message deselect of the chip
--                       * may be needed to terminate a mode or command
--                       */
--                      ndelay(nsecs);
--                      bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
--                      ndelay(nsecs);
--              }
--
--              m->status = status;
--              m->complete(m->context);
--
--              /* restore speed and wordsize */
--              if (setup_transfer)
--                      setup_transfer(spi, NULL);
--
--              /* normally deactivate chipselect ... unless no error and
--               * cs_change has hinted that the next message will probably
--               * be for this chip too.
--               */
--              if (!(status == 0 && cs_change)) {
--                      ndelay(nsecs);
--                      bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
--                      ndelay(nsecs);
--              }
-+              spin_unlock_irqrestore(&bitbang->lock, flags);
-+              spi_bitbang_transfer_sync(m->spi, m);
-               spin_lock_irqsave(&bitbang->lock, flags);
-       }
-       bitbang->busy = 0;
-@@ -459,6 +469,9 @@ int spi_bitbang_start(struct spi_bitbang
-       if (!bitbang->master->transfer)
-               bitbang->master->transfer = spi_bitbang_transfer;
-+      if (!bitbang->master->transfer_sync && bitbang->non_blocking_transfer)
-+              bitbang->master->transfer_sync = spi_bitbang_transfer_sync;
-+
-       if (!bitbang->txrx_bufs) {
-               bitbang->use_dma = 0;
-               bitbang->txrx_bufs = spi_bitbang_bufs;
---- a/drivers/spi/spi_s3c24xx_gpio.c
-+++ b/drivers/spi/spi_s3c24xx_gpio.c
-@@ -91,7 +91,7 @@ static void s3c2410_spigpio_chipselect(s
-       struct s3c2410_spigpio *sg = spidev_to_sg(dev);
-       if (sg->info && sg->info->chip_select)
--              (sg->info->chip_select)(sg->info, value);
-+              (sg->info->chip_select)(sg->info, dev->chip_select, value);
- }
- static int s3c2410_spigpio_probe(struct platform_device *dev)
-@@ -112,14 +112,17 @@ static int s3c2410_spigpio_probe(struct 
-       platform_set_drvdata(dev, sp);
--      /* copy in the plkatform data */
-+      /* copy in the platform data */
-       info = sp->info = dev->dev.platform_data;
-+      master->num_chipselect = info->num_chipselect;
-+
-       /* setup spi bitbang adaptor */
-       sp->bitbang.master = spi_master_get(master);
-       sp->bitbang.master->bus_num = info->bus_num;
-       sp->bitbang.master->num_chipselect = info->num_chipselect;
-       sp->bitbang.chipselect = s3c2410_spigpio_chipselect;
-+      sp->bitbang.non_blocking_transfer = info->non_blocking_transfer;
-       sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0;
-       sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1;
---- a/include/linux/mmc/core.h
-+++ b/include/linux/mmc/core.h
-@@ -129,6 +129,8 @@ struct mmc_request {
- struct mmc_host;
- struct mmc_card;
-+extern void mmc_flush_scheduled_work(void);
-+
- extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
- extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
- extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
---- a/include/linux/mmc/sdio_ids.h
-+++ b/include/linux/mmc/sdio_ids.h
-@@ -25,5 +25,9 @@
- #define SDIO_VENDOR_ID_MARVELL                        0x02df
- #define SDIO_DEVICE_ID_MARVELL_LIBERTAS               0x9103
-+#define SDIO_DEVICE_ID_MARVELL_88W8688                0x9104
-+#define SDIO_VENDOR_ID_ATHEROS                        0x0271
-+#define SDIO_DEVICE_ID_ATHEROS_AR6001         0x0100
-+#define SDIO_DEVICE_ID_ATHEROS_AR6002         0x0200
- #endif
---- a/include/linux/spi/spi_bitbang.h
-+++ b/include/linux/spi/spi_bitbang.h
-@@ -31,6 +31,9 @@ struct spi_bitbang {
-       u8                      use_dma;
-       u8                      flags;          /* extra spi->mode support */
-+      /* Support for synchronous non blocking transfers */
-+      int                     non_blocking_transfer; 
-+
-       struct spi_master       *master;
-       /* setup_transfer() changes clock and/or wordsize to match settings
-@@ -62,6 +65,8 @@ extern void spi_bitbang_cleanup(struct s
- extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m);
- extern int spi_bitbang_setup_transfer(struct spi_device *spi,
-                                     struct spi_transfer *t);
-+extern int spi_bitbang_transfer_sync(struct spi_device *spi,
-+                                    struct spi_message *m);
- /* start or stop queue processing */
- extern int spi_bitbang_start(struct spi_bitbang *spi);
---- a/include/linux/spi/spi.h
-+++ b/include/linux/spi/spi.h
-@@ -204,7 +204,6 @@ static inline void spi_unregister_driver
-  *    SPI slaves, and are numbered from zero to num_chipselects.
-  *    each slave has a chipselect signal, but it's common that not
-  *    every chipselect is connected to a slave.
-- * @dma_alignment: SPI controller constraint on DMA buffers alignment.
-  * @setup: updates the device mode and clocking records used by a
-  *    device's SPI controller; protocol code may call this.  This
-  *    must fail if an unrecognized or unsupported mode is requested.
-@@ -240,17 +239,7 @@ struct spi_master {
-        */
-       u16                     num_chipselect;
--      /* some SPI controllers pose alignment requirements on DMAable
--       * buffers; let protocol drivers know about these requirements.
--       */
--      u16                     dma_alignment;
--
--      /* Setup mode and clock, etc (spi driver may call many times).
--       *
--       * IMPORTANT:  this may be called when transfers to another
--       * device are active.  DO NOT UPDATE SHARED REGISTERS in ways
--       * which could break those transfers.
--       */
-+      /* setup mode and clock, etc (spi driver may call many times) */
-       int                     (*setup)(struct spi_device *spi);
-       /* bidirectional bulk transfers
-@@ -275,6 +264,13 @@ struct spi_master {
-       int                     (*transfer)(struct spi_device *spi,
-                                               struct spi_message *mesg);
-+      /* 
-+       * Synchronous non blocking transfer function. Should guarantee
-+       * data availability when it returns 
-+       */
-+      int                     (*transfer_sync)(struct spi_device *spi,
-+                                              struct spi_message *mesg);
-+
-       /* called on release() to free memory provided by spi_master */
-       void                    (*cleanup)(struct spi_device *spi);
- };
-@@ -584,6 +580,29 @@ spi_async(struct spi_device *spi, struct
-       return spi->master->transfer(spi, message);
- }
-+/**
-+ * spi_non_blocking_transfer - Synchronous, non blocking transfer
-+ * @spi: device with which data will be exchanged
-+ * @message: describes the data transfers with optional completion handlers
-+ * Context: any (irqs may be blocked, etc)
-+ *
-+ * Data is guaranteed to be written or read when this function returns.
-+ *
-+ * Note : This may not be supported by all spi masters.
-+ */
-+
-+static inline int
-+spi_non_blocking_transfer(struct spi_device *spi, struct spi_message *message)
-+{
-+      if (unlikely(!spi->master->transfer_sync)) {
-+              dev_err(&spi->master->dev,
-+                              "non-blocking transfers not supported\n");
-+              return -EIO;
-+      }
-+
-+      return spi->master->transfer_sync(spi, message);
-+}
-+
- /*---------------------------------------------------------------------------*/
- /* All these synchronous SPI transfer routines are utilities layered