diff options
Diffstat (limited to 'drivers/spi/spi-sun4i.c')
| -rw-r--r-- | drivers/spi/spi-sun4i.c | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index cbfac6596fad..aa92fd5a35a9 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -75,7 +75,7 @@ #define SUN4I_FIFO_STA_TF_CNT_BITS 16 struct sun4i_spi { - struct spi_master *master; + struct spi_controller *host; void __iomem *base_addr; struct clk *hclk; struct clk *mclk; @@ -161,13 +161,13 @@ static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) { - struct sun4i_spi *sspi = spi_master_get_devdata(spi->master); + struct sun4i_spi *sspi = spi_controller_get_devdata(spi->controller); u32 reg; reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); reg &= ~SUN4I_CTL_CS_MASK; - reg |= SUN4I_CTL_CS(spi->chip_select); + reg |= SUN4I_CTL_CS(spi_get_chipselect(spi, 0)); /* We want to control the chip select manually */ reg |= SUN4I_CTL_CS_MANUAL; @@ -198,15 +198,16 @@ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) static size_t sun4i_spi_max_transfer_size(struct spi_device *spi) { - return SUN4I_FIFO_DEPTH - 1; + return SUN4I_MAX_XFER_SIZE - 1; } -static int sun4i_spi_transfer_one(struct spi_master *master, +static int sun4i_spi_transfer_one(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *tfr) { - struct sun4i_spi *sspi = spi_master_get_devdata(master); - unsigned int mclk_rate, div, timeout; + struct sun4i_spi *sspi = spi_controller_get_devdata(host); + unsigned int mclk_rate, div; + unsigned long time_left; unsigned int start, end, tx_time; unsigned int tx_len = 0; int ret = 0; @@ -263,6 +264,9 @@ static int sun4i_spi_transfer_one(struct spi_master *master, else reg |= SUN4I_CTL_DHB; + /* Now that the settings are correct, enable the interface */ + reg |= SUN4I_CTL_ENABLE; + sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); /* Ensure that we have a parent clock fast enough */ @@ -280,7 +284,7 @@ static int sun4i_spi_transfer_one(struct spi_master *master, * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1)) * Or we can use CDR2, which is calculated with the formula: * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) - * Wether we use the former or the latter is set through the + * Whether we use the former or the latter is set through the * DRS bit. * * First try CDR2, and if we can't reach the expected @@ -327,11 +331,11 @@ static int sun4i_spi_transfer_one(struct spi_master *master, tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); start = jiffies; - timeout = wait_for_completion_timeout(&sspi->done, - msecs_to_jiffies(tx_time)); + time_left = wait_for_completion_timeout(&sspi->done, + msecs_to_jiffies(tx_time)); end = jiffies; - if (!timeout) { - dev_warn(&master->dev, + if (!time_left) { + dev_warn(&host->dev, "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", dev_name(&spi->dev), tfr->len, tfr->speed_hz, jiffies_to_msecs(end - start), tx_time); @@ -386,8 +390,8 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) static int sun4i_spi_runtime_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct sun4i_spi *sspi = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct sun4i_spi *sspi = spi_controller_get_devdata(host); int ret; ret = clk_prepare_enable(sspi->hclk); @@ -403,7 +407,7 @@ static int sun4i_spi_runtime_resume(struct device *dev) } sun4i_spi_write(sspi, SUN4I_CTL_REG, - SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); + SUN4I_CTL_MASTER | SUN4I_CTL_TP); return 0; @@ -415,8 +419,8 @@ out: static int sun4i_spi_runtime_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct sun4i_spi *sspi = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct sun4i_spi *sspi = spi_controller_get_devdata(host); clk_disable_unprepare(sspi->mclk); clk_disable_unprepare(sspi->hclk); @@ -426,62 +430,63 @@ static int sun4i_spi_runtime_suspend(struct device *dev) static int sun4i_spi_probe(struct platform_device *pdev) { - struct spi_master *master; + struct spi_controller *host; struct sun4i_spi *sspi; int ret = 0, irq; - master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi)); - if (!master) { - dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); + host = spi_alloc_host(&pdev->dev, sizeof(struct sun4i_spi)); + if (!host) { + dev_err(&pdev->dev, "Unable to allocate SPI Host\n"); return -ENOMEM; } - platform_set_drvdata(pdev, master); - sspi = spi_master_get_devdata(master); + platform_set_drvdata(pdev, host); + sspi = spi_controller_get_devdata(host); sspi->base_addr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sspi->base_addr)) { ret = PTR_ERR(sspi->base_addr); - goto err_free_master; + goto err_free_host; } irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; - goto err_free_master; + goto err_free_host; } ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler, 0, "sun4i-spi", sspi); if (ret) { dev_err(&pdev->dev, "Cannot request IRQ\n"); - goto err_free_master; + goto err_free_host; } - sspi->master = master; - master->max_speed_hz = 100 * 1000 * 1000; - master->min_speed_hz = 3 * 1000; - master->set_cs = sun4i_spi_set_cs; - master->transfer_one = sun4i_spi_transfer_one; - master->num_chipselect = 4; - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; - master->bits_per_word_mask = SPI_BPW_MASK(8); - master->dev.of_node = pdev->dev.of_node; - master->auto_runtime_pm = true; - master->max_transfer_size = sun4i_spi_max_transfer_size; + sspi->host = host; + host->max_speed_hz = 100 * 1000 * 1000; + host->min_speed_hz = 3 * 1000; + host->use_gpio_descriptors = true; + host->set_cs = sun4i_spi_set_cs; + host->transfer_one = sun4i_spi_transfer_one; + host->num_chipselect = 4; + host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; + host->bits_per_word_mask = SPI_BPW_MASK(8); + host->dev.of_node = pdev->dev.of_node; + host->auto_runtime_pm = true; + host->max_transfer_size = sun4i_spi_max_transfer_size; sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(sspi->hclk)) { dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); ret = PTR_ERR(sspi->hclk); - goto err_free_master; + goto err_free_host; } sspi->mclk = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(sspi->mclk)) { dev_err(&pdev->dev, "Unable to acquire module clock\n"); ret = PTR_ERR(sspi->mclk); - goto err_free_master; + goto err_free_host; } init_completion(&sspi->done); @@ -493,16 +498,16 @@ static int sun4i_spi_probe(struct platform_device *pdev) ret = sun4i_spi_runtime_resume(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Couldn't resume the device\n"); - goto err_free_master; + goto err_free_host; } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_idle(&pdev->dev); - ret = devm_spi_register_master(&pdev->dev, master); + ret = devm_spi_register_controller(&pdev->dev, host); if (ret) { - dev_err(&pdev->dev, "cannot register SPI master\n"); + dev_err(&pdev->dev, "cannot register SPI host\n"); goto err_pm_disable; } @@ -511,16 +516,14 @@ static int sun4i_spi_probe(struct platform_device *pdev) err_pm_disable: pm_runtime_disable(&pdev->dev); sun4i_spi_runtime_suspend(&pdev->dev); -err_free_master: - spi_master_put(master); +err_free_host: + spi_controller_put(host); return ret; } -static int sun4i_spi_remove(struct platform_device *pdev) +static void sun4i_spi_remove(struct platform_device *pdev) { pm_runtime_force_suspend(&pdev->dev); - - return 0; } static const struct of_device_id sun4i_spi_match[] = { @@ -536,7 +539,7 @@ static const struct dev_pm_ops sun4i_spi_pm_ops = { static struct platform_driver sun4i_spi_driver = { .probe = sun4i_spi_probe, - .remove = sun4i_spi_remove, + .remove = sun4i_spi_remove, .driver = { .name = "sun4i-spi", .of_match_table = sun4i_spi_match, |
