From 8197f489f4c4398391746a377c10501076b05168 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 6 Nov 2017 10:38:23 -0800 Subject: spi: imx: Fix failure path leak on GPIO request error correctly In commit 974488e4ce1e ("spi: imx: Fix failure path leak on GPIO request error"), spi_bitbang_start() was moved later in the probe sequence. But this doesn't work, as spi_bitbang_start() has to be called before requesting GPIOs because the GPIO data in the spi master is populated when the master is registed, and that doesn't happen until spi_bitbang_start() is called. The default only works if one uses one CS. So add a failure path call to spi_bitbang_stop() to fix the leak. CC: Shawn Guo CC: Sascha Hauer CC: Fabio Estevam CC: Mark Brown CC: Oleksij Rempel Signed-off-by: Trent Piepho Reviewed-by: Oleksij Rempel Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 5ddd32ba2521..301cdb721bad 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1613,6 +1613,11 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->devtype_data->intctrl(spi_imx, 0); master->dev.of_node = pdev->dev.of_node; + ret = spi_bitbang_start(&spi_imx->bitbang); + if (ret) { + dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); + goto out_clk_put; + } if (!spi_imx->slave_mode) { if (!master->cs_gpios) { @@ -1631,23 +1636,19 @@ static int spi_imx_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Can't get CS GPIO %i\n", master->cs_gpios[i]); - goto out_clk_put; + goto out_spi_bitbang; } } } - ret = spi_bitbang_start(&spi_imx->bitbang); - if (ret) { - dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); - goto out_clk_put; - } - dev_info(&pdev->dev, "probed\n"); clk_disable(spi_imx->clk_ipg); clk_disable(spi_imx->clk_per); return ret; +out_spi_bitbang: + spi_bitbang_stop(&spi_imx->bitbang); out_clk_put: clk_disable_unprepare(spi_imx->clk_ipg); out_put_per: -- cgit v1.2.3 From 00ac9562158e8541d60e91eb72aa9ed0674d4a6a Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Mon, 13 Nov 2017 08:47:21 +0100 Subject: spi: spi-fsl-dspi: add SPI_LSB_FIRST to driver capabilities The driver as well as the controller support the SPI lsb first mode. However, it's not possible to configure it e.g. when using spidev. Adding this flag to mode_bits resolves the issue and lsb first mode can be used. Signed-off-by: Kurt Kanzenbach Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-dspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index f652f70cb8db..02d3ed7f2558 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -980,7 +980,7 @@ static int dspi_probe(struct platform_device *pdev) master->dev.of_node = pdev->dev.of_node; master->cleanup = dspi_cleanup; - master->mode_bits = SPI_CPOL | SPI_CPHA; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) | SPI_BPW_MASK(16); -- cgit v1.2.3 From a5db27c00da37654ba518b814925d4e9cd05259c Mon Sep 17 00:00:00 2001 From: Sunny Luo Date: Tue, 28 Nov 2017 21:29:25 +0800 Subject: spi: meson-axg: add SPICC driver support Add new compatible string to support SPICC controller which found at Amlogic Meson-AXG SoC. This is aiming at adding a couple of enhanced feature patches. Signed-off-by: Sunny Luo Signed-off-by: Yixun Lan Signed-off-by: Mark Brown --- drivers/spi/spi-meson-spicc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index 7f8429635502..5c82910e3480 100644 --- a/drivers/spi/spi-meson-spicc.c +++ b/drivers/spi/spi-meson-spicc.c @@ -599,6 +599,7 @@ static int meson_spicc_remove(struct platform_device *pdev) static const struct of_device_id meson_spicc_of_match[] = { { .compatible = "amlogic,meson-gx-spicc", }, + { .compatible = "amlogic,meson-axg-spicc", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_spicc_of_match); -- cgit v1.2.3 From 16eab16ef9382704ff12c68ef52d62c68219cbb9 Mon Sep 17 00:00:00 2001 From: Takuo Koguchi Date: Thu, 7 Dec 2017 19:11:41 +0900 Subject: spi: jcore: disable clock when registering spi conroller failed When probe function fails in registering the spi controller, the clock should remain disabled. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Takuo Koguchi Signed-off-by: Mark Brown --- drivers/spi/spi-jcore.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c index cebfea5faa4b..dafed6280df3 100644 --- a/drivers/spi/spi-jcore.c +++ b/drivers/spi/spi-jcore.c @@ -198,8 +198,10 @@ static int jcore_spi_probe(struct platform_device *pdev) /* Register our spi controller */ err = devm_spi_register_master(&pdev->dev, master); - if (err) + if (err) { + clk_disable(clk); goto exit; + } return 0; -- cgit v1.2.3 From 230c08b2acf65863ac5905ea1fa93106bdd20af3 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 2 Jan 2018 14:28:06 +0100 Subject: spi: spi-fsl-dspi: account for const type of of_device_id.data This driver creates a number of const structures that it stores in the data field of an of_device_id array. The data field of an of_device_id structure has type const void *, so there is no need for a const-discarding cast when putting const values into such a structure. Done using Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-dspi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 02d3ed7f2558..0630962ce442 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -903,10 +903,9 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) } static const struct of_device_id fsl_dspi_dt_ids[] = { - { .compatible = "fsl,vf610-dspi", .data = (void *)&vf610_data, }, - { .compatible = "fsl,ls1021a-v1.0-dspi", - .data = (void *)&ls1021a_v1_data, }, - { .compatible = "fsl,ls2085a-dspi", .data = (void *)&ls2085a_data, }, + { .compatible = "fsl,vf610-dspi", .data = &vf610_data, }, + { .compatible = "fsl,ls1021a-v1.0-dspi", .data = &ls1021a_v1_data, }, + { .compatible = "fsl,ls2085a-dspi", .data = &ls2085a_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); -- cgit v1.2.3 From 92ae112e477ac412decc3fdd5c1eeb6c90c266b4 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 12 Jan 2018 11:42:33 +0100 Subject: spi: orion: Fix clock resource by adding an optional bus clock On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock is optional because not all the SoCs need them but at least for Armada 7K/8K it is actually mandatory. The binding documentation is updating accordingly as well as mentioning the mandatory clock which was also missing. Signed-off-by: Gregory CLEMENT Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-orion.txt | 9 +++++++++ drivers/spi/spi-orion.c | 14 ++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index df8ec31f2f07..8434a65fc12a 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt @@ -18,8 +18,17 @@ Required properties: The eight register sets following the control registers refer to chip-select lines 0 through 7 respectively. - cell-index : Which of multiple SPI controllers is this. +- clocks : pointers to the reference clocks for this device, the first + one is the one used for the clock on the spi bus, the + second one is optional and is the clock used for the + functional part of the controller + Optional properties: - interrupts : Is currently not used. +- clock-names : names of used clocks, mandatory if the second clock is + used, the name must be "core", and "axi" (the latter + is only for Armada 7K/8K). + Example: spi@10600 { diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 8974bb340b3a..482a0cf3b7aa 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -94,6 +94,7 @@ struct orion_spi { struct spi_master *master; void __iomem *base; struct clk *clk; + struct clk *axi_clk; const struct orion_spi_dev *devdata; struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; @@ -634,6 +635,14 @@ static int orion_spi_probe(struct platform_device *pdev) if (status) goto out; + /* The following clock is only used by some SoCs */ + spi->axi_clk = devm_clk_get(&pdev->dev, "axi"); + if (IS_ERR(spi->axi_clk) && + PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!IS_ERR(spi->axi_clk)) + clk_prepare_enable(spi->axi_clk); + tclk_hz = clk_get_rate(spi->clk); /* @@ -725,6 +734,7 @@ static int orion_spi_probe(struct platform_device *pdev) out_rel_pm: pm_runtime_disable(&pdev->dev); out_rel_clk: + clk_disable_unprepare(spi->axi_clk); clk_disable_unprepare(spi->clk); out: spi_master_put(master); @@ -738,6 +748,7 @@ static int orion_spi_remove(struct platform_device *pdev) struct orion_spi *spi = spi_master_get_devdata(master); pm_runtime_get_sync(&pdev->dev); + clk_disable_unprepare(spi->axi_clk); clk_disable_unprepare(spi->clk); spi_unregister_master(master); @@ -754,6 +765,7 @@ static int orion_spi_runtime_suspend(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct orion_spi *spi = spi_master_get_devdata(master); + clk_disable_unprepare(spi->axi_clk); clk_disable_unprepare(spi->clk); return 0; } @@ -763,6 +775,8 @@ static int orion_spi_runtime_resume(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct orion_spi *spi = spi_master_get_devdata(master); + if (!IS_ERR(spi->axi_clk)) + clk_prepare_enable(spi->axi_clk); return clk_prepare_enable(spi->clk); } #endif -- cgit v1.2.3 From 479c03a7173d07b2967f9b521159271543d99e2f Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Thu, 25 Jan 2018 21:16:17 +0100 Subject: spi: orion: Fix a resource leak if the optional "axi" clk is deferred If the optional "axi" clk is deferred, we still need to undo some initialisation. Especially 'master' must be released. It will be reallocated the next time 'orion_spi_probe()' is called. Add a new label to clean what needs to be cleaned and rename another label to improve the names used. Fixes: 92ae112e477a ("spi: orion: Fix clock resource by adding an optional bus clock") Signed-off-by: Christophe JAILLET Acked-by: Gregory CLEMENT Signed-off-by: Mark Brown --- drivers/spi/spi-orion.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 482a0cf3b7aa..deca63e82ff6 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -638,8 +638,10 @@ static int orion_spi_probe(struct platform_device *pdev) /* The following clock is only used by some SoCs */ spi->axi_clk = devm_clk_get(&pdev->dev, "axi"); if (IS_ERR(spi->axi_clk) && - PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) - return -EPROBE_DEFER; + PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) { + status = -EPROBE_DEFER; + goto out_rel_clk; + } if (!IS_ERR(spi->axi_clk)) clk_prepare_enable(spi->axi_clk); @@ -667,7 +669,7 @@ static int orion_spi_probe(struct platform_device *pdev) spi->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(spi->base)) { status = PTR_ERR(spi->base); - goto out_rel_clk; + goto out_rel_axi_clk; } /* Scan all SPI devices of this controller for direct mapped devices */ @@ -705,7 +707,7 @@ static int orion_spi_probe(struct platform_device *pdev) PAGE_SIZE); if (!spi->direct_access[cs].vaddr) { status = -ENOMEM; - goto out_rel_clk; + goto out_rel_axi_clk; } spi->direct_access[cs].size = PAGE_SIZE; @@ -733,8 +735,9 @@ static int orion_spi_probe(struct platform_device *pdev) out_rel_pm: pm_runtime_disable(&pdev->dev); -out_rel_clk: +out_rel_axi_clk: clk_disable_unprepare(spi->axi_clk); +out_rel_clk: clk_disable_unprepare(spi->clk); out: spi_master_put(master); -- cgit v1.2.3