Skip to content

Commit bb16ea1

Browse files
gclementstorulf
authored andcommitted
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. Fixes: 3a3748d ("mmc: sdhci-xenon: Add Marvell Xenon SDHC core functionality)" CC: Stable <[email protected]> Tested-by: Zhoujie Wu <[email protected]> Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: Ulf Hansson <[email protected]>
1 parent 0a44697 commit bb16ea1

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ Required Properties:
1616

1717
- clocks:
1818
Array of clocks required for SDHC.
19-
Require at least input clock for Xenon IP core.
19+
Require at least input clock for Xenon IP core. For Armada AP806 and
20+
CP110, the AXI clock is also mandatory.
2021

2122
- clock-names:
2223
Array of names corresponding to clocks property.
2324
The input clock for Xenon IP core should be named as "core".
25+
The input clock for the AXI bus must be named as "axi".
2426

2527
- reg:
2628
* For "marvell,armada-3700-sdhci", two register areas.
@@ -106,8 +108,8 @@ Example:
106108
compatible = "marvell,armada-ap806-sdhci";
107109
reg = <0xaa0000 0x1000>;
108110
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>
109-
clocks = <&emmc_clk>;
110-
clock-names = "core";
111+
clocks = <&emmc_clk>,<&axi_clk>;
112+
clock-names = "core", "axi";
111113
bus-width = <4>;
112114
marvell,xenon-phy-slow-mode;
113115
marvell,xenon-tun-count = <11>;
@@ -126,8 +128,8 @@ Example:
126128
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>
127129
vqmmc-supply = <&sd_vqmmc_regulator>;
128130
vmmc-supply = <&sd_vmmc_regulator>;
129-
clocks = <&sdclk>;
130-
clock-names = "core";
131+
clocks = <&sdclk>, <&axi_clk>;
132+
clock-names = "core", "axi";
131133
bus-width = <4>;
132134
marvell,xenon-tun-count = <9>;
133135
};

drivers/mmc/host/sdhci-xenon.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev)
466466
{
467467
struct sdhci_pltfm_host *pltfm_host;
468468
struct sdhci_host *host;
469+
struct xenon_priv *priv;
469470
int err;
470471

471472
host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,
@@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev)
474475
return PTR_ERR(host);
475476

476477
pltfm_host = sdhci_priv(host);
478+
priv = sdhci_pltfm_priv(pltfm_host);
477479

478480
/*
479481
* Link Xenon specific mmc_host_ops function,
@@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev)
491493
if (err)
492494
goto free_pltfm;
493495

496+
priv->axi_clk = devm_clk_get(&pdev->dev, "axi");
497+
if (IS_ERR(priv->axi_clk)) {
498+
err = PTR_ERR(priv->axi_clk);
499+
if (err == -EPROBE_DEFER)
500+
goto err_clk;
501+
} else {
502+
err = clk_prepare_enable(priv->axi_clk);
503+
if (err)
504+
goto err_clk;
505+
}
506+
494507
err = mmc_of_parse(host->mmc);
495508
if (err)
496-
goto err_clk;
509+
goto err_clk_axi;
497510

498511
sdhci_get_of_property(pdev);
499512

@@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev)
502515
/* Xenon specific dt parse */
503516
err = xenon_probe_dt(pdev);
504517
if (err)
505-
goto err_clk;
518+
goto err_clk_axi;
506519

507520
err = xenon_sdhc_prepare(host);
508521
if (err)
509-
goto err_clk;
522+
goto err_clk_axi;
510523

511524
pm_runtime_get_noresume(&pdev->dev);
512525
pm_runtime_set_active(&pdev->dev);
@@ -527,6 +540,8 @@ static int xenon_probe(struct platform_device *pdev)
527540
pm_runtime_disable(&pdev->dev);
528541
pm_runtime_put_noidle(&pdev->dev);
529542
xenon_sdhc_unprepare(host);
543+
err_clk_axi:
544+
clk_disable_unprepare(priv->axi_clk);
530545
err_clk:
531546
clk_disable_unprepare(pltfm_host->clk);
532547
free_pltfm:
@@ -538,6 +553,7 @@ static int xenon_remove(struct platform_device *pdev)
538553
{
539554
struct sdhci_host *host = platform_get_drvdata(pdev);
540555
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
556+
struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
541557

542558
pm_runtime_get_sync(&pdev->dev);
543559
pm_runtime_disable(&pdev->dev);
@@ -546,7 +562,7 @@ static int xenon_remove(struct platform_device *pdev)
546562
sdhci_remove_host(host, 0);
547563

548564
xenon_sdhc_unprepare(host);
549-
565+
clk_disable_unprepare(priv->axi_clk);
550566
clk_disable_unprepare(pltfm_host->clk);
551567

552568
sdhci_pltfm_free(pdev);

drivers/mmc/host/sdhci-xenon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct xenon_priv {
8383
unsigned char bus_width;
8484
unsigned char timing;
8585
unsigned int clock;
86+
struct clk *axi_clk;
8687

8788
int phy_type;
8889
/*

0 commit comments

Comments
 (0)