From d96760f98e8eb9d35a2eace586d8b93b0e58cbd5 Mon Sep 17 00:00:00 2001 From: Girish K S Date: Thu, 27 Jun 2013 12:26:53 +0530 Subject: spi: s3c64xx: add missing check for polling mode After the patch "spi/s3c64xx: Fix non-dmaengine usage" with commit id 563b444e33810f3120838620c990480304e24e63 submitted by Mark Brown, the spi device detection in polling mode breaks. This revealed the missing check for polling during dma prepare. This patch adds the missing check. Signed-off-by: Girish K S Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index eb53df27e7ea..63e2070c6c14 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -434,6 +434,9 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) dma_cap_mask_t mask; int ret; + if (is_polling(sdd)) + return 0; + dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); -- cgit v1.2.1 From e07619539017ac31004a038d1d886e2ed4d0e61a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 10 Jul 2013 09:25:28 +0200 Subject: spi/xilinx: Revert master->setup function removal master->setup() must be initialized to be able to successfully run spi_bitbang_start() and satisfy if/else logic there. "spi: convert drivers to use bits_per_word_mask" (sha1: 24778be20f87d5aadb19624fc768b3159fa43efc) Signed-off-by: Michal Simek Signed-off-by: Mark Brown --- drivers/spi/spi-xilinx.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index fb56fcfdf65e..09a942852593 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -233,6 +233,21 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, return 0; } +static int xilinx_spi_setup(struct spi_device *spi) +{ + /* always return 0, we can not check the number of bits. + * There are cases when SPI setup is called before any driver is + * there, in that case the SPI core defaults to 8 bits, which we + * do not support in some cases. But if we return an error, the + * SPI device would not be registered and no driver can get hold of it + * When the driver is there, it will call SPI setup again with the + * correct number of bits per transfer. + * If a driver setups with the wrong bit number, it will fail when + * it tries to do a transfer + */ + return 0; +} + static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi) { u8 sr; @@ -360,6 +375,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, xspi->bitbang.chipselect = xilinx_spi_chipselect; xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; + xspi->bitbang.master->setup = xilinx_spi_setup; init_completion(&xspi->done); if (!request_mem_region(mem->start, resource_size(mem), -- cgit v1.2.1 From 103ccee4ef1595468cf79c93068d253c7f2d85a8 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 10 Jul 2013 10:38:18 -0600 Subject: spi: revert master->setup function removal for altera and nuc900 Commit 24778be "spi: convert drivers to use bits_per_word_mask" removed what appeared to be redundant code from many drivers. However, it appears that in the spi-bitbang case, these functions are required by the spi-bitbang core, even if they don't do anything. Restore them. For 3.12, the spi-bitbang core should be adjusted not to require these callbacks to exist if they don't need to do anything. This is the equivalent of Michal Simek's patch "spi/xilinx: Revert master->setup function removal", applied to other affected drivers. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-altera.c | 12 ++++++++++++ drivers/spi/spi-nuc900.c | 13 +++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 8a6bb37910da..81b9adb6e766 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c @@ -103,6 +103,16 @@ static void altera_spi_chipsel(struct spi_device *spi, int value) } } +static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) +{ + return 0; +} + +static int altera_spi_setup(struct spi_device *spi) +{ + return 0; +} + static inline unsigned int hw_txbyte(struct altera_spi *hw, int count) { if (hw->tx) { @@ -221,6 +231,7 @@ static int altera_spi_probe(struct platform_device *pdev) master->bus_num = pdev->id; master->num_chipselect = 16; master->mode_bits = SPI_CS_HIGH; + master->setup = altera_spi_setup; hw = spi_master_get_devdata(master); platform_set_drvdata(pdev, hw); @@ -229,6 +240,7 @@ static int altera_spi_probe(struct platform_device *pdev) hw->bitbang.master = spi_master_get(master); if (!hw->bitbang.master) return err; + hw->bitbang.setup_transfer = altera_spi_setupxfer; hw->bitbang.chipselect = altera_spi_chipsel; hw->bitbang.txrx_bufs = altera_spi_txrx; diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 2ad3d74ac021..150d85453c27 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -174,6 +174,17 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw) spin_unlock_irqrestore(&hw->lock, flags); } +static int nuc900_spi_setupxfer(struct spi_device *spi, + struct spi_transfer *t) +{ + return 0; +} + +static int nuc900_spi_setup(struct spi_device *spi) +{ + return 0; +} + static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count) { return hw->tx ? hw->tx[count] : 0; @@ -366,8 +377,10 @@ static int nuc900_spi_probe(struct platform_device *pdev) master->num_chipselect = hw->pdata->num_cs; master->bus_num = hw->pdata->bus_num; hw->bitbang.master = hw->master; + hw->bitbang.setup_transfer = nuc900_spi_setupxfer; hw->bitbang.chipselect = nuc900_spi_chipsel; hw->bitbang.txrx_bufs = nuc900_spi_txrx; + hw->bitbang.master->setup = nuc900_spi_setup; hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (hw->res == NULL) { -- cgit v1.2.1 From e2b0509908aa5e874a1837a733422b6e8b8502b8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 2 Aug 2013 15:03:42 +0200 Subject: spi: rspi: provide port addresses to dmaengine driver via slave configuration Don't rely on shdma dhaengine driver getting DMA slave addresses from its slave configuration. Instead provide those addresses, using a dmaengine_slave_config() call. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index b44a6ac3cec9..5f122d9d2063 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -664,12 +664,13 @@ static irqreturn_t rspi_irq(int irq, void *_sr) static int rspi_request_dma(struct rspi_data *rspi, struct platform_device *pdev) { + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; dma_cap_mask_t mask; struct dma_slave_config cfg; int ret; - if (!rspi_pd) + if (!res || !rspi_pd) return 0; /* The driver assumes no error. */ rspi->dma_width_16bit = rspi_pd->dma_width_16bit; @@ -683,6 +684,8 @@ static int rspi_request_dma(struct rspi_data *rspi, if (rspi->chan_rx) { cfg.slave_id = rspi_pd->dma_rx_id; cfg.direction = DMA_DEV_TO_MEM; + cfg.dst_addr = 0; + cfg.src_addr = res->start + RSPI_SPDR; ret = dmaengine_slave_config(rspi->chan_rx, &cfg); if (!ret) dev_info(&pdev->dev, "Use DMA when rx.\n"); @@ -698,6 +701,8 @@ static int rspi_request_dma(struct rspi_data *rspi, if (rspi->chan_tx) { cfg.slave_id = rspi_pd->dma_tx_id; cfg.direction = DMA_MEM_TO_DEV; + cfg.dst_addr = res->start + RSPI_SPDR; + cfg.src_addr = 0; ret = dmaengine_slave_config(rspi->chan_tx, &cfg); if (!ret) dev_info(&pdev->dev, "Use DMA when tx\n"); -- cgit v1.2.1 From 8d4d08ce8319ae26227c4dd558405963c14c2037 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Tue, 27 Aug 2013 11:15:09 +0900 Subject: spi: spi-rspi: fix inconsistent spin_lock_irqsave This patch fixes the following Smatch warning: CHECK drivers/spi/spi-rspi.c drivers/spi/spi-rspi.c:606 rspi_work() warn: inconsistent returns spin_lock:&rspi->lock: locked (602) unlocked (606) drivers/spi/spi-rspi.c:606 rspi_work() warn: inconsistent returns irqsave:flags: locked (602) unlocked (606) Reported-by: Dan Carpenter Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 5f122d9d2063..00c32320dce8 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -564,8 +564,12 @@ static void rspi_work(struct work_struct *work) unsigned long flags; int ret; - spin_lock_irqsave(&rspi->lock, flags); - while (!list_empty(&rspi->queue)) { + while (1) { + spin_lock_irqsave(&rspi->lock, flags); + if (list_empty(&rspi->queue)) { + spin_unlock_irqrestore(&rspi->lock, flags); + break; + } mesg = list_entry(rspi->queue.next, struct spi_message, queue); list_del_init(&mesg->queue); spin_unlock_irqrestore(&rspi->lock, flags); @@ -595,8 +599,6 @@ static void rspi_work(struct work_struct *work) mesg->status = 0; mesg->complete(mesg->context); - - spin_lock_irqsave(&rspi->lock, flags); } return; -- cgit v1.2.1