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 3dcf9c048..000000000 --- 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 | 
