From 8197f489f4c4398391746a377c10501076b05168 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 6 Nov 2017 10:38:23 -0800 Subject: [PATCH 1/8] 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(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 5ddd32ba2521b2..301cdb721badca 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: From 00ac9562158e8541d60e91eb72aa9ed0674d4a6a Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Mon, 13 Nov 2017 08:47:21 +0100 Subject: [PATCH 2/8] 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(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index f652f70cb8db16..02d3ed7f25581a 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); From a78841479696efa557a2251c86462c936a208f90 Mon Sep 17 00:00:00 2001 From: Sunny Luo Date: Tue, 28 Nov 2017 21:29:24 +0800 Subject: [PATCH 3/8] spi: meson-axg: update compatible string for the Meson-AXG Update the compatbile string to support Meson-AXG SoCs. Signed-off-by: Sunny Luo Signed-off-by: Yixun Lan Acked-by: Rob Herring Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-meson.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/spi-meson.txt b/Documentation/devicetree/bindings/spi/spi-meson.txt index 825c39cae74a15..b7f5e86fed225b 100644 --- a/Documentation/devicetree/bindings/spi/spi-meson.txt +++ b/Documentation/devicetree/bindings/spi/spi-meson.txt @@ -27,7 +27,9 @@ The Meson SPICC is generic SPI controller for general purpose Full-Duplex communications with dedicated 16 words RX/TX PIO FIFOs. Required properties: - - compatible: should be "amlogic,meson-gx-spicc" on Amlogic GX SoCs. + - compatible: should be: + "amlogic,meson-gx-spicc" on Amlogic GX and compatible SoCs. + "amlogic,meson-axg-spicc" on Amlogic AXG and compatible SoCs - reg: physical base address and length of the controller registers - interrupts: The interrupt specifier - clock-names: Must contain "core" From a5db27c00da37654ba518b814925d4e9cd05259c Mon Sep 17 00:00:00 2001 From: Sunny Luo Date: Tue, 28 Nov 2017 21:29:25 +0800 Subject: [PATCH 4/8] 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(+) diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index 7f84296355025d..5c82910e3480d0 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); From 16eab16ef9382704ff12c68ef52d62c68219cbb9 Mon Sep 17 00:00:00 2001 From: Takuo Koguchi Date: Thu, 7 Dec 2017 19:11:41 +0900 Subject: [PATCH 5/8] 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(-) diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c index cebfea5faa4be2..dafed6280df328 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; From 230c08b2acf65863ac5905ea1fa93106bdd20af3 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 2 Jan 2018 14:28:06 +0100 Subject: [PATCH 6/8] 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(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 02d3ed7f25581a..0630962ce442ee 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); From 92ae112e477ac412decc3fdd5c1eeb6c90c266b4 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 12 Jan 2018 11:42:33 +0100 Subject: [PATCH 7/8] 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 --- .../devicetree/bindings/spi/spi-orion.txt | 9 +++++++++ drivers/spi/spi-orion.c | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index df8ec31f2f076a..8434a65fc12a65 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 8974bb340b3abe..482a0cf3b7aaf0 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 From 479c03a7173d07b2967f9b521159271543d99e2f Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Thu, 25 Jan 2018 21:16:17 +0100 Subject: [PATCH 8/8] 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(-) diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 482a0cf3b7aaf0..deca63e82ff688 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);