diff options
Diffstat (limited to 'drivers/spi/spi-coldfire-qspi.c')
| -rw-r--r-- | drivers/spi/spi-coldfire-qspi.c | 171 |
1 files changed, 64 insertions, 107 deletions
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index cc5b75d10c3..e2fa628e55e 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -77,8 +77,6 @@ struct mcfqspi { struct mcfqspi_cs_control *cs_control; wait_queue_head_t waitq; - - struct device *dev; }; static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) @@ -135,13 +133,13 @@ static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select, static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi) { - return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ? + return (mcfqspi->cs_control->setup) ? mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0; } static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi) { - if (mcfqspi->cs_control && mcfqspi->cs_control->teardown) + if (mcfqspi->cs_control->teardown) mcfqspi->cs_control->teardown(mcfqspi->cs_control); } @@ -300,68 +298,45 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count, } } -static int mcfqspi_transfer_one_message(struct spi_master *master, - struct spi_message *msg) +static void mcfqspi_set_cs(struct spi_device *spi, bool enable) { - struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - struct spi_device *spi = msg->spi; - struct spi_transfer *t; - int status = 0; - - list_for_each_entry(t, &msg->transfers, transfer_list) { - bool cs_high = spi->mode & SPI_CS_HIGH; - u16 qmr = MCFQSPI_QMR_MSTR; - - qmr |= t->bits_per_word << 10; - if (spi->mode & SPI_CPHA) - qmr |= MCFQSPI_QMR_CPHA; - if (spi->mode & SPI_CPOL) - qmr |= MCFQSPI_QMR_CPOL; - if (t->speed_hz) - qmr |= mcfqspi_qmr_baud(t->speed_hz); - else - qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); - mcfqspi_wr_qmr(mcfqspi, qmr); + struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master); + bool cs_high = spi->mode & SPI_CS_HIGH; + if (enable) mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); + else + mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high); +} - mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); - if (t->bits_per_word == 8) - mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, - t->rx_buf); - else - mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, - t->rx_buf); - mcfqspi_wr_qir(mcfqspi, 0); - - if (t->delay_usecs) - udelay(t->delay_usecs); - if (t->cs_change) { - if (!list_is_last(&t->transfer_list, &msg->transfers)) - mcfqspi_cs_deselect(mcfqspi, spi->chip_select, - cs_high); - } else { - if (list_is_last(&t->transfer_list, &msg->transfers)) - mcfqspi_cs_deselect(mcfqspi, spi->chip_select, - cs_high); - } - msg->actual_length += t->len; - } - msg->status = status; - spi_finalize_current_message(master); - - return status; +static int mcfqspi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *t) +{ + struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + u16 qmr = MCFQSPI_QMR_MSTR; + + qmr |= t->bits_per_word << 10; + if (spi->mode & SPI_CPHA) + qmr |= MCFQSPI_QMR_CPHA; + if (spi->mode & SPI_CPOL) + qmr |= MCFQSPI_QMR_CPOL; + qmr |= mcfqspi_qmr_baud(t->speed_hz); + mcfqspi_wr_qmr(mcfqspi, qmr); + + mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); + if (t->bits_per_word == 8) + mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, t->rx_buf); + else + mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, + t->rx_buf); + mcfqspi_wr_qir(mcfqspi, 0); + return 0; } static int mcfqspi_setup(struct spi_device *spi) { - if (spi->chip_select >= spi->master->num_chipselect) { - dev_dbg(&spi->dev, "%d chip select is out of range\n", - spi->chip_select); - return -EINVAL; - } - mcfqspi_cs_deselect(spi_master_get_devdata(spi->master), spi->chip_select, spi->mode & SPI_CS_HIGH); @@ -388,6 +363,11 @@ static int mcfqspi_probe(struct platform_device *pdev) return -ENOENT; } + if (!pdata->cs_control) { + dev_dbg(&pdev->dev, "pdata->cs_control is NULL\n"); + return -EINVAL; + } + master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi)); if (master == NULL) { dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); @@ -397,44 +377,31 @@ static int mcfqspi_probe(struct platform_device *pdev) mcfqspi = spi_master_get_devdata(master); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_dbg(&pdev->dev, "platform_get_resource failed\n"); - status = -ENXIO; - goto fail0; - } - - if (!request_mem_region(res->start, resource_size(res), pdev->name)) { - dev_dbg(&pdev->dev, "request_mem_region failed\n"); - status = -EBUSY; + mcfqspi->iobase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mcfqspi->iobase)) { + status = PTR_ERR(mcfqspi->iobase); goto fail0; } - mcfqspi->iobase = ioremap(res->start, resource_size(res)); - if (!mcfqspi->iobase) { - dev_dbg(&pdev->dev, "ioremap failed\n"); - status = -ENOMEM; - goto fail1; - } - mcfqspi->irq = platform_get_irq(pdev, 0); if (mcfqspi->irq < 0) { dev_dbg(&pdev->dev, "platform_get_irq failed\n"); status = -ENXIO; - goto fail2; + goto fail0; } - status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0, - pdev->name, mcfqspi); + status = devm_request_irq(&pdev->dev, mcfqspi->irq, mcfqspi_irq_handler, + 0, pdev->name, mcfqspi); if (status) { dev_dbg(&pdev->dev, "request_irq failed\n"); - goto fail2; + goto fail0; } - mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk"); + mcfqspi->clk = devm_clk_get(&pdev->dev, "qspi_clk"); if (IS_ERR(mcfqspi->clk)) { dev_dbg(&pdev->dev, "clk_get failed\n"); status = PTR_ERR(mcfqspi->clk); - goto fail3; + goto fail0; } clk_enable(mcfqspi->clk); @@ -445,42 +412,35 @@ static int mcfqspi_probe(struct platform_device *pdev) status = mcfqspi_cs_setup(mcfqspi); if (status) { dev_dbg(&pdev->dev, "error initializing cs_control\n"); - goto fail4; + goto fail1; } init_waitqueue_head(&mcfqspi->waitq); - mcfqspi->dev = &pdev->dev; master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); master->setup = mcfqspi_setup; - master->transfer_one_message = mcfqspi_transfer_one_message; + master->set_cs = mcfqspi_set_cs; + master->transfer_one = mcfqspi_transfer_one; master->auto_runtime_pm = true; platform_set_drvdata(pdev, master); - status = spi_register_master(master); + status = devm_spi_register_master(&pdev->dev, master); if (status) { dev_dbg(&pdev->dev, "spi_register_master failed\n"); - goto fail5; + goto fail2; } - pm_runtime_enable(mcfqspi->dev); + pm_runtime_enable(&pdev->dev); dev_info(&pdev->dev, "Coldfire QSPI bus driver\n"); return 0; -fail5: - mcfqspi_cs_teardown(mcfqspi); -fail4: - clk_disable(mcfqspi->clk); - clk_put(mcfqspi->clk); -fail3: - free_irq(mcfqspi->irq, mcfqspi); fail2: - iounmap(mcfqspi->iobase); + mcfqspi_cs_teardown(mcfqspi); fail1: - release_mem_region(res->start, resource_size(res)); + clk_disable(mcfqspi->clk); fail0: spi_master_put(master); @@ -493,19 +453,13 @@ static int mcfqspi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pm_runtime_disable(mcfqspi->dev); + pm_runtime_disable(&pdev->dev); /* disable the hardware (set the baud rate to 0) */ mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); mcfqspi_cs_teardown(mcfqspi); clk_disable(mcfqspi->clk); - clk_put(mcfqspi->clk); - free_irq(mcfqspi->irq, mcfqspi); - iounmap(mcfqspi->iobase); - release_mem_region(res->start, resource_size(res)); - spi_unregister_master(master); return 0; } @@ -515,8 +469,11 @@ static int mcfqspi_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + int ret; - spi_master_suspend(master); + ret = spi_master_suspend(master); + if (ret) + return ret; clk_disable(mcfqspi->clk); @@ -528,18 +485,17 @@ static int mcfqspi_resume(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - spi_master_resume(master); - clk_enable(mcfqspi->clk); - return 0; + return spi_master_resume(master); } #endif #ifdef CONFIG_PM_RUNTIME static int mcfqspi_runtime_suspend(struct device *dev) { - struct mcfqspi *mcfqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + struct mcfqspi *mcfqspi = spi_master_get_devdata(master); clk_disable(mcfqspi->clk); @@ -548,7 +504,8 @@ static int mcfqspi_runtime_suspend(struct device *dev) static int mcfqspi_runtime_resume(struct device *dev) { - struct mcfqspi *mcfqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + struct mcfqspi *mcfqspi = spi_master_get_devdata(master); clk_enable(mcfqspi->clk); |
