summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch418
1 files changed, 0 insertions, 418 deletions
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
index 3dcf9c0486..0000000000
--- a/target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch
+++ /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