Loading drivers/spi/spi-s3c64xx.c +43 −69 Original line number Original line Diff line number Diff line Loading @@ -172,7 +172,6 @@ struct s3c64xx_spi_port_config { * @master: Pointer to the SPI Protocol master. * @master: Pointer to the SPI Protocol master. * @cntrlr_info: Platform specific data for the controller this driver manages. * @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. * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. * @queue: To log SPI xfer requests. * @lock: Controller specific lock. * @lock: Controller specific lock. * @state: Set of FLAGS to indicate status. * @state: Set of FLAGS to indicate status. * @rx_dmach: Controller's DMA channel for Rx. * @rx_dmach: Controller's DMA channel for Rx. Loading @@ -193,7 +192,6 @@ struct s3c64xx_spi_driver_data { struct spi_master *master; struct spi_master *master; struct s3c64xx_spi_info *cntrlr_info; struct s3c64xx_spi_info *cntrlr_info; struct spi_device *tgl_spi; struct spi_device *tgl_spi; struct list_head queue; spinlock_t lock; spinlock_t lock; unsigned long sfr_start; unsigned long sfr_start; struct completion xfer_completion; struct completion xfer_completion; Loading Loading @@ -338,8 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; req.client = &s3c64xx_spi_dma_client; sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); sdd->rx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); 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; return 1; } } Loading Loading @@ -386,9 +386,10 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, { { struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd; struct dma_slave_config config; struct dma_slave_config config; struct scatterlist sg; struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc; memset(&config, 0, sizeof(config)); if (dma->direction == DMA_DEV_TO_MEM) { if (dma->direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); struct s3c64xx_spi_driver_data, rx_dma); Loading @@ -407,14 +408,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, dmaengine_slave_config(dma->ch, &config); dmaengine_slave_config(dma->ch, &config); } } sg_init_table(&sg, 1); desc = dmaengine_prep_slave_single(dma->ch, buf, len, sg_dma_len(&sg) = len; dma->direction, DMA_PREP_INTERRUPT); 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->callback = s3c64xx_spi_dmacb; desc->callback = s3c64xx_spi_dmacb; desc->callback_param = dma; desc->callback_param = dma; Loading @@ -431,9 +426,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) dma_cap_mask_t mask; dma_cap_mask_t mask; int ret; int ret; if (is_polling(sdd)) if (!is_polling(sdd)) { return 0; dma_cap_zero(mask); dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask); Loading @@ -453,6 +446,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) ret = -EBUSY; ret = -EBUSY; goto out_rx; goto out_rx; } } } ret = pm_runtime_get_sync(&sdd->pdev->dev); ret = pm_runtime_get_sync(&sdd->pdev->dev); if (ret < 0) { if (ret < 0) { Loading Loading @@ -1053,8 +1047,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci; struct s3c64xx_spi_info *sci; struct spi_message *msg; unsigned long flags; int err; int err; sdd = spi_master_get_devdata(spi->master); sdd = spi_master_get_devdata(spi->master); Loading @@ -1068,6 +1060,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi) return -ENODEV; return -ENODEV; } } if (!spi_get_ctldata(spi)) { /* Request gpio only if cs line is asserted by gpio pins */ /* Request gpio only if cs line is asserted by gpio pins */ if (sdd->cs_gpio) { if (sdd->cs_gpio) { err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, Loading @@ -1080,25 +1073,10 @@ static int s3c64xx_spi_setup(struct spi_device *spi) } } } } if (!spi_get_ctldata(spi)) spi_set_ctldata(spi, cs); spi_set_ctldata(spi, cs); 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); sci = sdd->cntrlr_info; pm_runtime_get_sync(&sdd->pdev->dev); pm_runtime_get_sync(&sdd->pdev->dev); Loading Loading @@ -1146,7 +1124,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) /* setup() returns with device de-selected */ /* setup() returns with device de-selected */ disable_cs(sdd, spi); disable_cs(sdd, spi); err_msgq: gpio_free(cs->line); gpio_free(cs->line); spi_set_ctldata(spi, NULL); spi_set_ctldata(spi, NULL); Loading Loading @@ -1361,16 +1338,14 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) if (!sdd->pdev->dev.of_node) { if (!sdd->pdev->dev.of_node) { res = platform_get_resource(pdev, IORESOURCE_DMA, 0); res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { if (!res) { dev_warn(&pdev->dev, "Unable to get SPI tx dma " dev_warn(&pdev->dev, "Unable to get SPI tx dma resource. Switching to poll mode\n"); "resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else } else sdd->tx_dma.dmach = res->start; sdd->tx_dma.dmach = res->start; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { if (!res) { dev_warn(&pdev->dev, "Unable to get SPI rx dma " dev_warn(&pdev->dev, "Unable to get SPI rx dma resource. Switching to poll mode\n"); "resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else } else sdd->rx_dma.dmach = res->start; sdd->rx_dma.dmach = res->start; Loading Loading @@ -1440,7 +1415,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) spin_lock_init(&sdd->lock); spin_lock_init(&sdd->lock); init_completion(&sdd->xfer_completion); init_completion(&sdd->xfer_completion); INIT_LIST_HEAD(&sdd->queue); ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd); "spi-s3c64xx", sdd); Loading @@ -1462,8 +1436,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", dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n", sdd->port_id, master->num_chipselect); sdd->port_id, master->num_chipselect); dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tDMA=[Rx-%d, Tx-%d]\n", mem_res->end, mem_res->start, mem_res, sdd->rx_dma.dmach, sdd->tx_dma.dmach); sdd->rx_dma.dmach, sdd->tx_dma.dmach); pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev); Loading Loading
drivers/spi/spi-s3c64xx.c +43 −69 Original line number Original line Diff line number Diff line Loading @@ -172,7 +172,6 @@ struct s3c64xx_spi_port_config { * @master: Pointer to the SPI Protocol master. * @master: Pointer to the SPI Protocol master. * @cntrlr_info: Platform specific data for the controller this driver manages. * @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. * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. * @queue: To log SPI xfer requests. * @lock: Controller specific lock. * @lock: Controller specific lock. * @state: Set of FLAGS to indicate status. * @state: Set of FLAGS to indicate status. * @rx_dmach: Controller's DMA channel for Rx. * @rx_dmach: Controller's DMA channel for Rx. Loading @@ -193,7 +192,6 @@ struct s3c64xx_spi_driver_data { struct spi_master *master; struct spi_master *master; struct s3c64xx_spi_info *cntrlr_info; struct s3c64xx_spi_info *cntrlr_info; struct spi_device *tgl_spi; struct spi_device *tgl_spi; struct list_head queue; spinlock_t lock; spinlock_t lock; unsigned long sfr_start; unsigned long sfr_start; struct completion xfer_completion; struct completion xfer_completion; Loading Loading @@ -338,8 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; req.client = &s3c64xx_spi_dma_client; sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); sdd->rx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); 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; return 1; } } Loading Loading @@ -386,9 +386,10 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, { { struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd; struct dma_slave_config config; struct dma_slave_config config; struct scatterlist sg; struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc; memset(&config, 0, sizeof(config)); if (dma->direction == DMA_DEV_TO_MEM) { if (dma->direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); struct s3c64xx_spi_driver_data, rx_dma); Loading @@ -407,14 +408,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, dmaengine_slave_config(dma->ch, &config); dmaengine_slave_config(dma->ch, &config); } } sg_init_table(&sg, 1); desc = dmaengine_prep_slave_single(dma->ch, buf, len, sg_dma_len(&sg) = len; dma->direction, DMA_PREP_INTERRUPT); 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->callback = s3c64xx_spi_dmacb; desc->callback = s3c64xx_spi_dmacb; desc->callback_param = dma; desc->callback_param = dma; Loading @@ -431,9 +426,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) dma_cap_mask_t mask; dma_cap_mask_t mask; int ret; int ret; if (is_polling(sdd)) if (!is_polling(sdd)) { return 0; dma_cap_zero(mask); dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask); Loading @@ -453,6 +446,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) ret = -EBUSY; ret = -EBUSY; goto out_rx; goto out_rx; } } } ret = pm_runtime_get_sync(&sdd->pdev->dev); ret = pm_runtime_get_sync(&sdd->pdev->dev); if (ret < 0) { if (ret < 0) { Loading Loading @@ -1053,8 +1047,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci; struct s3c64xx_spi_info *sci; struct spi_message *msg; unsigned long flags; int err; int err; sdd = spi_master_get_devdata(spi->master); sdd = spi_master_get_devdata(spi->master); Loading @@ -1068,6 +1060,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi) return -ENODEV; return -ENODEV; } } if (!spi_get_ctldata(spi)) { /* Request gpio only if cs line is asserted by gpio pins */ /* Request gpio only if cs line is asserted by gpio pins */ if (sdd->cs_gpio) { if (sdd->cs_gpio) { err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, Loading @@ -1080,25 +1073,10 @@ static int s3c64xx_spi_setup(struct spi_device *spi) } } } } if (!spi_get_ctldata(spi)) spi_set_ctldata(spi, cs); spi_set_ctldata(spi, cs); 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); sci = sdd->cntrlr_info; pm_runtime_get_sync(&sdd->pdev->dev); pm_runtime_get_sync(&sdd->pdev->dev); Loading Loading @@ -1146,7 +1124,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) /* setup() returns with device de-selected */ /* setup() returns with device de-selected */ disable_cs(sdd, spi); disable_cs(sdd, spi); err_msgq: gpio_free(cs->line); gpio_free(cs->line); spi_set_ctldata(spi, NULL); spi_set_ctldata(spi, NULL); Loading Loading @@ -1361,16 +1338,14 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) if (!sdd->pdev->dev.of_node) { if (!sdd->pdev->dev.of_node) { res = platform_get_resource(pdev, IORESOURCE_DMA, 0); res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { if (!res) { dev_warn(&pdev->dev, "Unable to get SPI tx dma " dev_warn(&pdev->dev, "Unable to get SPI tx dma resource. Switching to poll mode\n"); "resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else } else sdd->tx_dma.dmach = res->start; sdd->tx_dma.dmach = res->start; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { if (!res) { dev_warn(&pdev->dev, "Unable to get SPI rx dma " dev_warn(&pdev->dev, "Unable to get SPI rx dma resource. Switching to poll mode\n"); "resource. Switching to poll mode\n"); sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL; } else } else sdd->rx_dma.dmach = res->start; sdd->rx_dma.dmach = res->start; Loading Loading @@ -1440,7 +1415,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) spin_lock_init(&sdd->lock); spin_lock_init(&sdd->lock); init_completion(&sdd->xfer_completion); init_completion(&sdd->xfer_completion); INIT_LIST_HEAD(&sdd->queue); ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd); "spi-s3c64xx", sdd); Loading @@ -1462,8 +1436,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", dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n", sdd->port_id, master->num_chipselect); sdd->port_id, master->num_chipselect); dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tDMA=[Rx-%d, Tx-%d]\n", mem_res->end, mem_res->start, mem_res, sdd->rx_dma.dmach, sdd->tx_dma.dmach); sdd->rx_dma.dmach, sdd->tx_dma.dmach); pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev); Loading