All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29  1:13 ` Christian Daudt
  0 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: Grant Likely, Rob Herring, Rob Landley, Russell King, Chris Ball,
	Stephen Warren, Olof Johansson, Greg Kroah-Hartman, Wei WANG,
	Anton Vorontsov, Lars-Peter Clausen, Shawn Guo, Bill Pemberton,
	Guennadi Liakhovetski, Viresh Kumar, Sascha Hauer, Jerry Huang,
	Kevin Liu, Haojian Zhuang, Ludovic Desroches, Arnd Bergmann,
	matt.porter
  Cc: csd_b, Christian Daudt

Add a param to allow users of sdhci_pltfm to allocate private space
in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
in the same way as sdhci does for its users.
 None of the users have been migrated yet and are passing in zero to
retain their private allocation.

- todo: migrate clients to using allocation this way
- todo: remove priv variable once migration is complete

Also removed unused variable in sdhci_pltfm_init fn

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index d49bc95..0584a1c 100644
--- a/drivers/mmc/host/sdhci-bcm2835.c
+++ b/drivers/mmc/host/sdhci-bcm2835.c
@@ -148,7 +148,7 @@ static int bcm2835_sdhci_probe(struct platform_device *pdev)
 	struct sdhci_pltfm_host *pltfm_host;
 	int ret;
 
-	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
+	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 8ebb6b6..f2cc266 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -96,7 +96,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata, 0);
 }
 
 static int sdhci_cns3xxx_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 15e7803..8424839 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -130,7 +130,7 @@ static int sdhci_dove_probe(struct platform_device *pdev)
 		gpio_direction_input(priv->gpio_cd);
 	}
 
-	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0);
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err_sdhci_pltfm_init;
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 67d6dde..9a1e6fa 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -470,7 +470,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	int err;
 	struct pltfm_imx_data *imx_data;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 5e68adc..37e668f 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -262,7 +262,7 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 
 static int sdhci_esdhc_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata, 0);
 }
 
 static int sdhci_esdhc_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 200a6a9..57c514a 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
 
 static int sdhci_hlwd_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
 }
 
 static int sdhci_hlwd_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index cd0f1f6..38e38a5 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -115,10 +115,10 @@ void sdhci_get_of_property(struct platform_device *pdev) {}
 EXPORT_SYMBOL_GPL(sdhci_get_of_property);
 
 struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-				    const struct sdhci_pltfm_data *pdata)
+				    const struct sdhci_pltfm_data *pdata,
+				    size_t priv_size)
 {
 	struct sdhci_host *host;
-	struct sdhci_pltfm_host *pltfm_host;
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *iomem;
 	int ret;
@@ -134,17 +134,17 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
 
 	/* Some PCI-based MFD need the parent here */
 	if (pdev->dev.parent != &platform_bus && !np)
-		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(pdev->dev.parent,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 	else
-		host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(&pdev->dev,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err;
 	}
 
-	pltfm_host = sdhci_priv(host);
-
 	host->hw_name = dev_name(&pdev->dev);
 	if (pdata && pdata->ops)
 		host->ops = pdata->ops;
@@ -202,12 +202,13 @@ void sdhci_pltfm_free(struct platform_device *pdev)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
 
 int sdhci_pltfm_register(struct platform_device *pdev,
-			 const struct sdhci_pltfm_data *pdata)
+			const struct sdhci_pltfm_data *pdata,
+			size_t priv_size)
 {
 	struct sdhci_host *host;
 	int ret = 0;
 
-	host = sdhci_pltfm_init(pdev, pdata);
+	host = sdhci_pltfm_init(pdev, pdata, priv_size);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 1210ed1..ed4a85d 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
 	/* migrate from sdhci_of_host */
 	unsigned int clock;
 	u16 xfer_mode_shadow;
+
+	unsigned long private[0] ____cacheline_aligned;
 };
 
 #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
@@ -91,15 +93,22 @@ static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
 extern void sdhci_get_of_property(struct platform_device *pdev);
 
 extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-					  const struct sdhci_pltfm_data *pdata);
+					  const struct sdhci_pltfm_data *pdata,
+					  size_t priv_size);
 extern void sdhci_pltfm_free(struct platform_device *pdev);
 
 extern int sdhci_pltfm_register(struct platform_device *pdev,
-				const struct sdhci_pltfm_data *pdata);
+				const struct sdhci_pltfm_data *pdata,
+				size_t priv_size);
 extern int sdhci_pltfm_unregister(struct platform_device *pdev);
 
 extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
 
+static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
+{
+	return (void *)host->private;
+}
+
 #ifdef CONFIG_PM
 extern const struct dev_pm_ops sdhci_pltfm_pmops;
 #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 6a3f702..1cf093f 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -175,7 +175,7 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, NULL);
+	host = sdhci_pltfm_init(pdev, NULL, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 1ae358e..9124104 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -230,7 +230,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index e0dba74..c8b0582 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -231,7 +231,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 		return -EINVAL;
 	soc_data = match->data;
 
-	host = sdhci_pltfm_init(pdev, soc_data->pdata);
+	host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 	pltfm_host = sdhci_priv(host);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29  1:13 ` Christian Daudt
  0 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: linux-arm-kernel

Add a param to allow users of sdhci_pltfm to allocate private space
in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
in the same way as sdhci does for its users.
 None of the users have been migrated yet and are passing in zero to
retain their private allocation.

- todo: migrate clients to using allocation this way
- todo: remove priv variable once migration is complete

Also removed unused variable in sdhci_pltfm_init fn

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index d49bc95..0584a1c 100644
--- a/drivers/mmc/host/sdhci-bcm2835.c
+++ b/drivers/mmc/host/sdhci-bcm2835.c
@@ -148,7 +148,7 @@ static int bcm2835_sdhci_probe(struct platform_device *pdev)
 	struct sdhci_pltfm_host *pltfm_host;
 	int ret;
 
-	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
+	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 8ebb6b6..f2cc266 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -96,7 +96,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata, 0);
 }
 
 static int sdhci_cns3xxx_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 15e7803..8424839 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -130,7 +130,7 @@ static int sdhci_dove_probe(struct platform_device *pdev)
 		gpio_direction_input(priv->gpio_cd);
 	}
 
-	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0);
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err_sdhci_pltfm_init;
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 67d6dde..9a1e6fa 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -470,7 +470,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	int err;
 	struct pltfm_imx_data *imx_data;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 5e68adc..37e668f 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -262,7 +262,7 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 
 static int sdhci_esdhc_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata, 0);
 }
 
 static int sdhci_esdhc_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 200a6a9..57c514a 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
 
 static int sdhci_hlwd_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
 }
 
 static int sdhci_hlwd_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index cd0f1f6..38e38a5 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -115,10 +115,10 @@ void sdhci_get_of_property(struct platform_device *pdev) {}
 EXPORT_SYMBOL_GPL(sdhci_get_of_property);
 
 struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-				    const struct sdhci_pltfm_data *pdata)
+				    const struct sdhci_pltfm_data *pdata,
+				    size_t priv_size)
 {
 	struct sdhci_host *host;
-	struct sdhci_pltfm_host *pltfm_host;
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *iomem;
 	int ret;
@@ -134,17 +134,17 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
 
 	/* Some PCI-based MFD need the parent here */
 	if (pdev->dev.parent != &platform_bus && !np)
-		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(pdev->dev.parent,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 	else
-		host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(&pdev->dev,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err;
 	}
 
-	pltfm_host = sdhci_priv(host);
-
 	host->hw_name = dev_name(&pdev->dev);
 	if (pdata && pdata->ops)
 		host->ops = pdata->ops;
@@ -202,12 +202,13 @@ void sdhci_pltfm_free(struct platform_device *pdev)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
 
 int sdhci_pltfm_register(struct platform_device *pdev,
-			 const struct sdhci_pltfm_data *pdata)
+			const struct sdhci_pltfm_data *pdata,
+			size_t priv_size)
 {
 	struct sdhci_host *host;
 	int ret = 0;
 
-	host = sdhci_pltfm_init(pdev, pdata);
+	host = sdhci_pltfm_init(pdev, pdata, priv_size);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 1210ed1..ed4a85d 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
 	/* migrate from sdhci_of_host */
 	unsigned int clock;
 	u16 xfer_mode_shadow;
+
+	unsigned long private[0] ____cacheline_aligned;
 };
 
 #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
@@ -91,15 +93,22 @@ static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
 extern void sdhci_get_of_property(struct platform_device *pdev);
 
 extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-					  const struct sdhci_pltfm_data *pdata);
+					  const struct sdhci_pltfm_data *pdata,
+					  size_t priv_size);
 extern void sdhci_pltfm_free(struct platform_device *pdev);
 
 extern int sdhci_pltfm_register(struct platform_device *pdev,
-				const struct sdhci_pltfm_data *pdata);
+				const struct sdhci_pltfm_data *pdata,
+				size_t priv_size);
 extern int sdhci_pltfm_unregister(struct platform_device *pdev);
 
 extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
 
+static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
+{
+	return (void *)host->private;
+}
+
 #ifdef CONFIG_PM
 extern const struct dev_pm_ops sdhci_pltfm_pmops;
 #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 6a3f702..1cf093f 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -175,7 +175,7 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, NULL);
+	host = sdhci_pltfm_init(pdev, NULL, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 1ae358e..9124104 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -230,7 +230,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index e0dba74..c8b0582 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -231,7 +231,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 		return -EINVAL;
 	soc_data = match->data;
 
-	host = sdhci_pltfm_init(pdev, soc_data->pdata);
+	host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 	pltfm_host = sdhci_priv(host);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH V3 2/3] ARM: mmc: bcm281xx SDHCI driver
  2013-05-29  1:13 ` Christian Daudt
@ 2013-05-29  1:13   ` Christian Daudt
  -1 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: Grant Likely, Rob Herring, Rob Landley, Russell King, Chris Ball,
	Stephen Warren, Olof Johansson, Greg Kroah-Hartman, Wei WANG,
	Anton Vorontsov, Lars-Peter Clausen, Shawn Guo, Bill Pemberton,
	Guennadi Liakhovetski, Viresh Kumar, Sascha Hauer, Jerry Huang,
	Kevin Liu, Haojian Zhuang, Ludovic Desroches, Arnd Bergmann,
	matt.porter
  Cc: csd_b, Christian Daudt

Add SDHCI driver for the Broadcom 281xx SoCs. Also
add bindings for it into bcm281xx dts files.
Still missing:
 - power managemement

Changes from V2:
 - Structure cleanups
 - init space from sdhci_pltfm_init
 - replace spinlock_irqsave with mutex on sd_card_emulate
 - Reduce init_74_clocks delay and document it

Changes from V1:
 - split DT into separate patch
 - use gpio_is_valid instead of direct test
 - switch pr_debug calls to dev_dbg
 - use of_property_read_bool

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index e3bf2d6..65edf6d 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -78,6 +78,13 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9ab8f8d..2455a35 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -249,6 +249,17 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_BCM_KONA
+	tristate "SDHCI support on Broadcom KONA platform"
+	depends on ARCH_BCM
+	select MMC_SDHCI_PLTFM
+	help
+	  This selects the Broadcom Kona Secure Digital Host Controller
+	  Interface(SDHCI) support.
+	  This is used in Broadcom mobile SoCs.
+
+	  If you have a controller with this interface, say Y or M here.
+
 config MMC_SDHCI_BCM2835
 	tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
 	depends on ARCH_BCM2835
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index cd32280..cd4c845 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)		+= sdhci-bcm2835.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
new file mode 100644
index 0000000..1cba006
--- /dev/null
+++ b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/version.h>
+
+#include "sdhci-pltfm.h"
+#include "sdhci.h"
+
+#define SDHCI_SOFT_RESET			0x01000000
+#define KONA_SDHOST_CORECTRL			0x8000
+#define KONA_SDHOST_CD_PINCTRL			0x00000008
+#define KONA_SDHOST_STOP_HCLK			0x00000004
+#define KONA_SDHOST_RESET			0x00000002
+#define KONA_SDHOST_EN				0x00000001
+
+#define KONA_SDHOST_CORESTAT			0x8004
+#define KONA_SDHOST_WP				0x00000002
+#define KONA_SDHOST_CD_SW			0x00000001
+
+#define KONA_SDHOST_COREIMR			0x8008
+#define KONA_SDHOST_IP				0x00000001
+
+#define KONA_SDHOST_COREISR			0x800C
+#define KONA_SDHOST_COREIMSR			0x8010
+#define KONA_SDHOST_COREDBG1			0x8014
+#define KONA_SDHOST_COREGPO_MASK		0x8018
+
+#define SD_DETECT_GPIO_DEBOUNCE_128MS		128
+
+#define KONA_MMC_AUTOSUSPEND_DELAY		(50)
+
+struct sdhci_bcm_kona_dev {
+	struct clk	*peri_clk;
+	struct clk	*sleep_clk;
+
+	struct mutex	write_lock; /* protect back to back writes */
+	unsigned int	max_freq;
+	int		is_8bit;
+	int		irq;
+	int		cd_gpio;
+	int		wp_gpio;
+	int		non_removable;
+};
+
+
+static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
+{
+	unsigned int val;
+	unsigned long timeout;
+
+	/* This timeout should be sufficent for core to reset */
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	/* reset the host using the top level reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_RESET;
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
+		if (time_is_before_jiffies(timeout)) {
+			pr_err("Error: sd host is stuck in reset!!!\n");
+			return -EFAULT;
+		}
+	}
+
+	/* bring the host out of reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val &= ~KONA_SDHOST_RESET;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	mdelay(1);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	return 0;
+}
+
+static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
+{
+	unsigned int val;
+
+	/* enable the interrupt from the IP core */
+	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
+	val |= KONA_SDHOST_IP;
+	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
+
+	/* Enable the AHB clock gating module to the host */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_EN;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	mdelay(1);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+}
+
+/*
+ * Software emulation of the SD card insertion/removal. Set insert=1 for insert
+ * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
+ * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
+ * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
+ */
+static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
+{
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	u32 val;
+	unsigned long flags;
+
+	/*
+	 * Back-to-Back register write needs a delay of min 10uS.
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 * We keep 20uS
+	 */
+	mutex_lock(&kona_dev->write_lock);
+	udelay(20);
+	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
+
+	if (insert) {
+		if (gpio_is_valid(kona_dev->wp_gpio)) {
+			int wp_status = gpio_get_value(kona_dev->wp_gpio);
+
+			if (wp_status)
+				val |= KONA_SDHOST_WP;
+			else
+				val &= ~KONA_SDHOST_WP;
+		}
+
+		val |= KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	} else {
+		val &= ~KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	}
+	mutex_unlock(&kona_dev->write_lock);
+
+	return 0;
+}
+
+/*
+ * SD card detection interrupt handler
+ */
+static irqreturn_t sdhci_bcm_kona_pltfm_cd_interrupt(int irq, void *h)
+{
+	struct sdhci_host *host = h;
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
+
+	if (gpio_get_value_cansleep(kona_dev->cd_gpio) == 0) {
+		dev_dbg(mmc_dev(host->mmc),
+			"card inserted\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 1);
+	} else {
+		dev_dbg(mmc_dev(host->mmc),
+			"card removed\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 0);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get the base clock. Use central clock source for now. Not sure if different
+ * clock speed to each dev is allowed
+ */
+static unsigned int sdhci_bcm_kona_get_max_clk(struct sdhci_host *host)
+{
+	struct sdhci_bcm_kona_dev *kona_dev;
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+
+	return kona_dev->max_freq;
+}
+
+static unsigned int sdhci_bcm_kona_get_timeout_clock(struct sdhci_host *host)
+{
+	return sdhci_bcm_kona_get_max_clk(host);
+}
+
+static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
+				u8 power_mode)
+{
+	/*
+	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
+	 * device after power up. With minimum bus (100KHz) that
+	 * that translates to 740us
+	 */
+	if (power_mode != MMC_POWER_OFF)
+		udelay(740);
+}
+
+static struct sdhci_ops sdhci_bcm_kona_ops = {
+	.get_max_clock = sdhci_bcm_kona_get_max_clk,
+	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
+	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
+};
+
+static struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
+	.ops    = &sdhci_bcm_kona_ops,
+	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
+		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
+		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
+		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+};
+
+static const struct of_device_id sdhci_bcm_kona_of_match[] __initdata = {
+	{ .compatible = "bcm,kona-sdhci"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
+
+static int __init sdhci_bcm_kona_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sdhci_bcm_kona_dev *kona_dev = NULL;
+	struct sdhci_pltfm_host *pltfm_priv;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	int ret;
+	unsigned int irq;
+	u32 temp;
+
+	ret = 0;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
+			sizeof(*kona_dev));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
+
+	pltfm_priv = sdhci_priv(host);
+
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	mutex_init(&kona_dev->write_lock);
+
+	kona_dev->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	kona_dev->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+	if (of_property_read_bool(np, "non-removable"))
+		kona_dev->non_removable = 1;
+
+	if (of_property_read_u32(np, "bus-width", &temp) == 0 && temp == 8)
+		kona_dev->is_8bit = 1;
+
+	if (of_property_read_u32(np, "max-frequency", &kona_dev->max_freq)) {
+		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
+		ret = -ENXIO;
+		goto err_pltfm_free;
+	}
+
+	dev_dbg(dev, "non-removable=%c\n",
+		(kona_dev->non_removable) ? 'Y' : 'N');
+	dev_dbg(dev, "cd_gpio %d, wp_gpio %d\n", kona_dev->cd_gpio,
+		kona_dev->wp_gpio);
+
+	if (kona_dev->non_removable) {
+		host->mmc->caps |= MMC_CAP_NONREMOVABLE;
+		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+	}
+
+	dev_dbg(dev, "is_8bit=%c\n", (kona_dev->is_8bit) ? 'Y' : 'N');
+	if (kona_dev->is_8bit)
+		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
+	ret = sdhci_bcm_kona_sd_reset(host);
+	if (ret)
+		goto err_pltfm_free;
+
+	sdhci_bcm_kona_sd_init(host);
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(dev, "Failed sdhci_add_host\n");
+		goto err_reset;
+	}
+
+	/* if device is eMMC, emulate card insert right here */
+	if (kona_dev->non_removable) {
+		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
+		if (ret) {
+			dev_err(dev,
+				"unable to emulate card insertion\n");
+			goto err_remove_host;
+		}
+	} else if (gpio_is_valid(kona_dev->cd_gpio)) {
+		ret = devm_gpio_request(dev, kona_dev->cd_gpio, "sdio cd");
+		if (ret < 0) {
+			dev_err(mmc_dev(host->mmc),
+				"Unable to request GPIO pin %d\n",
+				kona_dev->cd_gpio);
+			goto err_remove_host;
+		}
+
+		gpio_direction_input(kona_dev->cd_gpio);
+
+		/* Set debounce for SD Card detect to maximum value (128ms)
+		 *
+		 * NOTE-1: If gpio_set_debounce() returns error we still
+		 * continue with the default debounce value set. Another reason
+		 * for doing this is that on rhea-ray boards the SD Detect GPIO
+		 * is on GPIO Expander and gpio_set_debounce() will return error
+		 * and if we return error from here, then probe() would fail and
+		 * SD detection would always fail.
+		 *
+		 * NOTE-2: We also give a msleep() of the "debounce" time here
+		 * so that we give enough time for the debounce to stabilize
+		 * before we read the gpio value in gpio_get_value_cansleep().
+		 */
+		ret = gpio_set_debounce(kona_dev->cd_gpio,
+				(SD_DETECT_GPIO_DEBOUNCE_128MS * 1000));
+		if (ret < 0) {
+			dev_err(mmc_dev(host->mmc),
+				"%s: gpio set debounce failed."
+				"default debounce value assumed\n", __func__);
+		}
+
+		/* Sleep for 128ms to allow debounce to stabilize */
+		msleep(SD_DETECT_GPIO_DEBOUNCE_128MS);
+		/* request irq for cd_gpio after the gpio debounce is
+		 * stabilized, otherwise, some bogus gpio interrupts might be
+		 * triggered.
+		 */
+		irq = gpio_to_irq(kona_dev->cd_gpio);
+		ret = devm_request_threaded_irq(dev,
+				irq,
+				NULL,
+				sdhci_bcm_kona_pltfm_cd_interrupt,
+				IRQF_TRIGGER_FALLING|
+				IRQF_TRIGGER_RISING |
+				IRQF_ONESHOT |
+				IRQF_NO_SUSPEND, "sdio cd", host);
+		if (ret) {
+			dev_err(mmc_dev(host->mmc),
+				"Failed irq %d request for gpio=%d ret=%d\n",
+				gpio_to_irq(kona_dev->cd_gpio),
+				kona_dev->cd_gpio, ret);
+			goto err_remove_host;
+		}
+		if (gpio_is_valid(kona_dev->wp_gpio)) {
+			ret = devm_gpio_request(dev,
+				kona_dev->wp_gpio, "sdio wp");
+			if (ret < 0) {
+				dev_err(&pdev->dev,
+					"Unable to request WP pin %d\n",
+					kona_dev->wp_gpio);
+				kona_dev->wp_gpio = -1;
+			} else {
+				gpio_direction_input(kona_dev->wp_gpio);
+			}
+		}
+
+		/*
+		 * Since the card detection GPIO interrupt is configured to be
+		 * edge sensitive, check the initial GPIO value here, emulate
+		 * only if the card is present
+		 */
+		if (gpio_get_value_cansleep(kona_dev->cd_gpio) == 0)
+			sdhci_bcm_kona_sd_card_emulate(host, 1);
+	}
+
+	dev_dbg(dev, "initialized properly\n");
+	return 0;
+
+err_remove_host:
+	sdhci_remove_host(host, 0);
+
+err_reset:
+	sdhci_bcm_kona_sd_reset(host);
+
+err_pltfm_free:
+	sdhci_pltfm_free(pdev);
+
+	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
+	return ret;
+}
+
+static int __exit sdhci_bcm_kona_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+	sdhci_remove_host(host, dead);
+
+	sdhci_free_host(host);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_bcm_kona_driver = {
+	.driver		= {
+		.name	= "sdhci-kona",
+		.owner	= THIS_MODULE,
+		.pm	= SDHCI_PLTFM_PMOPS,
+		.of_match_table = of_match_ptr(sdhci_bcm_kona_of_match),
+	},
+	.probe		= sdhci_bcm_kona_probe,
+	.remove		= __exit_p(sdhci_bcm_kona_remove),
+};
+module_platform_driver(sdhci_bcm_kona_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
+MODULE_AUTHOR("Broadcom");
+MODULE_LICENSE("GPL v2");
+
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH V3 2/3] ARM: mmc: bcm281xx SDHCI driver
@ 2013-05-29  1:13   ` Christian Daudt
  0 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: linux-arm-kernel

Add SDHCI driver for the Broadcom 281xx SoCs. Also
add bindings for it into bcm281xx dts files.
Still missing:
 - power managemement

Changes from V2:
 - Structure cleanups
 - init space from sdhci_pltfm_init
 - replace spinlock_irqsave with mutex on sd_card_emulate
 - Reduce init_74_clocks delay and document it

Changes from V1:
 - split DT into separate patch
 - use gpio_is_valid instead of direct test
 - switch pr_debug calls to dev_dbg
 - use of_property_read_bool

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index e3bf2d6..65edf6d 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -78,6 +78,13 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9ab8f8d..2455a35 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -249,6 +249,17 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_BCM_KONA
+	tristate "SDHCI support on Broadcom KONA platform"
+	depends on ARCH_BCM
+	select MMC_SDHCI_PLTFM
+	help
+	  This selects the Broadcom Kona Secure Digital Host Controller
+	  Interface(SDHCI) support.
+	  This is used in Broadcom mobile SoCs.
+
+	  If you have a controller with this interface, say Y or M here.
+
 config MMC_SDHCI_BCM2835
 	tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
 	depends on ARCH_BCM2835
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index cd32280..cd4c845 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)		+= sdhci-bcm2835.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
new file mode 100644
index 0000000..1cba006
--- /dev/null
+++ b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/version.h>
+
+#include "sdhci-pltfm.h"
+#include "sdhci.h"
+
+#define SDHCI_SOFT_RESET			0x01000000
+#define KONA_SDHOST_CORECTRL			0x8000
+#define KONA_SDHOST_CD_PINCTRL			0x00000008
+#define KONA_SDHOST_STOP_HCLK			0x00000004
+#define KONA_SDHOST_RESET			0x00000002
+#define KONA_SDHOST_EN				0x00000001
+
+#define KONA_SDHOST_CORESTAT			0x8004
+#define KONA_SDHOST_WP				0x00000002
+#define KONA_SDHOST_CD_SW			0x00000001
+
+#define KONA_SDHOST_COREIMR			0x8008
+#define KONA_SDHOST_IP				0x00000001
+
+#define KONA_SDHOST_COREISR			0x800C
+#define KONA_SDHOST_COREIMSR			0x8010
+#define KONA_SDHOST_COREDBG1			0x8014
+#define KONA_SDHOST_COREGPO_MASK		0x8018
+
+#define SD_DETECT_GPIO_DEBOUNCE_128MS		128
+
+#define KONA_MMC_AUTOSUSPEND_DELAY		(50)
+
+struct sdhci_bcm_kona_dev {
+	struct clk	*peri_clk;
+	struct clk	*sleep_clk;
+
+	struct mutex	write_lock; /* protect back to back writes */
+	unsigned int	max_freq;
+	int		is_8bit;
+	int		irq;
+	int		cd_gpio;
+	int		wp_gpio;
+	int		non_removable;
+};
+
+
+static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
+{
+	unsigned int val;
+	unsigned long timeout;
+
+	/* This timeout should be sufficent for core to reset */
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	/* reset the host using the top level reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_RESET;
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
+		if (time_is_before_jiffies(timeout)) {
+			pr_err("Error: sd host is stuck in reset!!!\n");
+			return -EFAULT;
+		}
+	}
+
+	/* bring the host out of reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val &= ~KONA_SDHOST_RESET;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	mdelay(1);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	return 0;
+}
+
+static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
+{
+	unsigned int val;
+
+	/* enable the interrupt from the IP core */
+	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
+	val |= KONA_SDHOST_IP;
+	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
+
+	/* Enable the AHB clock gating module to the host */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_EN;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	mdelay(1);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+}
+
+/*
+ * Software emulation of the SD card insertion/removal. Set insert=1 for insert
+ * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
+ * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
+ * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
+ */
+static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
+{
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	u32 val;
+	unsigned long flags;
+
+	/*
+	 * Back-to-Back register write needs a delay of min 10uS.
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 * We keep 20uS
+	 */
+	mutex_lock(&kona_dev->write_lock);
+	udelay(20);
+	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
+
+	if (insert) {
+		if (gpio_is_valid(kona_dev->wp_gpio)) {
+			int wp_status = gpio_get_value(kona_dev->wp_gpio);
+
+			if (wp_status)
+				val |= KONA_SDHOST_WP;
+			else
+				val &= ~KONA_SDHOST_WP;
+		}
+
+		val |= KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	} else {
+		val &= ~KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	}
+	mutex_unlock(&kona_dev->write_lock);
+
+	return 0;
+}
+
+/*
+ * SD card detection interrupt handler
+ */
+static irqreturn_t sdhci_bcm_kona_pltfm_cd_interrupt(int irq, void *h)
+{
+	struct sdhci_host *host = h;
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
+
+	if (gpio_get_value_cansleep(kona_dev->cd_gpio) == 0) {
+		dev_dbg(mmc_dev(host->mmc),
+			"card inserted\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 1);
+	} else {
+		dev_dbg(mmc_dev(host->mmc),
+			"card removed\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 0);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get the base clock. Use central clock source for now. Not sure if different
+ * clock speed to each dev is allowed
+ */
+static unsigned int sdhci_bcm_kona_get_max_clk(struct sdhci_host *host)
+{
+	struct sdhci_bcm_kona_dev *kona_dev;
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+
+	return kona_dev->max_freq;
+}
+
+static unsigned int sdhci_bcm_kona_get_timeout_clock(struct sdhci_host *host)
+{
+	return sdhci_bcm_kona_get_max_clk(host);
+}
+
+static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
+				u8 power_mode)
+{
+	/*
+	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
+	 * device after power up. With minimum bus (100KHz) that
+	 * that translates to 740us
+	 */
+	if (power_mode != MMC_POWER_OFF)
+		udelay(740);
+}
+
+static struct sdhci_ops sdhci_bcm_kona_ops = {
+	.get_max_clock = sdhci_bcm_kona_get_max_clk,
+	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
+	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
+};
+
+static struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
+	.ops    = &sdhci_bcm_kona_ops,
+	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
+		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
+		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
+		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+};
+
+static const struct of_device_id sdhci_bcm_kona_of_match[] __initdata = {
+	{ .compatible = "bcm,kona-sdhci"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
+
+static int __init sdhci_bcm_kona_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sdhci_bcm_kona_dev *kona_dev = NULL;
+	struct sdhci_pltfm_host *pltfm_priv;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	int ret;
+	unsigned int irq;
+	u32 temp;
+
+	ret = 0;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
+			sizeof(*kona_dev));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
+
+	pltfm_priv = sdhci_priv(host);
+
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	mutex_init(&kona_dev->write_lock);
+
+	kona_dev->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	kona_dev->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+	if (of_property_read_bool(np, "non-removable"))
+		kona_dev->non_removable = 1;
+
+	if (of_property_read_u32(np, "bus-width", &temp) == 0 && temp == 8)
+		kona_dev->is_8bit = 1;
+
+	if (of_property_read_u32(np, "max-frequency", &kona_dev->max_freq)) {
+		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
+		ret = -ENXIO;
+		goto err_pltfm_free;
+	}
+
+	dev_dbg(dev, "non-removable=%c\n",
+		(kona_dev->non_removable) ? 'Y' : 'N');
+	dev_dbg(dev, "cd_gpio %d, wp_gpio %d\n", kona_dev->cd_gpio,
+		kona_dev->wp_gpio);
+
+	if (kona_dev->non_removable) {
+		host->mmc->caps |= MMC_CAP_NONREMOVABLE;
+		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+	}
+
+	dev_dbg(dev, "is_8bit=%c\n", (kona_dev->is_8bit) ? 'Y' : 'N');
+	if (kona_dev->is_8bit)
+		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
+	ret = sdhci_bcm_kona_sd_reset(host);
+	if (ret)
+		goto err_pltfm_free;
+
+	sdhci_bcm_kona_sd_init(host);
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(dev, "Failed sdhci_add_host\n");
+		goto err_reset;
+	}
+
+	/* if device is eMMC, emulate card insert right here */
+	if (kona_dev->non_removable) {
+		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
+		if (ret) {
+			dev_err(dev,
+				"unable to emulate card insertion\n");
+			goto err_remove_host;
+		}
+	} else if (gpio_is_valid(kona_dev->cd_gpio)) {
+		ret = devm_gpio_request(dev, kona_dev->cd_gpio, "sdio cd");
+		if (ret < 0) {
+			dev_err(mmc_dev(host->mmc),
+				"Unable to request GPIO pin %d\n",
+				kona_dev->cd_gpio);
+			goto err_remove_host;
+		}
+
+		gpio_direction_input(kona_dev->cd_gpio);
+
+		/* Set debounce for SD Card detect to maximum value (128ms)
+		 *
+		 * NOTE-1: If gpio_set_debounce() returns error we still
+		 * continue with the default debounce value set. Another reason
+		 * for doing this is that on rhea-ray boards the SD Detect GPIO
+		 * is on GPIO Expander and gpio_set_debounce() will return error
+		 * and if we return error from here, then probe() would fail and
+		 * SD detection would always fail.
+		 *
+		 * NOTE-2: We also give a msleep() of the "debounce" time here
+		 * so that we give enough time for the debounce to stabilize
+		 * before we read the gpio value in gpio_get_value_cansleep().
+		 */
+		ret = gpio_set_debounce(kona_dev->cd_gpio,
+				(SD_DETECT_GPIO_DEBOUNCE_128MS * 1000));
+		if (ret < 0) {
+			dev_err(mmc_dev(host->mmc),
+				"%s: gpio set debounce failed."
+				"default debounce value assumed\n", __func__);
+		}
+
+		/* Sleep for 128ms to allow debounce to stabilize */
+		msleep(SD_DETECT_GPIO_DEBOUNCE_128MS);
+		/* request irq for cd_gpio after the gpio debounce is
+		 * stabilized, otherwise, some bogus gpio interrupts might be
+		 * triggered.
+		 */
+		irq = gpio_to_irq(kona_dev->cd_gpio);
+		ret = devm_request_threaded_irq(dev,
+				irq,
+				NULL,
+				sdhci_bcm_kona_pltfm_cd_interrupt,
+				IRQF_TRIGGER_FALLING|
+				IRQF_TRIGGER_RISING |
+				IRQF_ONESHOT |
+				IRQF_NO_SUSPEND, "sdio cd", host);
+		if (ret) {
+			dev_err(mmc_dev(host->mmc),
+				"Failed irq %d request for gpio=%d ret=%d\n",
+				gpio_to_irq(kona_dev->cd_gpio),
+				kona_dev->cd_gpio, ret);
+			goto err_remove_host;
+		}
+		if (gpio_is_valid(kona_dev->wp_gpio)) {
+			ret = devm_gpio_request(dev,
+				kona_dev->wp_gpio, "sdio wp");
+			if (ret < 0) {
+				dev_err(&pdev->dev,
+					"Unable to request WP pin %d\n",
+					kona_dev->wp_gpio);
+				kona_dev->wp_gpio = -1;
+			} else {
+				gpio_direction_input(kona_dev->wp_gpio);
+			}
+		}
+
+		/*
+		 * Since the card detection GPIO interrupt is configured to be
+		 * edge sensitive, check the initial GPIO value here, emulate
+		 * only if the card is present
+		 */
+		if (gpio_get_value_cansleep(kona_dev->cd_gpio) == 0)
+			sdhci_bcm_kona_sd_card_emulate(host, 1);
+	}
+
+	dev_dbg(dev, "initialized properly\n");
+	return 0;
+
+err_remove_host:
+	sdhci_remove_host(host, 0);
+
+err_reset:
+	sdhci_bcm_kona_sd_reset(host);
+
+err_pltfm_free:
+	sdhci_pltfm_free(pdev);
+
+	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
+	return ret;
+}
+
+static int __exit sdhci_bcm_kona_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+	sdhci_remove_host(host, dead);
+
+	sdhci_free_host(host);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_bcm_kona_driver = {
+	.driver		= {
+		.name	= "sdhci-kona",
+		.owner	= THIS_MODULE,
+		.pm	= SDHCI_PLTFM_PMOPS,
+		.of_match_table = of_match_ptr(sdhci_bcm_kona_of_match),
+	},
+	.probe		= sdhci_bcm_kona_probe,
+	.remove		= __exit_p(sdhci_bcm_kona_remove),
+};
+module_platform_driver(sdhci_bcm_kona_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
+MODULE_AUTHOR("Broadcom");
+MODULE_LICENSE("GPL v2");
+
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH V3 3/3] ARM: mmc: bcm281xx SDHCI driver (dt mods)
  2013-05-29  1:13 ` Christian Daudt
@ 2013-05-29  1:13   ` Christian Daudt
  -1 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: Grant Likely, Rob Herring, Rob Landley, Russell King, Chris Ball,
	Stephen Warren, Olof Johansson, Greg Kroah-Hartman, Wei WANG,
	Anton Vorontsov, Lars-Peter Clausen, Shawn Guo, Bill Pemberton,
	Guennadi Liakhovetski, Viresh Kumar, Sascha Hauer, Jerry Huang,
	Kevin Liu, Haojian Zhuang, Ludovic Desroches, Arnd Bergmann,
	matt.porter
  Cc: csd_b, Christian Daudt

Add SDHCI bindings for the Broadcom 281xx SoCs.

Changes from V2:
 - Documentation cleanups

Changes from V1:
 - split original patch into 2, one for driver and this one for dt

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt b/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt
new file mode 100644
index 0000000..094ae01
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt
@@ -0,0 +1,16 @@
+Broadcom BCM281xx SDHCI
+
+This file documents differences between the core properties in mmc.txt
+and the properties present in the bcm281xx SDHCI
+
+Required properties:
+- compatible : Should be "bcm,kona-sdhci"
+
+Example:
+
+sdio2: sdio@0x3f1a0000 {
+	compatible = "bcm,kona-sdhci";
+	reg = <0x3f1a0000 0x10000>;
+	interrupts = <0x0 74 0x4>;
+};
+
diff --git a/arch/arm/boot/dts/bcm11351-brt.dts b/arch/arm/boot/dts/bcm11351-brt.dts
index 248067c..9ae3404 100644
--- a/arch/arm/boot/dts/bcm11351-brt.dts
+++ b/arch/arm/boot/dts/bcm11351-brt.dts
@@ -27,4 +27,21 @@
 		status = "okay";
 	};
 
+	sdio0: sdio@0x3f180000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio1: sdio@0x3f190000 {
+		non-removable;
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio3: sdio@0x3f1b0000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+
 };
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
index 41b2c6c..39de6e2 100644
--- a/arch/arm/boot/dts/bcm11351.dtsi
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -60,4 +60,32 @@
 		clock-frequency = <32768>;
 	};
 
+	sdio0: sdio@0x3f180000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f180000 0x10000>;
+		interrupts = <0x0 77 0x4>;
+		status = "disabled";
+	};
+
+	sdio1: sdio@0x3f190000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f190000 0x10000>;
+		interrupts = <0x0 76 0x4>;
+		status = "disabled";
+	};
+
+	sdio2: sdio@0x3f1a0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1a0000 0x10000>;
+		interrupts = <0x0 74 0x4>;
+		status = "disabled";
+	};
+
+	sdio3: sdio@0x3f1b0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1b0000 0x10000>;
+		interrupts = <0x0 73 0x4>;
+		status = "disabled";
+	};
+
 };
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH V3 3/3] ARM: mmc: bcm281xx SDHCI driver (dt mods)
@ 2013-05-29  1:13   ` Christian Daudt
  0 siblings, 0 replies; 18+ messages in thread
From: Christian Daudt @ 2013-05-29  1:13 UTC (permalink / raw)
  To: linux-arm-kernel

Add SDHCI bindings for the Broadcom 281xx SoCs.

Changes from V2:
 - Documentation cleanups

Changes from V1:
 - split original patch into 2, one for driver and this one for dt

Signed-off-by: Christian Daudt <csd@broadcom.com>

diff --git a/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt b/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt
new file mode 100644
index 0000000..094ae01
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt
@@ -0,0 +1,16 @@
+Broadcom BCM281xx SDHCI
+
+This file documents differences between the core properties in mmc.txt
+and the properties present in the bcm281xx SDHCI
+
+Required properties:
+- compatible : Should be "bcm,kona-sdhci"
+
+Example:
+
+sdio2: sdio at 0x3f1a0000 {
+	compatible = "bcm,kona-sdhci";
+	reg = <0x3f1a0000 0x10000>;
+	interrupts = <0x0 74 0x4>;
+};
+
diff --git a/arch/arm/boot/dts/bcm11351-brt.dts b/arch/arm/boot/dts/bcm11351-brt.dts
index 248067c..9ae3404 100644
--- a/arch/arm/boot/dts/bcm11351-brt.dts
+++ b/arch/arm/boot/dts/bcm11351-brt.dts
@@ -27,4 +27,21 @@
 		status = "okay";
 	};
 
+	sdio0: sdio at 0x3f180000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio1: sdio at 0x3f190000 {
+		non-removable;
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio3: sdio at 0x3f1b0000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+
 };
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
index 41b2c6c..39de6e2 100644
--- a/arch/arm/boot/dts/bcm11351.dtsi
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -60,4 +60,32 @@
 		clock-frequency = <32768>;
 	};
 
+	sdio0: sdio at 0x3f180000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f180000 0x10000>;
+		interrupts = <0x0 77 0x4>;
+		status = "disabled";
+	};
+
+	sdio1: sdio at 0x3f190000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f190000 0x10000>;
+		interrupts = <0x0 76 0x4>;
+		status = "disabled";
+	};
+
+	sdio2: sdio at 0x3f1a0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1a0000 0x10000>;
+		interrupts = <0x0 74 0x4>;
+		status = "disabled";
+	};
+
+	sdio3: sdio at 0x3f1b0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1b0000 0x10000>;
+		interrupts = <0x0 73 0x4>;
+		status = "disabled";
+	};
+
 };
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 1/3] mmc: Add size for caller in init+register
  2013-05-29  1:13 ` Christian Daudt
@ 2013-05-29 12:01   ` Ulf Hansson
  -1 siblings, 0 replies; 18+ messages in thread
From: Ulf Hansson @ 2013-05-29 12:01 UTC (permalink / raw)
  To: Christian Daudt
  Cc: linux-doc, Jerry Huang, Grant Likely, Wei WANG, matt.porter,
	Kevin Liu, Lars-Peter Clausen, Stephen Warren, csd_b,
	Viresh Kumar, Chris Ball, plagnioj, devicetree-discuss,
	Arnd Bergmann, Sascha Hauer, Rob Herring, Bill Pemberton,
	Haojian Zhuang, Russell King, Anton Vorontsov, linux-arm-kernel,
	Greg Kroah-Hartman, linux-mmc, linux-kernel, Ludovic Desroches

On 29 May 2013 03:13, Christian Daudt <csd@broadcom.com> wrote:
> Add a param to allow users of sdhci_pltfm to allocate private space
> in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
> in the same way as sdhci does for its users.
>  None of the users have been migrated yet and are passing in zero to
> retain their private allocation.
>
> - todo: migrate clients to using allocation this way
> - todo: remove priv variable once migration is complete
>
> Also removed unused variable in sdhci_pltfm_init fn
>
> Signed-off-by: Christian Daudt <csd@broadcom.com>

Hi Christian,

Sorry if being a bit picky, do you mind using "mmc: sdhci" as the
prefix for the heading of this patch?

>
> diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
> index d49bc95..0584a1c 100644
> --- a/drivers/mmc/host/sdhci-bcm2835.c
> +++ b/drivers/mmc/host/sdhci-bcm2835.c
> @@ -148,7 +148,7 @@ static int bcm2835_sdhci_probe(struct platform_device *pdev)
>         struct sdhci_pltfm_host *pltfm_host;
>         int ret;
>
> -       host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
> +       host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
> index 8ebb6b6..f2cc266 100644
> --- a/drivers/mmc/host/sdhci-cns3xxx.c
> +++ b/drivers/mmc/host/sdhci-cns3xxx.c
> @@ -96,7 +96,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
>
>  static int sdhci_cns3xxx_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata, 0);
>  }
>
>  static int sdhci_cns3xxx_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
> index 15e7803..8424839 100644
> --- a/drivers/mmc/host/sdhci-dove.c
> +++ b/drivers/mmc/host/sdhci-dove.c
> @@ -130,7 +130,7 @@ static int sdhci_dove_probe(struct platform_device *pdev)
>                 gpio_direction_input(priv->gpio_cd);
>         }
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0);
>         if (IS_ERR(host)) {
>                 ret = PTR_ERR(host);
>                 goto err_sdhci_pltfm_init;
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 67d6dde..9a1e6fa 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -470,7 +470,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>         int err;
>         struct pltfm_imx_data *imx_data;
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 5e68adc..37e668f 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -262,7 +262,7 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
>
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata, 0);
>  }
>
>  static int sdhci_esdhc_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
> index 200a6a9..57c514a 100644
> --- a/drivers/mmc/host/sdhci-of-hlwd.c
> +++ b/drivers/mmc/host/sdhci-of-hlwd.c
> @@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
>
>  static int sdhci_hlwd_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
>  }
>
>  static int sdhci_hlwd_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
> index cd0f1f6..38e38a5 100644
> --- a/drivers/mmc/host/sdhci-pltfm.c
> +++ b/drivers/mmc/host/sdhci-pltfm.c
> @@ -115,10 +115,10 @@ void sdhci_get_of_property(struct platform_device *pdev) {}
>  EXPORT_SYMBOL_GPL(sdhci_get_of_property);
>
>  struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
> -                                   const struct sdhci_pltfm_data *pdata)
> +                                   const struct sdhci_pltfm_data *pdata,
> +                                   size_t priv_size)
>  {
>         struct sdhci_host *host;
> -       struct sdhci_pltfm_host *pltfm_host;
>         struct device_node *np = pdev->dev.of_node;
>         struct resource *iomem;
>         int ret;
> @@ -134,17 +134,17 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
>
>         /* Some PCI-based MFD need the parent here */
>         if (pdev->dev.parent != &platform_bus && !np)
> -               host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
> +               host = sdhci_alloc_host(pdev->dev.parent,
> +                       sizeof(struct sdhci_pltfm_host) + priv_size);
>         else
> -               host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
> +               host = sdhci_alloc_host(&pdev->dev,
> +                       sizeof(struct sdhci_pltfm_host) + priv_size);
>
>         if (IS_ERR(host)) {
>                 ret = PTR_ERR(host);
>                 goto err;
>         }
>
> -       pltfm_host = sdhci_priv(host);
> -
>         host->hw_name = dev_name(&pdev->dev);
>         if (pdata && pdata->ops)
>                 host->ops = pdata->ops;
> @@ -202,12 +202,13 @@ void sdhci_pltfm_free(struct platform_device *pdev)
>  EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
>
>  int sdhci_pltfm_register(struct platform_device *pdev,
> -                        const struct sdhci_pltfm_data *pdata)
> +                       const struct sdhci_pltfm_data *pdata,
> +                       size_t priv_size)
>  {
>         struct sdhci_host *host;
>         int ret = 0;
>
> -       host = sdhci_pltfm_init(pdev, pdata);
> +       host = sdhci_pltfm_init(pdev, pdata, priv_size);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
> index 1210ed1..ed4a85d 100644
> --- a/drivers/mmc/host/sdhci-pltfm.h
> +++ b/drivers/mmc/host/sdhci-pltfm.h
> @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
>         /* migrate from sdhci_of_host */
>         unsigned int clock;
>         u16 xfer_mode_shadow;
> +
> +       unsigned long private[0] ____cacheline_aligned;

Why do you need this to be "____cacheline_aligned"?

>  };
>
>  #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> @@ -91,15 +93,22 @@ static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
>  extern void sdhci_get_of_property(struct platform_device *pdev);
>
>  extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
> -                                         const struct sdhci_pltfm_data *pdata);
> +                                         const struct sdhci_pltfm_data *pdata,
> +                                         size_t priv_size);
>  extern void sdhci_pltfm_free(struct platform_device *pdev);
>
>  extern int sdhci_pltfm_register(struct platform_device *pdev,
> -                               const struct sdhci_pltfm_data *pdata);
> +                               const struct sdhci_pltfm_data *pdata,
> +                               size_t priv_size);
>  extern int sdhci_pltfm_unregister(struct platform_device *pdev);
>
>  extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
>
> +static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
> +{
> +       return (void *)host->private;
> +}
> +
>  #ifdef CONFIG_PM
>  extern const struct dev_pm_ops sdhci_pltfm_pmops;
>  #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
> diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
> index 6a3f702..1cf093f 100644
> --- a/drivers/mmc/host/sdhci-pxav2.c
> +++ b/drivers/mmc/host/sdhci-pxav2.c
> @@ -175,7 +175,7 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
>         if (!pxa)
>                 return -ENOMEM;
>
> -       host = sdhci_pltfm_init(pdev, NULL);
> +       host = sdhci_pltfm_init(pdev, NULL, 0);
>         if (IS_ERR(host)) {
>                 kfree(pxa);
>                 return PTR_ERR(host);
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 1ae358e..9124104 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -230,7 +230,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
>         if (!pxa)
>                 return -ENOMEM;
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, 0);
>         if (IS_ERR(host)) {
>                 kfree(pxa);
>                 return PTR_ERR(host);
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index e0dba74..c8b0582 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -231,7 +231,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>                 return -EINVAL;
>         soc_data = match->data;
>
> -       host = sdhci_pltfm_init(pdev, soc_data->pdata);
> +       host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>         pltfm_host = sdhci_priv(host);
> --
> 1.7.10.4
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Kind regards
Ulf Hansson

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29 12:01   ` Ulf Hansson
  0 siblings, 0 replies; 18+ messages in thread
From: Ulf Hansson @ 2013-05-29 12:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 May 2013 03:13, Christian Daudt <csd@broadcom.com> wrote:
> Add a param to allow users of sdhci_pltfm to allocate private space
> in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
> in the same way as sdhci does for its users.
>  None of the users have been migrated yet and are passing in zero to
> retain their private allocation.
>
> - todo: migrate clients to using allocation this way
> - todo: remove priv variable once migration is complete
>
> Also removed unused variable in sdhci_pltfm_init fn
>
> Signed-off-by: Christian Daudt <csd@broadcom.com>

Hi Christian,

Sorry if being a bit picky, do you mind using "mmc: sdhci" as the
prefix for the heading of this patch?

>
> diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
> index d49bc95..0584a1c 100644
> --- a/drivers/mmc/host/sdhci-bcm2835.c
> +++ b/drivers/mmc/host/sdhci-bcm2835.c
> @@ -148,7 +148,7 @@ static int bcm2835_sdhci_probe(struct platform_device *pdev)
>         struct sdhci_pltfm_host *pltfm_host;
>         int ret;
>
> -       host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
> +       host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
> index 8ebb6b6..f2cc266 100644
> --- a/drivers/mmc/host/sdhci-cns3xxx.c
> +++ b/drivers/mmc/host/sdhci-cns3xxx.c
> @@ -96,7 +96,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
>
>  static int sdhci_cns3xxx_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata, 0);
>  }
>
>  static int sdhci_cns3xxx_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
> index 15e7803..8424839 100644
> --- a/drivers/mmc/host/sdhci-dove.c
> +++ b/drivers/mmc/host/sdhci-dove.c
> @@ -130,7 +130,7 @@ static int sdhci_dove_probe(struct platform_device *pdev)
>                 gpio_direction_input(priv->gpio_cd);
>         }
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0);
>         if (IS_ERR(host)) {
>                 ret = PTR_ERR(host);
>                 goto err_sdhci_pltfm_init;
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 67d6dde..9a1e6fa 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -470,7 +470,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>         int err;
>         struct pltfm_imx_data *imx_data;
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 5e68adc..37e668f 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -262,7 +262,7 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
>
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata, 0);
>  }
>
>  static int sdhci_esdhc_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
> index 200a6a9..57c514a 100644
> --- a/drivers/mmc/host/sdhci-of-hlwd.c
> +++ b/drivers/mmc/host/sdhci-of-hlwd.c
> @@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
>
>  static int sdhci_hlwd_probe(struct platform_device *pdev)
>  {
> -       return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
> +       return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
>  }
>
>  static int sdhci_hlwd_remove(struct platform_device *pdev)
> diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
> index cd0f1f6..38e38a5 100644
> --- a/drivers/mmc/host/sdhci-pltfm.c
> +++ b/drivers/mmc/host/sdhci-pltfm.c
> @@ -115,10 +115,10 @@ void sdhci_get_of_property(struct platform_device *pdev) {}
>  EXPORT_SYMBOL_GPL(sdhci_get_of_property);
>
>  struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
> -                                   const struct sdhci_pltfm_data *pdata)
> +                                   const struct sdhci_pltfm_data *pdata,
> +                                   size_t priv_size)
>  {
>         struct sdhci_host *host;
> -       struct sdhci_pltfm_host *pltfm_host;
>         struct device_node *np = pdev->dev.of_node;
>         struct resource *iomem;
>         int ret;
> @@ -134,17 +134,17 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
>
>         /* Some PCI-based MFD need the parent here */
>         if (pdev->dev.parent != &platform_bus && !np)
> -               host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
> +               host = sdhci_alloc_host(pdev->dev.parent,
> +                       sizeof(struct sdhci_pltfm_host) + priv_size);
>         else
> -               host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
> +               host = sdhci_alloc_host(&pdev->dev,
> +                       sizeof(struct sdhci_pltfm_host) + priv_size);
>
>         if (IS_ERR(host)) {
>                 ret = PTR_ERR(host);
>                 goto err;
>         }
>
> -       pltfm_host = sdhci_priv(host);
> -
>         host->hw_name = dev_name(&pdev->dev);
>         if (pdata && pdata->ops)
>                 host->ops = pdata->ops;
> @@ -202,12 +202,13 @@ void sdhci_pltfm_free(struct platform_device *pdev)
>  EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
>
>  int sdhci_pltfm_register(struct platform_device *pdev,
> -                        const struct sdhci_pltfm_data *pdata)
> +                       const struct sdhci_pltfm_data *pdata,
> +                       size_t priv_size)
>  {
>         struct sdhci_host *host;
>         int ret = 0;
>
> -       host = sdhci_pltfm_init(pdev, pdata);
> +       host = sdhci_pltfm_init(pdev, pdata, priv_size);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
> index 1210ed1..ed4a85d 100644
> --- a/drivers/mmc/host/sdhci-pltfm.h
> +++ b/drivers/mmc/host/sdhci-pltfm.h
> @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
>         /* migrate from sdhci_of_host */
>         unsigned int clock;
>         u16 xfer_mode_shadow;
> +
> +       unsigned long private[0] ____cacheline_aligned;

Why do you need this to be "____cacheline_aligned"?

>  };
>
>  #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> @@ -91,15 +93,22 @@ static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
>  extern void sdhci_get_of_property(struct platform_device *pdev);
>
>  extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
> -                                         const struct sdhci_pltfm_data *pdata);
> +                                         const struct sdhci_pltfm_data *pdata,
> +                                         size_t priv_size);
>  extern void sdhci_pltfm_free(struct platform_device *pdev);
>
>  extern int sdhci_pltfm_register(struct platform_device *pdev,
> -                               const struct sdhci_pltfm_data *pdata);
> +                               const struct sdhci_pltfm_data *pdata,
> +                               size_t priv_size);
>  extern int sdhci_pltfm_unregister(struct platform_device *pdev);
>
>  extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
>
> +static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
> +{
> +       return (void *)host->private;
> +}
> +
>  #ifdef CONFIG_PM
>  extern const struct dev_pm_ops sdhci_pltfm_pmops;
>  #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
> diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
> index 6a3f702..1cf093f 100644
> --- a/drivers/mmc/host/sdhci-pxav2.c
> +++ b/drivers/mmc/host/sdhci-pxav2.c
> @@ -175,7 +175,7 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
>         if (!pxa)
>                 return -ENOMEM;
>
> -       host = sdhci_pltfm_init(pdev, NULL);
> +       host = sdhci_pltfm_init(pdev, NULL, 0);
>         if (IS_ERR(host)) {
>                 kfree(pxa);
>                 return PTR_ERR(host);
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 1ae358e..9124104 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -230,7 +230,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
>         if (!pxa)
>                 return -ENOMEM;
>
> -       host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
> +       host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, 0);
>         if (IS_ERR(host)) {
>                 kfree(pxa);
>                 return PTR_ERR(host);
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index e0dba74..c8b0582 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -231,7 +231,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>                 return -EINVAL;
>         soc_data = match->data;
>
> -       host = sdhci_pltfm_init(pdev, soc_data->pdata);
> +       host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>         pltfm_host = sdhci_priv(host);
> --
> 1.7.10.4
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Kind regards
Ulf Hansson

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 1/3] mmc: Add size for caller in init+register
  2013-05-29  1:13 ` Christian Daudt
@ 2013-05-29 14:17     ` Arnd Bergmann
  -1 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:17 UTC (permalink / raw)
  To: Christian Daudt
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA, Jerry Huang, Wei WANG,
	matt.porter-QSEj5FYQhm4dnm+yROfE0A, Kevin Liu,
	Lars-Peter Clausen, Stephen Warren, Viresh Kumar, Chris Ball,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Sascha Hauer,
	Rob Herring, Bill Pemberton, Russell King, Anton Vorontsov,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guennadi Liakhovetski

On Wednesday 29 May 2013, Christian Daudt wrote:
> Add a param to allow users of sdhci_pltfm to allocate private space
> in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
> in the same way as sdhci does for its users.
>  None of the users have been migrated yet and are passing in zero to
> retain their private allocation.
> 
> - todo: migrate clients to using allocation this way
> - todo: remove priv variable once migration is complete
> 
> Also removed unused variable in sdhci_pltfm_init fn
> 
> Signed-off-by: Christian Daudt <csd-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29 14:17     ` Arnd Bergmann
  0 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 29 May 2013, Christian Daudt wrote:
> Add a param to allow users of sdhci_pltfm to allocate private space
> in calls to sdhci_pltfm_init+sdhci_pltfm_register. This is implemented
> in the same way as sdhci does for its users.
>  None of the users have been migrated yet and are passing in zero to
> retain their private allocation.
> 
> - todo: migrate clients to using allocation this way
> - todo: remove priv variable once migration is complete
> 
> Also removed unused variable in sdhci_pltfm_init fn
> 
> Signed-off-by: Christian Daudt <csd@broadcom.com>

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 1/3] mmc: Add size for caller in init+register
  2013-05-29 12:01   ` Ulf Hansson
@ 2013-05-29 14:19       ` Arnd Bergmann
  -1 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:19 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA, Christian Daudt, Jerry Huang,
	Wei WANG, matt.porter-QSEj5FYQhm4dnm+yROfE0A, Kevin Liu,
	Lars-Peter Clausen, Russell King, Viresh Kumar, Chris Ball,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Sascha Hauer,
	Rob Herring, Bill Pemberton, Stephen Warren, Anton Vorontsov,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guennadi Liakhovetski

On Wednesday 29 May 2013, Ulf Hansson wrote:
> > diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
> > index 1210ed1..ed4a85d 100644
> > --- a/drivers/mmc/host/sdhci-pltfm.h
> > +++ b/drivers/mmc/host/sdhci-pltfm.h
> > @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
> >         /* migrate from sdhci_of_host */
> >         unsigned int clock;
> >         u16 xfer_mode_shadow;
> > +
> > +       unsigned long private[0] ____cacheline_aligned;
> 
> Why do you need this to be "____cacheline_aligned"?

This is common practice for additional members in data structures
like this. The reason is that we append a structure which
may have larger alignment requirements than 'unsigned long'.

The kmalloc function generally returns a cache line aligned
object, so this provides the same alignment that we get
with a separate allocation.

	Arnd

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29 14:19       ` Arnd Bergmann
  0 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 29 May 2013, Ulf Hansson wrote:
> > diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
> > index 1210ed1..ed4a85d 100644
> > --- a/drivers/mmc/host/sdhci-pltfm.h
> > +++ b/drivers/mmc/host/sdhci-pltfm.h
> > @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
> >         /* migrate from sdhci_of_host */
> >         unsigned int clock;
> >         u16 xfer_mode_shadow;
> > +
> > +       unsigned long private[0] ____cacheline_aligned;
> 
> Why do you need this to be "____cacheline_aligned"?

This is common practice for additional members in data structures
like this. The reason is that we append a structure which
may have larger alignment requirements than 'unsigned long'.

The kmalloc function generally returns a cache line aligned
object, so this provides the same alignment that we get
with a separate allocation.

	Arnd

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 1/3] mmc: Add size for caller in init+register
  2013-05-29 14:19       ` Arnd Bergmann
@ 2013-05-29 14:25         ` Ulf Hansson
  -1 siblings, 0 replies; 18+ messages in thread
From: Ulf Hansson @ 2013-05-29 14:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-doc, Christian Daudt, Jerry Huang, Grant Likely, Wei WANG,
	matt.porter, Kevin Liu, Lars-Peter Clausen, Russell King, csd_b,
	Viresh Kumar, Chris Ball, plagnioj, Sascha Hauer,
	devicetree-discuss, Rob Herring, Bill Pemberton, Haojian Zhuang,
	Stephen Warren, Anton Vorontsov, linux-arm-kernel,
	Greg Kroah-Hartman, linux-mmc, linux-kernel, Ludovic Desroches

On 29 May 2013 16:19, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 29 May 2013, Ulf Hansson wrote:
>> > diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
>> > index 1210ed1..ed4a85d 100644
>> > --- a/drivers/mmc/host/sdhci-pltfm.h
>> > +++ b/drivers/mmc/host/sdhci-pltfm.h
>> > @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
>> >         /* migrate from sdhci_of_host */
>> >         unsigned int clock;
>> >         u16 xfer_mode_shadow;
>> > +
>> > +       unsigned long private[0] ____cacheline_aligned;
>>
>> Why do you need this to be "____cacheline_aligned"?
>
> This is common practice for additional members in data structures
> like this. The reason is that we append a structure which
> may have larger alignment requirements than 'unsigned long'.
>
> The kmalloc function generally returns a cache line aligned
> object, so this provides the same alignment that we get
> with a separate allocation.
>
>         Arnd
>

Arnd, thanks for the explanation!

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 1/3] mmc: Add size for caller in init+register
@ 2013-05-29 14:25         ` Ulf Hansson
  0 siblings, 0 replies; 18+ messages in thread
From: Ulf Hansson @ 2013-05-29 14:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 May 2013 16:19, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 29 May 2013, Ulf Hansson wrote:
>> > diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
>> > index 1210ed1..ed4a85d 100644
>> > --- a/drivers/mmc/host/sdhci-pltfm.h
>> > +++ b/drivers/mmc/host/sdhci-pltfm.h
>> > @@ -27,6 +27,8 @@ struct sdhci_pltfm_host {
>> >         /* migrate from sdhci_of_host */
>> >         unsigned int clock;
>> >         u16 xfer_mode_shadow;
>> > +
>> > +       unsigned long private[0] ____cacheline_aligned;
>>
>> Why do you need this to be "____cacheline_aligned"?
>
> This is common practice for additional members in data structures
> like this. The reason is that we append a structure which
> may have larger alignment requirements than 'unsigned long'.
>
> The kmalloc function generally returns a cache line aligned
> object, so this provides the same alignment that we get
> with a separate allocation.
>
>         Arnd
>

Arnd, thanks for the explanation!

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 2/3] ARM: mmc: bcm281xx SDHCI driver
  2013-05-29  1:13   ` Christian Daudt
@ 2013-05-29 14:25       ` Arnd Bergmann
  -1 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:25 UTC (permalink / raw)
  To: Christian Daudt
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA, Jerry Huang, Wei WANG,
	matt.porter-QSEj5FYQhm4dnm+yROfE0A, Kevin Liu,
	Lars-Peter Clausen, Stephen Warren, Viresh Kumar, Chris Ball,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Sascha Hauer,
	Rob Herring, Bill Pemberton, Russell King, Anton Vorontsov,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guennadi Liakhovetski

On Wednesday 29 May 2013, Christian Daudt wrote:
> +static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
> +{

> +	/*
> +	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
> +	 * Back-to-Back writes to same register needs delay when SD bus clock
> +	 * is very low w.r.t AHB clock, mainly during boot-time and during card
> +	 * insert-removal.
> +	 */
> +	mdelay(1);
> +	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);

This is now called always without spinlocks held and interrupts enabled,
so it should really be msleep() not mdelay().

> +static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
> +{
> +	unsigned int val;
> +
> +	/* enable the interrupt from the IP core */
> +	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
> +	val |= KONA_SDHOST_IP;
> +	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
> +
> +	/* Enable the AHB clock gating module to the host */
> +	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
> +	val |= KONA_SDHOST_EN;
> +
> +	/*
> +	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
> +	 * Back-to-Back writes to same register needs delay when SD bus clock
> +	 * is very low w.r.t AHB clock, mainly during boot-time and during card
> +	 * insert-removal.
> +	 */
> +	mdelay(1);
> +	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
> +}

Same here.

Looks good aside from that.

	Arnd

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 2/3] ARM: mmc: bcm281xx SDHCI driver
@ 2013-05-29 14:25       ` Arnd Bergmann
  0 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 29 May 2013, Christian Daudt wrote:
> +static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
> +{

> +	/*
> +	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
> +	 * Back-to-Back writes to same register needs delay when SD bus clock
> +	 * is very low w.r.t AHB clock, mainly during boot-time and during card
> +	 * insert-removal.
> +	 */
> +	mdelay(1);
> +	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);

This is now called always without spinlocks held and interrupts enabled,
so it should really be msleep() not mdelay().

> +static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
> +{
> +	unsigned int val;
> +
> +	/* enable the interrupt from the IP core */
> +	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
> +	val |= KONA_SDHOST_IP;
> +	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
> +
> +	/* Enable the AHB clock gating module to the host */
> +	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
> +	val |= KONA_SDHOST_EN;
> +
> +	/*
> +	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
> +	 * Back-to-Back writes to same register needs delay when SD bus clock
> +	 * is very low w.r.t AHB clock, mainly during boot-time and during card
> +	 * insert-removal.
> +	 */
> +	mdelay(1);
> +	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
> +}

Same here.

Looks good aside from that.

	Arnd

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH V3 3/3] ARM: mmc: bcm281xx SDHCI driver (dt mods)
  2013-05-29  1:13   ` Christian Daudt
@ 2013-05-29 14:27       ` Arnd Bergmann
  -1 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:27 UTC (permalink / raw)
  To: Christian Daudt
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA, Jerry Huang, Wei WANG,
	matt.porter-QSEj5FYQhm4dnm+yROfE0A, Kevin Liu,
	Lars-Peter Clausen, Stephen Warren, Viresh Kumar, Chris Ball,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Sascha Hauer,
	Rob Herring, Bill Pemberton, Russell King, Anton Vorontsov,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guennadi Liakhovetski

On Wednesday 29 May 2013, Christian Daudt wrote:
> +       sdio0: sdio@0x3f180000 {
> +               max-frequency = <48000000>;
> +               status = "okay";
> +       };
> +

On a general note, there is no need to duplicate both the label and the
name here, one of the two is enough. The easiest way to write this
in a board file is

&sdio {
	max-frequency = <48000000>;
	status = "okay";
};

Your version is not wrong though, so

Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH V3 3/3] ARM: mmc: bcm281xx SDHCI driver (dt mods)
@ 2013-05-29 14:27       ` Arnd Bergmann
  0 siblings, 0 replies; 18+ messages in thread
From: Arnd Bergmann @ 2013-05-29 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 29 May 2013, Christian Daudt wrote:
> +       sdio0: sdio at 0x3f180000 {
> +               max-frequency = <48000000>;
> +               status = "okay";
> +       };
> +

On a general note, there is no need to duplicate both the label and the
name here, one of the two is enough. The easiest way to write this
in a board file is

&sdio {
	max-frequency = <48000000>;
	status = "okay";
};

Your version is not wrong though, so

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2013-05-29 14:27 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-29  1:13 [PATCH V3 1/3] mmc: Add size for caller in init+register Christian Daudt
2013-05-29  1:13 ` Christian Daudt
2013-05-29  1:13 ` [PATCH V3 2/3] ARM: mmc: bcm281xx SDHCI driver Christian Daudt
2013-05-29  1:13   ` Christian Daudt
     [not found]   ` <1369790016-13270-2-git-send-email-csd-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2013-05-29 14:25     ` Arnd Bergmann
2013-05-29 14:25       ` Arnd Bergmann
2013-05-29  1:13 ` [PATCH V3 3/3] ARM: mmc: bcm281xx SDHCI driver (dt mods) Christian Daudt
2013-05-29  1:13   ` Christian Daudt
     [not found]   ` <1369790016-13270-3-git-send-email-csd-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2013-05-29 14:27     ` Arnd Bergmann
2013-05-29 14:27       ` Arnd Bergmann
2013-05-29 12:01 ` [PATCH V3 1/3] mmc: Add size for caller in init+register Ulf Hansson
2013-05-29 12:01   ` Ulf Hansson
     [not found]   ` <CAPDyKFoPO0KTfW_i1EP8urSUT+U8yEaafrE2HdN2mmEkYCZm-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-05-29 14:19     ` Arnd Bergmann
2013-05-29 14:19       ` Arnd Bergmann
2013-05-29 14:25       ` Ulf Hansson
2013-05-29 14:25         ` Ulf Hansson
     [not found] ` <1369790016-13270-1-git-send-email-csd-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2013-05-29 14:17   ` Arnd Bergmann
2013-05-29 14:17     ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.