From 9f4b323803ff18d87dcc042723b527ee646dddfc 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 Due to changes in mainline prior to submission 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/spi-s3c64xx.c') 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.3 From 900bfe33b6d46058c4dd64d4bff7f287baf2a34e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 5 Jul 2013 18:53:22 +0100 Subject: spi/s3c64xx: Remove unused message queue Since the driver has been converted to use the core message pump code the only use of the messsage queue in the driver is a check to see if it is empty which will always succeed since nothing ever adds to the queue. Just remove the queue. Signed-off-by: Mark Brown Acked-by: Kukjin Kim --- drivers/spi/spi-s3c64xx.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 63e2070c6c14..3fb8c96ece41 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -172,7 +172,6 @@ struct s3c64xx_spi_port_config { * @master: Pointer to the SPI Protocol master. * @cntrlr_info: Platform specific data for the controller this driver manages. * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. - * @queue: To log SPI xfer requests. * @lock: Controller specific lock. * @state: Set of FLAGS to indicate status. * @rx_dmach: Controller's DMA channel for Rx. @@ -193,7 +192,6 @@ struct s3c64xx_spi_driver_data { struct spi_master *master; struct s3c64xx_spi_info *cntrlr_info; struct spi_device *tgl_spi; - struct list_head queue; spinlock_t lock; unsigned long sfr_start; struct completion xfer_completion; @@ -1056,8 +1054,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci; - struct spi_message *msg; - unsigned long flags; int err; sdd = spi_master_get_devdata(spi->master); @@ -1088,21 +1084,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) sci = sdd->cntrlr_info; - spin_lock_irqsave(&sdd->lock, flags); - - list_for_each_entry(msg, &sdd->queue, queue) { - /* Is some mssg is already queued for this device */ - if (msg->spi == spi) { - dev_err(&spi->dev, - "setup: attempt while mssg in queue!\n"); - spin_unlock_irqrestore(&sdd->lock, flags); - err = -EBUSY; - goto err_msgq; - } - } - - spin_unlock_irqrestore(&sdd->lock, flags); - pm_runtime_get_sync(&sdd->pdev->dev); /* Check if we can provide the requested rate */ @@ -1149,7 +1130,6 @@ setup_exit: /* setup() returns with device de-selected */ disable_cs(sdd, spi); -err_msgq: gpio_free(cs->line); spi_set_ctldata(spi, NULL); @@ -1442,7 +1422,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) spin_lock_init(&sdd->lock); init_completion(&sdd->xfer_completion); - INIT_LIST_HEAD(&sdd->queue); ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd); -- cgit v1.2.3 From db0606ecd635de0522191e0200868a92ffc18b4d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 15 Jul 2013 15:11:57 +0900 Subject: spi: s3c64xx: fix checkpatch error and warnings Fix the following checkpatch error and warnings: ERROR: "(foo*)" should be "(foo *)" WARNING: line over 80 characters WARNING: quoted string split across lines Signed-off-by: Jingoo Han Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 3fb8c96ece41..61cffaff78fc 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -336,8 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; - sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); - sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); + sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, + &req, dev, "rx"); + sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, + &req, dev, "tx"); return 1; } @@ -440,7 +442,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) /* Acquire DMA channels */ sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void*)sdd->rx_dma.dmach, dev, "rx"); + (void *)sdd->rx_dma.dmach, dev, "rx"); if (!sdd->rx_dma.ch) { dev_err(dev, "Failed to get RX DMA channel\n"); ret = -EBUSY; @@ -448,7 +450,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) } sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void*)sdd->tx_dma.dmach, dev, "tx"); + (void *)sdd->tx_dma.dmach, dev, "tx"); if (!sdd->tx_dma.ch) { dev_err(dev, "Failed to get TX DMA channel\n"); ret = -EBUSY; @@ -1344,16 +1346,14 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) if (!sdd->pdev->dev.of_node) { res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { - dev_warn(&pdev->dev, "Unable to get SPI tx dma " - "resource. Switching to poll mode\n"); + dev_warn(&pdev->dev, "Unable to get SPI tx dma resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else sdd->tx_dma.dmach = res->start; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { - dev_warn(&pdev->dev, "Unable to get SPI rx dma " - "resource. Switching to poll mode\n"); + dev_warn(&pdev->dev, "Unable to get SPI rx dma resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else sdd->rx_dma.dmach = res->start; -- cgit v1.2.3 From c65bc4a8df3cd806e1868992bbc818b1267072d5 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 16 Jul 2013 08:53:33 +0900 Subject: spi: s3c64xx: fix printk warnings Fix the following build warnings when LPAE is enabled: drivers/spi/spi-s3c64xx.c:1466:2: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' [-Wformat] drivers/spi/spi-s3c64xx.c:1466:2: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'resource_size_t' [-Wformat] Use vsprintf extension %pR to format resource. Signed-off-by: Jingoo Han Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 61cffaff78fc..702a5362aaac 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1443,8 +1443,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n", sdd->port_id, master->num_chipselect); - dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", - mem_res->end, mem_res->start, + dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tDMA=[Rx-%d, Tx-%d]\n", + mem_res, sdd->rx_dma.dmach, sdd->tx_dma.dmach); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3 From b998aca8ade221d592c8fc6b00687f2c4034d918 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 17 Jul 2013 17:54:11 +0900 Subject: spi: s3c64xx: fix casting warning sdd->ops->request is unsigned int, not unsigned long. Also, sdd->rx_dma.ch is a 'struct dma_chan *'. Thus, (void *) is converted to (struct dma_chan *)(unsigned long), in order to fix possible sparse warnings. Signed-off-by: Jingoo Han Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 702a5362aaac..c9d0b1273be9 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -336,10 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; - sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, - &req, dev, "rx"); - sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, - &req, dev, "tx"); + sdd->rx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( + sdd->rx_dma.dmach, &req, dev, "rx"); + sdd->tx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( + sdd->tx_dma.dmach, &req, dev, "tx"); return 1; } -- cgit v1.2.3 From b1a8e78d173081c303bea88e92a1e1423befca63 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sun, 11 Aug 2013 02:33:28 +0200 Subject: spi: s3c64xx: Zero dma_slave_config struct in prepare_dma() Not all fields of dma_slave_config struct are being initialized by prepare_dma() function, leaving those which are not in undefined state, which can confuse DMA drivers using them. This patch adds call to memset() to zero the struct before initializing a subset of its fields. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index c9d0b1273be9..d67384b3c318 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -392,6 +392,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, struct scatterlist sg; struct dma_async_tx_descriptor *desc; + memset(&config, 0, sizeof(config)); + if (dma->direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); -- cgit v1.2.3 From 0149871c428cc8cb44337703ca46a98a6b541b42 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sun, 11 Aug 2013 02:33:29 +0200 Subject: spi: s3c64xx: Do not request CS GPIO on subsequent calls to .setup() Comments in linux/spi/spi.h and observed behavior show that .setup() callback can be called multiple times without corresponding calls to .cleanup(), what was incorrectly assumed by spi-s3c64xx driver, leading to failures trying to request CS GPIO multiple times. This patch modifies the behavior of spi-s3c64xx driver to request CS GPIO only on first call to .setup() after last .cleanup(). Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index d67384b3c318..2330dceb27cc 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1071,20 +1071,21 @@ static int s3c64xx_spi_setup(struct spi_device *spi) return -ENODEV; } - /* Request gpio only if cs line is asserted by gpio pins */ - if (sdd->cs_gpio) { - err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, - dev_name(&spi->dev)); - if (err) { - dev_err(&spi->dev, - "Failed to get /CS gpio [%d]: %d\n", - cs->line, err); - goto err_gpio_req; + if (!spi_get_ctldata(spi)) { + /* Request gpio only if cs line is asserted by gpio pins */ + if (sdd->cs_gpio) { + err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, + dev_name(&spi->dev)); + if (err) { + dev_err(&spi->dev, + "Failed to get /CS gpio [%d]: %d\n", + cs->line, err); + goto err_gpio_req; + } } - } - if (!spi_get_ctldata(spi)) spi_set_ctldata(spi, cs); + } sci = sdd->cntrlr_info; -- cgit v1.2.3 From 90438c4bf987a653ad8679a4fa25a909f0c642b5 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sun, 11 Aug 2013 02:33:30 +0200 Subject: spi: s3c64xx: Use dmaengine_prep_slave_single() to prepare DMA transfers Since the driver supports only contiguous buffers, there is no need to manually construct a scatterlist with just a single entry, when there is a dedicated helper for this purpose. This patch modifies prepare_dma() function to use available helper instead of manually creating a scatterlist. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 2330dceb27cc..a7a739c89488 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -389,7 +389,6 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, { struct s3c64xx_spi_driver_data *sdd; struct dma_slave_config config; - struct scatterlist sg; struct dma_async_tx_descriptor *desc; memset(&config, 0, sizeof(config)); @@ -412,14 +411,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, dmaengine_slave_config(dma->ch, &config); } - sg_init_table(&sg, 1); - sg_dma_len(&sg) = len; - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), - len, offset_in_page(buf)); - sg_dma_address(&sg) = buf; - - desc = dmaengine_prep_slave_sg(dma->ch, - &sg, 1, dma->direction, DMA_PREP_INTERRUPT); + desc = dmaengine_prep_slave_single(dma->ch, buf, len, + dma->direction, DMA_PREP_INTERRUPT); desc->callback = s3c64xx_spi_dmacb; desc->callback_param = dma; -- cgit v1.2.3 From c12f964357fc6de54252a4134720083d687caa22 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 Aug 2013 19:03:01 +0100 Subject: spi/s3c64xx: Take runtime PM reference even if DMA is not supported We always need the device to be runtime PM enabled to use it so just skip the DMA initialisation not the entire prepare when polling. Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers/spi/spi-s3c64xx.c') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index a7a739c89488..eee1a7b4adc4 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -429,27 +429,26 @@ 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); - - /* Acquire DMA channels */ - sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void *)sdd->rx_dma.dmach, dev, "rx"); - if (!sdd->rx_dma.ch) { - dev_err(dev, "Failed to get RX DMA channel\n"); - ret = -EBUSY; - goto out; - } + if (!is_polling(sdd)) { + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* Acquire DMA channels */ + sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void *)sdd->rx_dma.dmach, dev, "rx"); + if (!sdd->rx_dma.ch) { + dev_err(dev, "Failed to get RX DMA channel\n"); + ret = -EBUSY; + goto out; + } - sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, - (void *)sdd->tx_dma.dmach, dev, "tx"); - if (!sdd->tx_dma.ch) { - dev_err(dev, "Failed to get TX DMA channel\n"); - ret = -EBUSY; - goto out_rx; + sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void *)sdd->tx_dma.dmach, dev, "tx"); + if (!sdd->tx_dma.ch) { + dev_err(dev, "Failed to get TX DMA channel\n"); + ret = -EBUSY; + goto out_rx; + } } ret = pm_runtime_get_sync(&sdd->pdev->dev); -- cgit v1.2.3