mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Subsystems (5)
PATCH 1/1 mmc: sdhci-xenon: 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.
Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver.
functionality)"
---
Hi Ulf and Adrian,
This patch should be merged in 4.14-rc, as it fixes real issues.
This patch maye looks like just as a nice clean-up but it is not. On the earlier version of the series adding the support for the xenon controller there was already this axi bus clock. But at this moment the documentation for the clock on the Armada 7K/8K was missing and there was no driver for it, so we just use the clock set by the bootloader and never change them that's why it worked without any visible problem.
Then as explained in the commit log the network driver enabled the clock for us, and it happened that it was setup before the xenon driver. It is only thanks the new information we received on the clocks of the Sov and with more exhaustive testes that we found this issue and the fix for it.
Thanks,
Gregory
.../bindings/mmc/marvell,xenon-sdhci.txt | 12 ++++++----- drivers/mmc/host/sdhci-xenon.c | 25 +++++++++++++++++++--- drivers/mmc/host/sdhci-xenon.h | 1 + 3 files changed, 30 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +7 -5
@@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi". - reg: * For "marvell,armada-3700-sdhci", two register areas.
@@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH> - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>;
@@ -126,8 +128,8 @@ Example: interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH> vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; };
drivers/mmc/host/sdhci-xenon.c +22 -3
@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) {struct sdhci_pltfm_host *pltfm_host;struct sdhci_host *host; +struct xenon_priv *priv;int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,
@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)return PTR_ERR (host); pltfm_host =sdhci_priv (host); + priv =sdhci_pltfm_priv (pltfm_host);/* * Link Xenon specific mmc_host_ops function,
@@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm; + priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) { + err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err); + priv->axi_clk =NULL ; + }else { + err =clk_prepare_enable (priv->axi_clk); +if (err) + goto err_clk; + } + err =mmc_of_parse (host->mmc);if (err) - goto err_clk; + goto err_clk_axi;sdhci_get_of_property (pdev);
@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)/* Xenon specific dt parse */ err =xenon_probe_dt (pdev);if (err) - goto err_clk; + goto err_clk_axi; err =xenon_sdhc_prepare (host);if (err) - goto err_clk; + goto err_clk_axi;pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);
@@ -527,6 +540,9 @@ static int xenon_probe(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);xenon_sdhc_unprepare (host); +err_clk_axi: +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk); err_clk:clk_disable_unprepare (pltfm_host->clk); free_pltfm:
@@ -538,6 +554,7 @@ static int xenon_remove(struct platform_device *pdev) {struct sdhci_host *host =platform_get_drvdata (pdev);struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct xenon_priv *priv =sdhci_pltfm_priv (pltfm_host);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);
@@ -546,6 +563,8 @@ static int xenon_remove(struct platform_device *pdev)sdhci_remove_host (host,0 );xenon_sdhc_unprepare (host); +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk);clk_disable_unprepare (pltfm_host->clk);
drivers/mmc/host/sdhci-xenon.h +1 -0
@@ -83,6 +83,7 @@ struct xenon_priv {unsigned char bus_width;unsigned char timing;unsigned int clock; +struct clk *axi_clk;int phy_type;/*
Signature · 1 line
2.14.1
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Hi,
Quoted 21 lines · Gregory CLEMENT
drivers/mmc/host/sdhci-xenon.c +2
-0@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) {struct sdhci_pltfm_host *pltfm_host;struct sdhci_host *host; +struct xenon_priv *priv;int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)return PTR_ERR (host); pltfm_host =sdhci_priv (host); + priv =sdhci_pltfm_priv (pltfm_host);/* * Link Xenon specific mmc_host_ops function,
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 499
Quoted 7 lines
drivers/mmc/host/sdhci-xenon.c +4
-0@@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm; + priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) { + err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err);
I should manage the -EPROBE_DEFER case here. So a v2 of this patch is coming soon.
Sorry to not have seen this before sending the patch.
Gregory
Quoted 70 lines
drivers/mmc/host/sdhci-xenon.c +16
-3+ priv->axi_clk =NULL ; + }else { + err =clk_prepare_enable (priv->axi_clk); +if (err) + goto err_clk; + } + err =mmc_of_parse (host->mmc);if (err) - goto err_clk; + goto err_clk_axi;sdhci_get_of_property (pdev);@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)/* Xenon specific dt parse */ err =xenon_probe_dt (pdev);if (err) - goto err_clk; + goto err_clk_axi; err =xenon_sdhc_prepare (host);if (err) - goto err_clk; + goto err_clk_axi;pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);@@ -527,6 +540,9 @@ static int xenon_probe(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);xenon_sdhc_unprepare (host); +err_clk_axi: +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk); err_clk:clk_disable_unprepare (pltfm_host->clk); free_pltfm:@@ -538,6 +554,7 @@ static int xenon_remove(struct platform_device *pdev) {struct sdhci_host *host =platform_get_drvdata (pdev);struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct xenon_priv *priv =sdhci_pltfm_priv (pltfm_host);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);@@ -546,6 +563,8 @@ static int xenon_remove(struct platform_device *pdev)sdhci_remove_host (host,0 );xenon_sdhc_unprepare (host); +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk);clk_disable_unprepare (pltfm_host->clk);drivers/mmc/host/sdhci-xenon.h +1
-0@@ -83,6 +83,7 @@ struct xenon_priv {unsigned char bus_width;unsigned char timing;unsigned int clock; +struct clk *axi_clk;int phy_type;/* Signature · 1 line
2.14.1
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
In reply to Gregory CLEMENT+ DT maintainers
Quoted 49 lines · On Thu, 28 Sep 2017 17:05:20 +0200 Gregory CLEMENT wrote:
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.
Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver.
Fixes 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC corefunctionality)"
CC Stable <[email protected]>Signed-off-by Gregory CLEMENT <[email protected]>---
Hi Ulf and Adrian,This patch should be merged in 4.14-rc, as it fixes real issues.
This patch maye looks like just as a nice clean-up but it is not. On the earlier version of the series adding the support for the xenon controller there was already this axi bus clock. But at this moment the documentation for the clock on the Armada 7K/8K was missing and there was no driver for it, so we just use the clock set by the bootloader and never change them that's why it worked without any visible problem.
Then as explained in the commit log the network driver enabled the clock for us, and it happened that it was setup before the xenon driver. It is only thanks the new information we received on the clocks of the Sov and with more exhaustive testes that we found this issue and the fix for it.
Thanks,
Gregory
.../bindings/mmc/marvell,xenon-sdhci.txt | 12 ++++++----- drivers/mmc/host/sdhci-xenon.c | 25 +++++++++++++++++++--- drivers/mmc/host/sdhci-xenon.h | 1 + 3 files changed, 30 insertions(+), 8 deletions(-)Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +0
-0@@ -16,11 +16,13 @@ Required Properties:
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt Required Properties: · line 25
Quoted 10 lines
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +3
-1- clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi".
Is "bus" more suitable?
Quoted 46 lines
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +4
-4- reg: * For "marvell,armada-3700-sdhci", two register areas.@@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH> - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>;@@ -126,8 +128,8 @@ Example: interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH> vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; };drivers/mmc/host/sdhci-xenon.c +2
-0@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) {struct sdhci_pltfm_host *pltfm_host;struct sdhci_host *host; +struct xenon_priv *priv;int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)return PTR_ERR (host); pltfm_host =sdhci_priv (host); + priv =sdhci_pltfm_priv (pltfm_host);/* * Link Xenon specific mmc_host_ops function,
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 499
Quoted 7 lines
drivers/mmc/host/sdhci-xenon.c +4
-0@@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm; + priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) { + err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err);
Since the bus clock is optional, can we remove this err msg?
Quoted 29 lines
drivers/mmc/host/sdhci-xenon.c +10
-3+ priv->axi_clk =NULL ; + }else { + err =clk_prepare_enable (priv->axi_clk); +if (err) + goto err_clk; + } + err =mmc_of_parse (host->mmc);if (err) - goto err_clk; + goto err_clk_axi;sdhci_get_of_property (pdev);@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)/* Xenon specific dt parse */ err =xenon_probe_dt (pdev);if (err) - goto err_clk; + goto err_clk_axi; err =xenon_sdhc_prepare (host);if (err) - goto err_clk; + goto err_clk_axi;pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 544
Quoted 5 lines
drivers/mmc/host/sdhci-xenon.c +2
-0@@ -527,6 +540,9 @@ static int xenon_probe(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);xenon_sdhc_unprepare (host); +err_clk_axi: +if (priv->axi_clk)
clk_disable_unprepare() will do the check. So this check could be removed to simplify the err path
Quoted 13 lines
drivers/mmc/host/sdhci-xenon.c +2
-0+clk_disable_unprepare (priv->axi_clk); err_clk:clk_disable_unprepare (pltfm_host->clk); free_pltfm:@@ -538,6 +554,7 @@ static int xenon_remove(struct platform_device *pdev) {struct sdhci_host *host =platform_get_drvdata (pdev);struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct xenon_priv *priv =sdhci_pltfm_priv (pltfm_host);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);
drivers/mmc/host/sdhci-xenon.c static int xenon_remove(struct platform_device *pdev) · line 567
Quoted 5 lines
drivers/mmc/host/sdhci-xenon.c +2
-0@@ -546,6 +563,8 @@ static int xenon_remove(struct platform_device *pdev)sdhci_remove_host (host,0 );xenon_sdhc_unprepare (host); +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk);
ditto
Quoted 15 lines
drivers/mmc/host/sdhci-xenon.c +0
-0clk_disable_unprepare (pltfm_host->clk);drivers/mmc/host/sdhci-xenon.h +1
-0@@ -83,6 +83,7 @@ struct xenon_priv {unsigned char bus_width;unsigned char timing;unsigned int clock; +struct clk *axi_clk;int phy_type;/*
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Hi Jisheng,
Quoted 59 lines · Jisheng Zhang
+ DT maintainers
Quoted 55 lines · On Thu, 28 Sep 2017 17:05:20 +0200 Gregory CLEMENT wrote:
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.
Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver.
Fixes 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC corefunctionality)"
CC Stable <[email protected]>Signed-off-by Gregory CLEMENT <[email protected]>---
Hi Ulf and Adrian,This patch should be merged in 4.14-rc, as it fixes real issues.
This patch maye looks like just as a nice clean-up but it is not. On the earlier version of the series adding the support for the xenon controller there was already this axi bus clock. But at this moment the documentation for the clock on the Armada 7K/8K was missing and there was no driver for it, so we just use the clock set by the bootloader and never change them that's why it worked without any visible problem.
Then as explained in the commit log the network driver enabled the clock for us, and it happened that it was setup before the xenon driver. It is only thanks the new information we received on the clocks of the Sov and with more exhaustive testes that we found this issue and the fix for it.
Thanks,
Gregory
.../bindings/mmc/marvell,xenon-sdhci.txt | 12 ++++++----- drivers/mmc/host/sdhci-xenon.c | 25 +++++++++++++++++++--- drivers/mmc/host/sdhci-xenon.h | 1 + 3 files changed, 30 insertions(+), 8 deletions(-)Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +2
-1@@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory.
Quoted 6 lines
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt Required Properties: · line 25
Quoted 4 lines
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +1
-0- clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi".Is "bus" more suitable?
I find bus too vague.
Quoted 50 lines
Quoted 50 lines
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +4
-4- reg: * For "marvell,armada-3700-sdhci", two register areas.@@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH> - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>;@@ -126,8 +128,8 @@ Example: interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH> vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; };drivers/mmc/host/sdhci-xenon.c +2
-0@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) {struct sdhci_pltfm_host *pltfm_host;struct sdhci_host *host; +struct xenon_priv *priv;int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)return PTR_ERR (host); pltfm_host =sdhci_priv (host); + priv =sdhci_pltfm_priv (pltfm_host);/* * Link Xenon specific mmc_host_ops function, @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm;
Quoted 6 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 499
Quoted 4 lines
drivers/mmc/host/sdhci-xenon.c +4
-0+ priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) { + err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err);Since the bus clock is optional, can we remove this err msg?
I will change it in dev_info.
Quoted 27 lines
Quoted 27 lines
drivers/mmc/host/sdhci-xenon.c +10
-3+ priv->axi_clk =NULL ; + }else { + err =clk_prepare_enable (priv->axi_clk); +if (err) + goto err_clk; + } + err =mmc_of_parse (host->mmc);if (err) - goto err_clk; + goto err_clk_axi;sdhci_get_of_property (pdev);@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)/* Xenon specific dt parse */ err =xenon_probe_dt (pdev);if (err) - goto err_clk; + goto err_clk_axi; err =xenon_sdhc_prepare (host);if (err) - goto err_clk; + goto err_clk_axi;
Quoted 11 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 544
Quoted 8 lines
drivers/mmc/host/sdhci-xenon.c +2
-0pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);@@ -527,6 +540,9 @@ static int xenon_probe(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);xenon_sdhc_unprepare (host); +err_clk_axi: +if (priv->axi_clk)
clk_disable_unprepare()will do the check. So this check could be removed to simplify the err path
Right I removed it
Quoted 16 lines
Quoted 16 lines
drivers/mmc/host/sdhci-xenon.c +2
-0+clk_disable_unprepare (priv->axi_clk); err_clk:clk_disable_unprepare (pltfm_host->clk); free_pltfm:@@ -538,6 +554,7 @@ static int xenon_remove(struct platform_device *pdev) {struct sdhci_host *host =platform_get_drvdata (pdev);struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct xenon_priv *priv =sdhci_pltfm_priv (pltfm_host);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);@@ -546,6 +563,8 @@ static int xenon_remove(struct platform_device *pdev)sdhci_remove_host (host,0 );
Quoted 5 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 545
Quoted 3 lines
drivers/mmc/host/sdhci-xenon.c +2
-0xenon_sdhc_unprepare (host); +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk);ditto
OK
Thanks,
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Hello,
Quoted 8 lines · Gregory CLEMENT
Quoted 6 lines
Quoted 4 lines
- clock-names:
Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core".
+ The input clock for the AXI bus must be named as "axi".Is "bus" more suitable?
I find bus too vague.
Actually no, I believe "bus" is more common. Indeed, you could have the same IP, attached to a different interconnect I guess.
Quoted 8 lines
Quoted 8 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 497
Quoted 8 lines
drivers/mmc/host/sdhci-xenon.c +2
-0/* * Link Xenon specific mmc_host_ops function, @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm; + priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) {
-EPROBE_DEFER handling ?
Quoted 6 lines
Quoted 4 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 499
Quoted 2 lines
drivers/mmc/host/sdhci-xenon.c +2
-0+ err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err);Since the bus clock is optional, can we remove this err msg?
I will change it in
dev_info.
This clock is optional (in order to keep DT backward compatibility), so there shouldn't be any error message, be it dev_err() or dev_info().
Best regards,
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Hi Thomas,
Quoted 22 lines · Thomas Petazzoni
Hello,
Quoted 8 lines · Gregory CLEMENT
Quoted 6 lines
Quoted 4 lines
- clock-names:
Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core".
+ The input clock for the AXI bus must be named as "axi".Is "bus" more suitable?
I find bus too vague.
Actually no, I believe "bus" is more common. Indeed, you could have the same IP, attached to a different interconnect I guess.
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/mmc/host/sdhci-xenon.c +0
-0/* * Link Xenon specific mmc_host_ops function, @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm;
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
drivers/mmc/host/sdhci-xenon.c static int xenon_probe(struct platform_device *pdev) · line 497
Quoted 2 lines
drivers/mmc/host/sdhci-xenon.c +2
-0+ priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) {-EPROBE_DEFER handling ?
See
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-September/533510.html
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
In reply to Gregory CLEMENTHi Gregory,
2017-09-28 23:05 GMT+08:00 Gregory CLEMENT <[email protected]>:
Quoted 27 lines
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.
Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver.
Fixes 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC corefunctionality)"
CC Stable <[email protected]>Signed-off-by Gregory CLEMENT <[email protected]>---
Hi Ulf and Adrian,This patch should be merged in 4.14-rc, as it fixes real issues.
This patch maye looks like just as a nice clean-up but it is not. On the earlier version of the series adding the support for the xenon controller there was already this axi bus clock. But at this moment the documentation for the clock on the Armada 7K/8K was missing and there was no driver for it, so we just use the clock set by the bootloader and never change them that's why it worked without any visible problem.
Quoted 5 lines
Then as explained in the commit log the network driver enabled the clock for us, and it happened that it was setup before the xenon driver. It is only thanks the new information we received on the clocks of the Sov and with more exhaustive testes that we found this issue and the fix for it.
I know very little about clk in Linux.
But I just happened to review this very issue before I left Marvell. I had some concerns about this patch at that time. Please check the following.
1. If that network device is used again, so that clock will be setup *twice* since there are two duplicated clock setup in that network driver
and Xenon driver. Right?
2. If that network device is used again and Xenon later exists and
shutdown the clock,
will that network device be corrupted?
3. In my very own opinion, such a shared AXI bus clock might be
controlled in u-boot or
a "SoC-level" init routine.
Please correct me if there is any misunderstanding.
Thank you.
Best regards,
Hu Ziji
Quoted 154 lines
Thanks,
Gregory
.../bindings/mmc/marvell,xenon-sdhci.txt | 12 ++++++----- drivers/mmc/host/sdhci-xenon.c | 25 +++++++++++++++++++--- drivers/mmc/host/sdhci-xenon.h | 1 + 3 files changed, 30 insertions(+), 8 deletions(-)Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +7
-5@@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi". - reg: * For "marvell,armada-3700-sdhci", two register areas.@@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH> - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>;@@ -126,8 +128,8 @@ Example: interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH> vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>,<&axi_clk>; + clock-names = "core","axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; };drivers/mmc/host/sdhci-xenon.c +22
-3@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) {struct sdhci_pltfm_host *pltfm_host;struct sdhci_host *host; +struct xenon_priv *priv;int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)return PTR_ERR (host); pltfm_host =sdhci_priv (host); + priv =sdhci_pltfm_priv (pltfm_host);/* * Link Xenon specific mmc_host_ops function, @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)if (err) goto free_pltfm; + priv->axi_clk =devm_clk_get (&pdev->dev,"axi" ); +if (IS_ERR (priv->axi_clk)) { + err =PTR_ERR (priv->axi_clk); +dev_err (&pdev->dev,"Failed to setup axi clk: %d\n" , err); + priv->axi_clk =NULL ; + }else { + err =clk_prepare_enable (priv->axi_clk); +if (err) + goto err_clk; + } + err =mmc_of_parse (host->mmc);if (err) - goto err_clk; + goto err_clk_axi;sdhci_get_of_property (pdev);@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)/* Xenon specific dt parse */ err =xenon_probe_dt (pdev);if (err) - goto err_clk; + goto err_clk_axi; err =xenon_sdhc_prepare (host);if (err) - goto err_clk; + goto err_clk_axi;pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);@@ -527,6 +540,9 @@ static int xenon_probe(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);xenon_sdhc_unprepare (host); +err_clk_axi: +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk); err_clk:clk_disable_unprepare (pltfm_host->clk); free_pltfm:@@ -538,6 +554,7 @@ static int xenon_remove(struct platform_device *pdev) {struct sdhci_host *host =platform_get_drvdata (pdev);struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct xenon_priv *priv =sdhci_pltfm_priv (pltfm_host);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);@@ -546,6 +563,8 @@ static int xenon_remove(struct platform_device *pdev)sdhci_remove_host (host,0 );xenon_sdhc_unprepare (host); +if (priv->axi_clk) +clk_disable_unprepare (priv->axi_clk);clk_disable_unprepare (pltfm_host->clk);drivers/mmc/host/sdhci-xenon.h +1
-1@@ -83,6 +83,7 @@ struct xenon_priv {unsigned char bus_width;unsigned char timing;unsigned int clock; +struct clk *axi_clk;int phy_type;/* -- 2.14.1
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/1 mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock
Hi Ziji,
Quoted 36 lines · On Sat, 30 Sep 2017 10:47:39 +0800 Ziji Hu wrote:
Hi Gregory,
2017-09-28 23:05 GMT+08:00 Gregory CLEMENT <[email protected]>:
Quoted 27 lines
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.
Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver.
Fixes 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC corefunctionality)"
CC Stable <[email protected]>Signed-off-by Gregory CLEMENT <[email protected]>---
Hi Ulf and Adrian,This patch should be merged in 4.14-rc, as it fixes real issues.
This patch maye looks like just as a nice clean-up but it is not. On the earlier version of the series adding the support for the xenon controller there was already this axi bus clock. But at this moment the documentation for the clock on the Armada 7K/8K was missing and there was no driver for it, so we just use the clock set by the bootloader and never change them that's why it worked without any visible problem.
Quoted 5 lines
Then as explained in the commit log the network driver enabled the clock for us, and it happened that it was setup before the xenon driver. It is only thanks the new information we received on the clocks of the Sov and with more exhaustive testes that we found this issue and the fix for it.
Quoted 8 lines
I know very little about clk in Linux.
But I just happened to review this very issue before I left Marvell. I had some concerns about this patch at that time. Please check the following.1. If that network device is used again, so that clock will be setup *twice* since there are two duplicated clock setup in that network driver
and Xenon driver. Right?
The first "setup" will be executed, the second one just increase the enable and prepare count.
Quoted 3 lines
2. If that network device is used again and Xenon later exists and
shutdown the clock,
will that network device be corrupted?
No. The enable and prepare count is reduced to 1, nothing else could happen. The clock won't be shutdown until there's no users.
Quoted 3 lines
3. In my very own opinion, such a shared AXI bus clock might be
controlled in u-boot or
a "SoC-level" init routine.
IMHO, it's the driver's responsibility to manage its own clocks.
Thanks