This patch set does a little cleanup on PXA v2/v3 drivers and
adds an additional, optional core clock to v3 driver that is
required on Marvell Berlin BG2 and BG2CD SoCs.
This is a resend of the patches are rebased on v3.18-rc1. As usual
a branch with the patches applied on top of v3.18-rc1 can be found at
git://git.infradead.org/users/hesselba/linux-berlin.git devel/bg2-bg2cd-sdhci-v1
Patches 1-9 should go through Chris' mmc tree, I'll pick up the DT
patches 10-12.
Patch 1 removes the unused private driver data from pxav2 driver.
Patch 2 is a fix for pxav3 driver to honor MMC_DDR52 timing on
uhs signaling. AFAICS, up to now there was no user affected by it
but Sony NSZ-GS7 will be.
Patch 3 moves struct sdhci_pxa from global include to the only
driver using it now. Patch 4 removes the unused clk_enable from
it.
Patch 5 removes some wrong and unnecessary checks on struct clk
from v3 driver. Patch 6 moves the struct clk for I/O clock to
the private driver data, while Patch 7 prepares the driver for
named clocks.
Patch 8 adds support for an additional, optional core clock that
is now also documented in the binding with Patch 9.
Patches 10-12 finally add corresponding sdhci nodes to berlin2
and berlin2cd, Chromecast and NSZ-GS7 DT files.
Sebastian Hesselbarth (12):
mmc: sdhci-pxav2: Drop unused struct sdhci_pxa
mmc: sdhci-pxav3: Respect MMC_DDR52 timing on uhs signaling
mmc: sdhci-pxav3: Move private driver data to driver source
mmc: sdhci-pxav3: Remove unused clk_enable from sdhci_pxa
mmc: sdhci-pxav3: Remove checks for mandatory host clock
mmc: sdhci-pxav3: Move I/O clock to private data
mmc: sdhci-pxav3: Try to get named I/O clock first
mmc: sdhci-pxav3: Get optional core clock
mmc: sdhci-pxav3: Document clocks and additional clock-names property
ARM: dts: berlin: Add SDHCI controller nodes to BG2/BG2CD
ARM: dts: berlin: Enable WiFi on Google Chromecast
ARM: dts: berlin: Enable eMMC on Sony NSZ-GS7
.../devicetree/bindings/mmc/sdhci-pxa.txt | 7 +++
arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts | 7 +++
arch/arm/boot/dts/berlin2.dtsi | 34 ++++++++++++
arch/arm/boot/dts/berlin2cd-google-chromecast.dts | 9 ++++
arch/arm/boot/dts/berlin2cd.dtsi | 9 ++++
drivers/mmc/host/sdhci-pxav2.c | 15 ++----
drivers/mmc/host/sdhci-pxav3.c | 60 ++++++++++++++--------
include/linux/platform_data/pxa_sdhci.h | 5 --
8 files changed, 108 insertions(+), 38 deletions(-)
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--
2.1.1
Now that sdhci-pxav3 driver allows to have more than one IP clock defined,
document both clocks and clock-names properties.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
index 86223c3eda90..4dd6deb90719 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
@@ -12,6 +12,10 @@ Required properties:
* for "marvell,armada-380-sdhci", two register areas. The first one
for the SDHCI registers themselves, and the second one for the
AXI/Mbus bridge registers of the SDHCI unit.
+- clocks: Array of clocks required for SDHCI; requires at least one for
+ I/O clock.
+- clock-names: Array of names corresponding to clocks property; shall be
+ "io" for I/O clock and "core" for optional core clock.
Optional properties:
- mrvl,clk-delay-cycles: Specify a number of cycles to delay for tuning.
@@ -23,6 +27,8 @@ sdhci@d4280800 {
reg = <0xd4280800 0x800>;
bus-width = <8>;
interrupts = <27>;
+ clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
+ clock-names = "io", "core";
non-removable;
mrvl,clk-delay-cycles = <31>;
};
@@ -32,5 +38,6 @@ sdhci@d8000 {
reg = <0xd8000 0x1000>, <0xdc000 0x100>;
interrupts = <0 25 0x4>;
clocks = <&gateclk 17>;
+ clock-names = "io";
mrvl,clk-delay-cycles = <0x1F>;
};
--
2.1.1
NULL-checking a struct clk it not only wrong but also not required as
for PXAv3 driver the corresponding clock is mandatory. Remove the
checks from sdhci_pxav3_runtime_{suspend,resume}.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index d1f63d32b2cd..e52bbbb09d88 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -448,13 +448,11 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
unsigned long flags;
- if (pltfm_host->clk) {
- spin_lock_irqsave(&host->lock, flags);
- host->runtime_suspended = true;
- spin_unlock_irqrestore(&host->lock, flags);
+ spin_lock_irqsave(&host->lock, flags);
+ host->runtime_suspended = true;
+ spin_unlock_irqrestore(&host->lock, flags);
- clk_disable_unprepare(pltfm_host->clk);
- }
+ clk_disable_unprepare(pltfm_host->clk);
return 0;
}
@@ -465,13 +463,11 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
unsigned long flags;
- if (pltfm_host->clk) {
- clk_prepare_enable(pltfm_host->clk);
+ clk_prepare_enable(pltfm_host->clk);
- spin_lock_irqsave(&host->lock, flags);
- host->runtime_suspended = false;
- spin_unlock_irqrestore(&host->lock, flags);
- }
+ spin_lock_irqsave(&host->lock, flags);
+ host->runtime_suspended = false;
+ spin_unlock_irqrestore(&host->lock, flags);
return 0;
}
--
2.1.1
With support for more than one clock, we'll need to distinguish between
the clock by name. Change clock probing to first try to get "io" clock
before falling back to unnamed clock.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index a34a589670e6..3dfd97977515 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -309,7 +309,9 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
pltfm_host->priv = pxa;
- pxa->clk_io = devm_clk_get(dev, NULL);
+ pxa->clk_io = devm_clk_get(dev, "io");
+ if (IS_ERR(pxa->clk_io))
+ pxa->clk_io = devm_clk_get(dev, NULL);
if (IS_ERR(pxa->clk_io)) {
dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(pxa->clk_io);
--
2.1.1
As we are using references to the I/O clock throughout the driver,
move it to the private data. Also, in preparation for core clock,
rename it to clk_io.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e52bbbb09d88..a34a589670e6 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -59,6 +59,7 @@
#define SDCE_MISC_INT_EN (1<<1)
struct sdhci_pxa {
+ struct clk *clk_io;
u8 power_mode;
};
@@ -288,9 +289,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
const struct of_device_id *match;
-
int ret;
- struct clk *clk;
pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
if (!pxa)
@@ -310,14 +309,14 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
pltfm_host->priv = pxa;
- clk = devm_clk_get(dev, NULL);
- if (IS_ERR(clk)) {
+ pxa->clk_io = devm_clk_get(dev, NULL);
+ if (IS_ERR(pxa->clk_io)) {
dev_err(dev, "failed to get io clock\n");
- ret = PTR_ERR(clk);
+ ret = PTR_ERR(pxa->clk_io);
goto err_clk_get;
}
- pltfm_host->clk = clk;
- clk_prepare_enable(clk);
+ pltfm_host->clk = pxa->clk_io;
+ clk_prepare_enable(pxa->clk_io);
/* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR;
@@ -390,7 +389,7 @@ err_add_host:
pm_runtime_disable(&pdev->dev);
err_of_parse:
err_cd_req:
- clk_disable_unprepare(clk);
+ clk_disable_unprepare(pxa->clk_io);
err_clk_get:
err_mbus_win:
sdhci_pltfm_free(pdev);
@@ -401,12 +400,13 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_pxa *pxa = pltfm_host->priv;
pm_runtime_get_sync(&pdev->dev);
sdhci_remove_host(host, 1);
pm_runtime_disable(&pdev->dev);
- clk_disable_unprepare(pltfm_host->clk);
+ clk_disable_unprepare(pxa->clk_io);
sdhci_pltfm_free(pdev);
@@ -446,13 +446,14 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_pxa *pxa = pltfm_host->priv;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
host->runtime_suspended = true;
spin_unlock_irqrestore(&host->lock, flags);
- clk_disable_unprepare(pltfm_host->clk);
+ clk_disable_unprepare(pxa->clk_io);
return 0;
}
@@ -461,9 +462,10 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_pxa *pxa = pltfm_host->priv;
unsigned long flags;
- clk_prepare_enable(pltfm_host->clk);
+ clk_prepare_enable(pxa->clk_io);
spin_lock_irqsave(&host->lock, flags);
host->runtime_suspended = false;
--
2.1.1
With SDHCI for BG2CD, we can now enable the port and allow to access
AzureWave WiFi/BT module on Google Chromecast.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
arch/arm/boot/dts/berlin2cd-google-chromecast.dts | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
index bcd81ffc495d..8c26a2dfd4a3 100644
--- a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
+++ b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
@@ -26,4 +26,13 @@
};
};
+/*
+ * AzureWave AW-NH387 (Marvell 88W8787)
+ * 802.11b/g/n + Bluetooth 2.1
+ */
+&sdhci0 {
+ non-removable;
+ status = "okay";
+};
+
&uart0 { status = "okay"; };
--
2.1.1
clk_enable from struct sdhci_pxa is unused, remove it from the private
driver data.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 48bc8179c8fc..d1f63d32b2cd 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -59,7 +59,6 @@
#define SDCE_MISC_INT_EN (1<<1)
struct sdhci_pxa {
- u8 clk_enable;
u8 power_mode;
};
--
2.1.1
With SDHCI for BG2, we can now enable the port and allow to access
Samsung M8G2FA 8GB eMMC on Sony NSZ-GS7.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
index c72bfd468d10..5e5f3a90e465 100644
--- a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
+++ b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
@@ -26,4 +26,11 @@
};
};
+/* Samsung M8G2FA 8GB eMMC */
+&sdhci2 {
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
+
&uart0 { status = "okay"; };
--
2.1.1
Besides the I/O clock, some PXAv3 SDHCI IP also requires a core clock to
be enabled. Add an optional core clock to the corresponding driver.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 3dfd97977515..ad0badad0ebc 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -59,6 +59,7 @@
#define SDCE_MISC_INT_EN (1<<1)
struct sdhci_pxa {
+ struct clk *clk_core;
struct clk *clk_io;
u8 power_mode;
};
@@ -320,6 +321,10 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
pltfm_host->clk = pxa->clk_io;
clk_prepare_enable(pxa->clk_io);
+ pxa->clk_core = devm_clk_get(dev, "core");
+ if (!IS_ERR(pxa->clk_core))
+ clk_prepare_enable(pxa->clk_core);
+
/* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR;
@@ -392,6 +397,8 @@ err_add_host:
err_of_parse:
err_cd_req:
clk_disable_unprepare(pxa->clk_io);
+ if (!IS_ERR(pxa->clk_core))
+ clk_disable_unprepare(pxa->clk_core);
err_clk_get:
err_mbus_win:
sdhci_pltfm_free(pdev);
@@ -409,6 +416,8 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(pxa->clk_io);
+ if (!IS_ERR(pxa->clk_core))
+ clk_disable_unprepare(pxa->clk_core);
sdhci_pltfm_free(pdev);
@@ -456,6 +465,8 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
spin_unlock_irqrestore(&host->lock, flags);
clk_disable_unprepare(pxa->clk_io);
+ if (!IS_ERR(pxa->clk_core))
+ clk_disable_unprepare(pxa->clk_core);
return 0;
}
@@ -468,6 +479,8 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
unsigned long flags;
clk_prepare_enable(pxa->clk_io);
+ if (!IS_ERR(pxa->clk_core))
+ clk_prepare_enable(pxa->clk_core);
spin_lock_irqsave(&host->lock, flags);
host->runtime_suspended = false;
--
2.1.1
struct sdhci_pxa is private data of PXA SDHCI driver, but not used in
sdhci-pxav2 at all. Drop unused references to struct sdhci_pxa.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav2.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index b4c23e983baf..f98008b5ea77 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -167,23 +167,17 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
struct sdhci_host *host = NULL;
- struct sdhci_pxa *pxa = NULL;
const struct of_device_id *match;
int ret;
struct clk *clk;
- pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
- if (!pxa)
- return -ENOMEM;
-
host = sdhci_pltfm_init(pdev, NULL, 0);
- if (IS_ERR(host)) {
- kfree(pxa);
+ if (IS_ERR(host))
return PTR_ERR(host);
- }
+
pltfm_host = sdhci_priv(host);
- pltfm_host->priv = pxa;
+ pltfm_host->priv = NULL;
clk = clk_get(dev, "PXA-SDHCLK");
if (IS_ERR(clk)) {
@@ -238,7 +232,6 @@ err_add_host:
clk_put(clk);
err_clk_get:
sdhci_pltfm_free(pdev);
- kfree(pxa);
return ret;
}
@@ -246,14 +239,12 @@ static int sdhci_pxav2_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct sdhci_pxa *pxa = pltfm_host->priv;
sdhci_remove_host(host, 1);
clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
sdhci_pltfm_free(pdev);
- kfree(pxa);
return 0;
}
--
2.1.1
Marvell Berlin BG2 has three, BG2CD just one pxav3 compatible
sdhci controllers, add them to the corresponding DT SoC
includes.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
arch/arm/boot/dts/berlin2.dtsi | 34 ++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/berlin2cd.dtsi | 9 +++++++++
2 files changed, 43 insertions(+)
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index 9d7c810ebd0b..504f1add1938 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -53,6 +53,35 @@
ranges = <0 0xf7000000 0x1000000>;
+ sdhci0: sdhci@ab0000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0000 0x200>;
+ clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@ab0800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0800 0x200>;
+ clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@ab1000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab1000 0x200>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
+ clock-names = "io", "core";
+ pinctrl-0 = <&emmc_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
l2: l2-cache-controller@ac0000 {
compatible = "marvell,tauros3-cache", "arm,pl310-cache";
reg = <0xac0000 0x1000>;
@@ -252,6 +281,11 @@
reg = <0xea0000 0x400>;
clocks = <&refclk>;
clock-names = "refclk";
+
+ emmc_pmux: emmc-pmux {
+ groups = "G26";
+ function = "emmc";
+ };
};
apb@fc0000 {
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index cc1df65da504..5a19017b5d71 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -45,6 +45,15 @@
ranges = <0 0xf7000000 0x1000000>;
+ sdhci0: sdhci@ab0000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0000 0x200>;
+ clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
l2: l2-cache-controller@ac0000 {
compatible = "arm,pl310-cache";
reg = <0xac0000 0x1000>;
--
2.1.1
commit bb8175a8aa42d731a840cd474e348ac3367eb5a0
("mmc: sdhci: clarify DDR timing mode between SD-UHS and eMMC")
added MMC_DDR52 as eMMC's DDR mode to be distinguished from SD-UHS.
While the differentation may be useful, pxav3 SDHCI controller lacks
a corresponding check in its custom .set_uhs_signaling callback for
MMC_DDR52. This patch adds a new switch case for MMC_TIMING_MMC_DDR52
to MMC_TIMING_UHS_DDR50 case.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 5036d7d39529..b55c807982fe 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -211,6 +211,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
case MMC_TIMING_UHS_SDR104:
ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
break;
+ case MMC_TIMING_MMC_DDR52:
case MMC_TIMING_UHS_DDR50:
ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
break;
--
2.1.1
struct sdhci_pxa is only used in sdhci_pxa driver itself, so move it
there.
Signed-off-by: Sebastian Hesselbarth <[email protected]>
---
Cc: Chris Ball <[email protected]>
Cc: Ulf Hansson <[email protected]>
Cc: "Antoine Ténart" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/mmc/host/sdhci-pxav3.c | 5 +++++
include/linux/platform_data/pxa_sdhci.h | 5 -----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index b55c807982fe..48bc8179c8fc 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -58,6 +58,11 @@
#define SDCE_MISC_INT (1<<2)
#define SDCE_MISC_INT_EN (1<<1)
+struct sdhci_pxa {
+ u8 clk_enable;
+ u8 power_mode;
+};
+
/*
* These registers are relative to the second register region, for the
* MBus bridge.
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
index 27d3156d093a..9e20c2fb4ffd 100644
--- a/include/linux/platform_data/pxa_sdhci.h
+++ b/include/linux/platform_data/pxa_sdhci.h
@@ -55,9 +55,4 @@ struct sdhci_pxa_platdata {
unsigned int quirks2;
unsigned int pm_caps;
};
-
-struct sdhci_pxa {
- u8 clk_enable;
- u8 power_mode;
-};
#endif /* _PXA_SDHCI_H_ */
--
2.1.1
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> As we are using references to the I/O clock throughout the driver,
> move it to the private data. Also, in preparation for core clock,
> rename it to clk_io.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 24 +++++++++++++-----------
> 1 file changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index e52bbbb09d88..a34a589670e6 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -59,6 +59,7 @@
> #define SDCE_MISC_INT_EN (1<<1)
>
> struct sdhci_pxa {
> + struct clk *clk_io;
> u8 power_mode;
> };
>
> @@ -288,9 +289,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> struct sdhci_host *host = NULL;
> struct sdhci_pxa *pxa = NULL;
> const struct of_device_id *match;
> -
> int ret;
> - struct clk *clk;
>
> pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
> if (!pxa)
> @@ -310,14 +309,14 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> pltfm_host = sdhci_priv(host);
> pltfm_host->priv = pxa;
>
> - clk = devm_clk_get(dev, NULL);
> - if (IS_ERR(clk)) {
> + pxa->clk_io = devm_clk_get(dev, NULL);
> + if (IS_ERR(pxa->clk_io)) {
> dev_err(dev, "failed to get io clock\n");
> - ret = PTR_ERR(clk);
> + ret = PTR_ERR(pxa->clk_io);
> goto err_clk_get;
> }
> - pltfm_host->clk = clk;
> - clk_prepare_enable(clk);
> + pltfm_host->clk = pxa->clk_io;
Is the above still needed?
> + clk_prepare_enable(pxa->clk_io);
>
> /* enable 1/8V DDR capable */
> host->mmc->caps |= MMC_CAP_1_8V_DDR;
> @@ -390,7 +389,7 @@ err_add_host:
> pm_runtime_disable(&pdev->dev);
> err_of_parse:
> err_cd_req:
> - clk_disable_unprepare(clk);
> + clk_disable_unprepare(pxa->clk_io);
> err_clk_get:
> err_mbus_win:
> sdhci_pltfm_free(pdev);
> @@ -401,12 +400,13 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
> {
> struct sdhci_host *host = platform_get_drvdata(pdev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
>
> pm_runtime_get_sync(&pdev->dev);
> sdhci_remove_host(host, 1);
> pm_runtime_disable(&pdev->dev);
>
> - clk_disable_unprepare(pltfm_host->clk);
> + clk_disable_unprepare(pxa->clk_io);
>
> sdhci_pltfm_free(pdev);
>
> @@ -446,13 +446,14 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
> {
> struct sdhci_host *host = dev_get_drvdata(dev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
> unsigned long flags;
>
> spin_lock_irqsave(&host->lock, flags);
> host->runtime_suspended = true;
> spin_unlock_irqrestore(&host->lock, flags);
>
> - clk_disable_unprepare(pltfm_host->clk);
> + clk_disable_unprepare(pxa->clk_io);
>
> return 0;
> }
> @@ -461,9 +462,10 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
> {
> struct sdhci_host *host = dev_get_drvdata(dev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
> unsigned long flags;
>
> - clk_prepare_enable(pltfm_host->clk);
> + clk_prepare_enable(pxa->clk_io);
>
> spin_lock_irqsave(&host->lock, flags);
> host->runtime_suspended = false;
> --
> 2.1.1
>
Kind regards
Uffe
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> struct sdhci_pxa is private data of PXA SDHCI driver, but not used in
> sdhci-pxav2 at all. Drop unused references to struct sdhci_pxa.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav2.c | 15 +++------------
> 1 file changed, 3 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
> index b4c23e983baf..f98008b5ea77 100644
> --- a/drivers/mmc/host/sdhci-pxav2.c
> +++ b/drivers/mmc/host/sdhci-pxav2.c
> @@ -167,23 +167,17 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
> struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
> struct device *dev = &pdev->dev;
> struct sdhci_host *host = NULL;
> - struct sdhci_pxa *pxa = NULL;
> const struct of_device_id *match;
>
> int ret;
> struct clk *clk;
>
> - pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
> - if (!pxa)
> - return -ENOMEM;
> -
> host = sdhci_pltfm_init(pdev, NULL, 0);
> - if (IS_ERR(host)) {
> - kfree(pxa);
> + if (IS_ERR(host))
> return PTR_ERR(host);
> - }
> +
> pltfm_host = sdhci_priv(host);
> - pltfm_host->priv = pxa;
> + pltfm_host->priv = NULL;
>
> clk = clk_get(dev, "PXA-SDHCLK");
> if (IS_ERR(clk)) {
> @@ -238,7 +232,6 @@ err_add_host:
> clk_put(clk);
> err_clk_get:
> sdhci_pltfm_free(pdev);
> - kfree(pxa);
> return ret;
> }
>
> @@ -246,14 +239,12 @@ static int sdhci_pxav2_remove(struct platform_device *pdev)
> {
> struct sdhci_host *host = platform_get_drvdata(pdev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> - struct sdhci_pxa *pxa = pltfm_host->priv;
>
> sdhci_remove_host(host, 1);
>
> clk_disable_unprepare(pltfm_host->clk);
> clk_put(pltfm_host->clk);
> sdhci_pltfm_free(pdev);
> - kfree(pxa);
>
> return 0;
> }
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> commit bb8175a8aa42d731a840cd474e348ac3367eb5a0
> ("mmc: sdhci: clarify DDR timing mode between SD-UHS and eMMC")
> added MMC_DDR52 as eMMC's DDR mode to be distinguished from SD-UHS.
>
> While the differentation may be useful, pxav3 SDHCI controller lacks
> a corresponding check in its custom .set_uhs_signaling callback for
> MMC_DDR52. This patch adds a new switch case for MMC_TIMING_MMC_DDR52
> to MMC_TIMING_UHS_DDR50 case.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 5036d7d39529..b55c807982fe 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -211,6 +211,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
> case MMC_TIMING_UHS_SDR104:
> ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
> break;
> + case MMC_TIMING_MMC_DDR52:
> case MMC_TIMING_UHS_DDR50:
> ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
> break;
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> struct sdhci_pxa is only used in sdhci_pxa driver itself, so move it
> there.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 5 +++++
> include/linux/platform_data/pxa_sdhci.h | 5 -----
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index b55c807982fe..48bc8179c8fc 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -58,6 +58,11 @@
> #define SDCE_MISC_INT (1<<2)
> #define SDCE_MISC_INT_EN (1<<1)
>
> +struct sdhci_pxa {
> + u8 clk_enable;
> + u8 power_mode;
> +};
> +
> /*
> * These registers are relative to the second register region, for the
> * MBus bridge.
> diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
> index 27d3156d093a..9e20c2fb4ffd 100644
> --- a/include/linux/platform_data/pxa_sdhci.h
> +++ b/include/linux/platform_data/pxa_sdhci.h
> @@ -55,9 +55,4 @@ struct sdhci_pxa_platdata {
> unsigned int quirks2;
> unsigned int pm_caps;
> };
> -
> -struct sdhci_pxa {
> - u8 clk_enable;
> - u8 power_mode;
> -};
> #endif /* _PXA_SDHCI_H_ */
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> clk_enable from struct sdhci_pxa is unused, remove it from the private
> driver data.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 48bc8179c8fc..d1f63d32b2cd 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -59,7 +59,6 @@
> #define SDCE_MISC_INT_EN (1<<1)
>
> struct sdhci_pxa {
> - u8 clk_enable;
> u8 power_mode;
> };
>
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> NULL-checking a struct clk it not only wrong but also not required as
> for PXAv3 driver the corresponding clock is mandatory. Remove the
> checks from sdhci_pxav3_runtime_{suspend,resume}.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 20 ++++++++------------
> 1 file changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index d1f63d32b2cd..e52bbbb09d88 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -448,13 +448,11 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> unsigned long flags;
>
> - if (pltfm_host->clk) {
> - spin_lock_irqsave(&host->lock, flags);
> - host->runtime_suspended = true;
> - spin_unlock_irqrestore(&host->lock, flags);
> + spin_lock_irqsave(&host->lock, flags);
> + host->runtime_suspended = true;
> + spin_unlock_irqrestore(&host->lock, flags);
>
> - clk_disable_unprepare(pltfm_host->clk);
> - }
> + clk_disable_unprepare(pltfm_host->clk);
>
> return 0;
> }
> @@ -465,13 +463,11 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> unsigned long flags;
>
> - if (pltfm_host->clk) {
> - clk_prepare_enable(pltfm_host->clk);
> + clk_prepare_enable(pltfm_host->clk);
>
> - spin_lock_irqsave(&host->lock, flags);
> - host->runtime_suspended = false;
> - spin_unlock_irqrestore(&host->lock, flags);
> - }
> + spin_lock_irqsave(&host->lock, flags);
> + host->runtime_suspended = false;
> + spin_unlock_irqrestore(&host->lock, flags);
>
> return 0;
> }
> --
> 2.1.1
>
On 10/27/2014 02:28 PM, Ulf Hansson wrote:
> On 21 October 2014 11:22, Sebastian Hesselbarth
> <[email protected]> wrote:
>> As we are using references to the I/O clock throughout the driver,
>> move it to the private data. Also, in preparation for core clock,
>> rename it to clk_io.
>>
>> Signed-off-by: Sebastian Hesselbarth <[email protected]>
>> ---
>> Cc: Chris Ball <[email protected]>
>> Cc: Ulf Hansson <[email protected]>
>> Cc: "Antoine Ténart" <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> ---
>> drivers/mmc/host/sdhci-pxav3.c | 24 +++++++++++++-----------
>> 1 file changed, 13 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
>> index e52bbbb09d88..a34a589670e6 100644
>> --- a/drivers/mmc/host/sdhci-pxav3.c
>> +++ b/drivers/mmc/host/sdhci-pxav3.c
>> @@ -59,6 +59,7 @@
>> #define SDCE_MISC_INT_EN (1<<1)
>>
>> struct sdhci_pxa {
>> + struct clk *clk_io;
>> u8 power_mode;
>> };
>>
>> @@ -288,9 +289,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
>> struct sdhci_host *host = NULL;
>> struct sdhci_pxa *pxa = NULL;
>> const struct of_device_id *match;
>> -
>> int ret;
>> - struct clk *clk;
>>
>> pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
>> if (!pxa)
>> @@ -310,14 +309,14 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
>> pltfm_host = sdhci_priv(host);
>> pltfm_host->priv = pxa;
>>
>> - clk = devm_clk_get(dev, NULL);
>> - if (IS_ERR(clk)) {
>> + pxa->clk_io = devm_clk_get(dev, NULL);
>> + if (IS_ERR(pxa->clk_io)) {
>> dev_err(dev, "failed to get io clock\n");
>> - ret = PTR_ERR(clk);
>> + ret = PTR_ERR(pxa->clk_io);
>> goto err_clk_get;
>> }
>> - pltfm_host->clk = clk;
>> - clk_prepare_enable(clk);
>> + pltfm_host->clk = pxa->clk_io;
>
> Is the above still needed?
>
>> + clk_prepare_enable(pxa->clk_io);
Ulf,
I guess it is. It sets sdhci_pltfm_host's clk field which is used
by sdhci-pltfm.c to e.g. determine sdhci clock rate.
Sebastian
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> As we are using references to the I/O clock throughout the driver,
> move it to the private data. Also, in preparation for core clock,
> rename it to clk_io.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
Thanks! Applied for next!
Kind regards
Uffe
> ---
> drivers/mmc/host/sdhci-pxav3.c | 24 +++++++++++++-----------
> 1 file changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index e52bbbb09d88..a34a589670e6 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -59,6 +59,7 @@
> #define SDCE_MISC_INT_EN (1<<1)
>
> struct sdhci_pxa {
> + struct clk *clk_io;
> u8 power_mode;
> };
>
> @@ -288,9 +289,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> struct sdhci_host *host = NULL;
> struct sdhci_pxa *pxa = NULL;
> const struct of_device_id *match;
> -
> int ret;
> - struct clk *clk;
>
> pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
> if (!pxa)
> @@ -310,14 +309,14 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> pltfm_host = sdhci_priv(host);
> pltfm_host->priv = pxa;
>
> - clk = devm_clk_get(dev, NULL);
> - if (IS_ERR(clk)) {
> + pxa->clk_io = devm_clk_get(dev, NULL);
> + if (IS_ERR(pxa->clk_io)) {
> dev_err(dev, "failed to get io clock\n");
> - ret = PTR_ERR(clk);
> + ret = PTR_ERR(pxa->clk_io);
> goto err_clk_get;
> }
> - pltfm_host->clk = clk;
> - clk_prepare_enable(clk);
> + pltfm_host->clk = pxa->clk_io;
> + clk_prepare_enable(pxa->clk_io);
>
> /* enable 1/8V DDR capable */
> host->mmc->caps |= MMC_CAP_1_8V_DDR;
> @@ -390,7 +389,7 @@ err_add_host:
> pm_runtime_disable(&pdev->dev);
> err_of_parse:
> err_cd_req:
> - clk_disable_unprepare(clk);
> + clk_disable_unprepare(pxa->clk_io);
> err_clk_get:
> err_mbus_win:
> sdhci_pltfm_free(pdev);
> @@ -401,12 +400,13 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
> {
> struct sdhci_host *host = platform_get_drvdata(pdev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
>
> pm_runtime_get_sync(&pdev->dev);
> sdhci_remove_host(host, 1);
> pm_runtime_disable(&pdev->dev);
>
> - clk_disable_unprepare(pltfm_host->clk);
> + clk_disable_unprepare(pxa->clk_io);
>
> sdhci_pltfm_free(pdev);
>
> @@ -446,13 +446,14 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
> {
> struct sdhci_host *host = dev_get_drvdata(dev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
> unsigned long flags;
>
> spin_lock_irqsave(&host->lock, flags);
> host->runtime_suspended = true;
> spin_unlock_irqrestore(&host->lock, flags);
>
> - clk_disable_unprepare(pltfm_host->clk);
> + clk_disable_unprepare(pxa->clk_io);
>
> return 0;
> }
> @@ -461,9 +462,10 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
> {
> struct sdhci_host *host = dev_get_drvdata(dev);
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_pxa *pxa = pltfm_host->priv;
> unsigned long flags;
>
> - clk_prepare_enable(pltfm_host->clk);
> + clk_prepare_enable(pxa->clk_io);
>
> spin_lock_irqsave(&host->lock, flags);
> host->runtime_suspended = false;
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> With support for more than one clock, we'll need to distinguish between
> the clock by name. Change clock probing to first try to get "io" clock
> before falling back to unnamed clock.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index a34a589670e6..3dfd97977515 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -309,7 +309,9 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> pltfm_host = sdhci_priv(host);
> pltfm_host->priv = pxa;
>
> - pxa->clk_io = devm_clk_get(dev, NULL);
> + pxa->clk_io = devm_clk_get(dev, "io");
> + if (IS_ERR(pxa->clk_io))
> + pxa->clk_io = devm_clk_get(dev, NULL);
> if (IS_ERR(pxa->clk_io)) {
> dev_err(dev, "failed to get io clock\n");
> ret = PTR_ERR(pxa->clk_io);
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> Besides the I/O clock, some PXAv3 SDHCI IP also requires a core clock to
> be enabled. Add an optional core clock to the corresponding driver.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/mmc/host/sdhci-pxav3.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 3dfd97977515..ad0badad0ebc 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -59,6 +59,7 @@
> #define SDCE_MISC_INT_EN (1<<1)
>
> struct sdhci_pxa {
> + struct clk *clk_core;
> struct clk *clk_io;
> u8 power_mode;
> };
> @@ -320,6 +321,10 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
> pltfm_host->clk = pxa->clk_io;
> clk_prepare_enable(pxa->clk_io);
>
> + pxa->clk_core = devm_clk_get(dev, "core");
> + if (!IS_ERR(pxa->clk_core))
> + clk_prepare_enable(pxa->clk_core);
> +
> /* enable 1/8V DDR capable */
> host->mmc->caps |= MMC_CAP_1_8V_DDR;
>
> @@ -392,6 +397,8 @@ err_add_host:
> err_of_parse:
> err_cd_req:
> clk_disable_unprepare(pxa->clk_io);
> + if (!IS_ERR(pxa->clk_core))
> + clk_disable_unprepare(pxa->clk_core);
> err_clk_get:
> err_mbus_win:
> sdhci_pltfm_free(pdev);
> @@ -409,6 +416,8 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
> pm_runtime_disable(&pdev->dev);
>
> clk_disable_unprepare(pxa->clk_io);
> + if (!IS_ERR(pxa->clk_core))
> + clk_disable_unprepare(pxa->clk_core);
>
> sdhci_pltfm_free(pdev);
>
> @@ -456,6 +465,8 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
> spin_unlock_irqrestore(&host->lock, flags);
>
> clk_disable_unprepare(pxa->clk_io);
> + if (!IS_ERR(pxa->clk_core))
> + clk_disable_unprepare(pxa->clk_core);
>
> return 0;
> }
> @@ -468,6 +479,8 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
> unsigned long flags;
>
> clk_prepare_enable(pxa->clk_io);
> + if (!IS_ERR(pxa->clk_core))
> + clk_prepare_enable(pxa->clk_core);
>
> spin_lock_irqsave(&host->lock, flags);
> host->runtime_suspended = false;
> --
> 2.1.1
>
On 21 October 2014 11:22, Sebastian Hesselbarth
<[email protected]> wrote:
> Now that sdhci-pxav3 driver allows to have more than one IP clock defined,
> document both clocks and clock-names properties.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Thanks! Applied for next!
Kind regards
Uffe
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
> index 86223c3eda90..4dd6deb90719 100644
> --- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
> @@ -12,6 +12,10 @@ Required properties:
> * for "marvell,armada-380-sdhci", two register areas. The first one
> for the SDHCI registers themselves, and the second one for the
> AXI/Mbus bridge registers of the SDHCI unit.
> +- clocks: Array of clocks required for SDHCI; requires at least one for
> + I/O clock.
> +- clock-names: Array of names corresponding to clocks property; shall be
> + "io" for I/O clock and "core" for optional core clock.
>
> Optional properties:
> - mrvl,clk-delay-cycles: Specify a number of cycles to delay for tuning.
> @@ -23,6 +27,8 @@ sdhci@d4280800 {
> reg = <0xd4280800 0x800>;
> bus-width = <8>;
> interrupts = <27>;
> + clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
> + clock-names = "io", "core";
> non-removable;
> mrvl,clk-delay-cycles = <31>;
> };
> @@ -32,5 +38,6 @@ sdhci@d8000 {
> reg = <0xd8000 0x1000>, <0xdc000 0x100>;
> interrupts = <0 25 0x4>;
> clocks = <&gateclk 17>;
> + clock-names = "io";
> mrvl,clk-delay-cycles = <0x1F>;
> };
> --
> 2.1.1
>
On 21.10.2014 11:22, Sebastian Hesselbarth wrote:
> Marvell Berlin BG2 has three, BG2CD just one pxav3 compatible
> sdhci controllers, add them to the corresponding DT SoC
> includes.
>
> Signed-off-by: Sebastian Hesselbarth <[email protected]>
Applied the three DT patches to berlin/dt.
Sebastian
> ---
> Cc: Chris Ball <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Cc: "Antoine Ténart" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> arch/arm/boot/dts/berlin2.dtsi | 34 ++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/berlin2cd.dtsi | 9 +++++++++
> 2 files changed, 43 insertions(+)
>
> diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> index 9d7c810ebd0b..504f1add1938 100644
> --- a/arch/arm/boot/dts/berlin2.dtsi
> +++ b/arch/arm/boot/dts/berlin2.dtsi
> @@ -53,6 +53,35 @@
>
> ranges = <0 0xf7000000 0x1000000>;
>
> + sdhci0: sdhci@ab0000 {
> + compatible = "mrvl,pxav3-mmc";
> + reg = <0xab0000 0x200>;
> + clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
> + clock-names = "io", "core";
> + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> + status = "disabled";
> + };
> +
> + sdhci1: sdhci@ab0800 {
> + compatible = "mrvl,pxav3-mmc";
> + reg = <0xab0800 0x200>;
> + clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
> + clock-names = "io", "core";
> + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> + status = "disabled";
> + };
> +
> + sdhci2: sdhci@ab1000 {
> + compatible = "mrvl,pxav3-mmc";
> + reg = <0xab1000 0x200>;
> + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
> + clock-names = "io", "core";
> + pinctrl-0 = <&emmc_pmux>;
> + pinctrl-names = "default";
> + status = "disabled";
> + };
> +
> l2: l2-cache-controller@ac0000 {
> compatible = "marvell,tauros3-cache", "arm,pl310-cache";
> reg = <0xac0000 0x1000>;
> @@ -252,6 +281,11 @@
> reg = <0xea0000 0x400>;
> clocks = <&refclk>;
> clock-names = "refclk";
> +
> + emmc_pmux: emmc-pmux {
> + groups = "G26";
> + function = "emmc";
> + };
> };
>
> apb@fc0000 {
> diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
> index cc1df65da504..5a19017b5d71 100644
> --- a/arch/arm/boot/dts/berlin2cd.dtsi
> +++ b/arch/arm/boot/dts/berlin2cd.dtsi
> @@ -45,6 +45,15 @@
>
> ranges = <0 0xf7000000 0x1000000>;
>
> + sdhci0: sdhci@ab0000 {
> + compatible = "mrvl,pxav3-mmc";
> + reg = <0xab0000 0x200>;
> + clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
> + clock-names = "io", "core";
> + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> + status = "disabled";
> + };
> +
> l2: l2-cache-controller@ac0000 {
> compatible = "arm,pl310-cache";
> reg = <0xac0000 0x1000>;
>