diff options
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.patch | 418 |
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 |