* [PATCH v2 1/7] mmc: sdhci: make sdhci-pltfm device drivers self registered
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 14:24 ` Anton Vorontsov
2011-05-05 13:22 ` [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data Shawn Guo
` (6 subsequent siblings)
7 siblings, 1 reply; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
The patch turns the common stuff in sdhci-pltfm.c into functions, and
add device drivers their own .probe and .remove which in turn call
into the common functions, so that those sdhci-pltfm device drivers
register itself and keep all device specific things away from common
sdhci-pltfm file.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/mmc/host/Kconfig | 32 ++++----
drivers/mmc/host/Makefile | 11 +--
drivers/mmc/host/sdhci-cns3xxx.c | 42 +++++++++-
drivers/mmc/host/sdhci-dove.c | 42 +++++++++-
drivers/mmc/host/sdhci-esdhc-imx.c | 112 ++++++++++++++++++-------
drivers/mmc/host/sdhci-pltfm.c | 157 +++++++++---------------------------
drivers/mmc/host/sdhci-pltfm.h | 17 +++-
drivers/mmc/host/sdhci-tegra.c | 118 +++++++++++++++++++--------
include/linux/mmc/sdhci-pltfm.h | 6 --
9 files changed, 317 insertions(+), 220 deletions(-)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index b981715..799e935 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -113,28 +113,27 @@ config MMC_SDHCI_OF_HLWD
If unsure, say N.
config MMC_SDHCI_PLTFM
- tristate "SDHCI support on the platform specific bus"
+ bool
depends on MMC_SDHCI
help
- This selects the platform specific bus support for Secure Digital Host
- Controller Interface.
-
- If you have a controller with this interface, say Y or M here.
-
- If unsure, say N.
+ This selects the platform common function support for Secure Digital
+ Host Controller Interface.
config MMC_SDHCI_CNS3XXX
- bool "SDHCI support on the Cavium Networks CNS3xxx SoC"
+ tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
depends on ARCH_CNS3XXX
- depends on MMC_SDHCI_PLTFM
+ depends on MMC_SDHCI
+ select MMC_SDHCI_PLTFM
help
This selects the SDHCI support for CNS3xxx System-on-Chip devices.
If unsure, say N.
config MMC_SDHCI_ESDHC_IMX
- bool "SDHCI platform support for the Freescale eSDHC i.MX controller"
- depends on MMC_SDHCI_PLTFM && (ARCH_MX25 || ARCH_MX35 || ARCH_MX5)
+ tristate "SDHCI platform support for the Freescale eSDHC i.MX controller"
+ depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX5
+ depends on MMC_SDHCI
+ select MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
help
This selects the Freescale eSDHC controller support on the platform
@@ -143,9 +142,10 @@ config MMC_SDHCI_ESDHC_IMX
If unsure, say N.
config MMC_SDHCI_DOVE
- bool "SDHCI support on Marvell's Dove SoC"
+ tristate "SDHCI support on Marvell's Dove SoC"
depends on ARCH_DOVE
- depends on MMC_SDHCI_PLTFM
+ depends on MMC_SDHCI
+ select MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
help
This selects the Secure Digital Host Controller Interface in
@@ -154,8 +154,10 @@ config MMC_SDHCI_DOVE
If unsure, say N.
config MMC_SDHCI_TEGRA
- bool "SDHCI platform support for the Tegra SD/MMC Controller"
- depends on MMC_SDHCI_PLTFM && ARCH_TEGRA
+ tristate "SDHCI platform support for the Tegra SD/MMC Controller"
+ depends on ARCH_TEGRA
+ depends on MMC_SDHCI
+ select MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
help
This selects the Tegra SD/MMC controller. If you have a Tegra
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 4f1df0a..95fddb8 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -43,12 +43,11 @@ obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
obj-$(CONFIG_MMC_USHC) += ushc.o
-obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-platform.o
-sdhci-platform-y := sdhci-pltfm.o
-sdhci-platform-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
-sdhci-platform-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
-sdhci-platform-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
-sdhci-platform-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
+obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
+obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
+obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
+obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
+obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
sdhci-of-y := sdhci-of-core.o
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 9ebd1d7..ac4b26f 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -86,7 +86,7 @@ static struct sdhci_ops sdhci_cns3xxx_ops = {
.set_clock = sdhci_cns3xxx_set_clock,
};
-struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
+static struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
.ops = &sdhci_cns3xxx_ops,
.quirks = SDHCI_QUIRK_BROKEN_DMA |
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
@@ -95,3 +95,43 @@ struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
SDHCI_QUIRK_NONSTANDARD_CLOCK,
};
+
+static int __devinit sdhci_cns3xxx_probe(struct platform_device *pdev)
+{
+ return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
+}
+
+static int __devexit sdhci_cns3xxx_remove(struct platform_device *pdev)
+{
+ return sdhci_pltfm_unregister(pdev);
+}
+
+static struct platform_driver sdhci_cns3xxx_driver = {
+ .driver = {
+ .name = "sdhci-cns3xxx",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_cns3xxx_probe,
+ .remove = __devexit_p(sdhci_cns3xxx_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
+};
+
+static int __init sdhci_cns3xxx_init(void)
+{
+ return platform_driver_register(&sdhci_cns3xxx_driver);
+}
+module_init(sdhci_cns3xxx_init);
+
+static void __exit sdhci_cns3xxx_exit(void)
+{
+ platform_driver_unregister(&sdhci_cns3xxx_driver);
+}
+module_exit(sdhci_cns3xxx_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for CNS3xxx");
+MODULE_AUTHOR("Scott Shu, "
+ "Anton Vorontsov <avorontsov@mvista.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 2aeef4f..49aa533 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -61,10 +61,50 @@ static struct sdhci_ops sdhci_dove_ops = {
.read_l = sdhci_dove_readl,
};
-struct sdhci_pltfm_data sdhci_dove_pdata = {
+static struct sdhci_pltfm_data sdhci_dove_pdata = {
.ops = &sdhci_dove_ops,
.quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
SDHCI_QUIRK_NO_BUSY_IRQ |
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
SDHCI_QUIRK_FORCE_DMA,
};
+
+static int __devinit sdhci_dove_probe(struct platform_device *pdev)
+{
+ return sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
+}
+
+static int __devexit sdhci_dove_remove(struct platform_device *pdev)
+{
+ return sdhci_pltfm_unregister(pdev);
+}
+
+static struct platform_driver sdhci_dove_driver = {
+ .driver = {
+ .name = "sdhci-dove",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_dove_probe,
+ .remove = __devexit_p(sdhci_dove_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
+};
+
+static int __init sdhci_dove_init(void)
+{
+ return platform_driver_register(&sdhci_dove_driver);
+}
+module_init(sdhci_dove_init);
+
+static void __exit sdhci_dove_exit(void)
+{
+ platform_driver_unregister(&sdhci_dove_driver);
+}
+module_exit(sdhci_dove_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for Dove");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, "
+ "Mike Rapoport <mike@compulab.co.il>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a19967d..8da57d4 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -191,16 +191,6 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk) / 256 / 16;
}
-static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
-{
- struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
-
- if (boarddata && gpio_is_valid(boarddata->wp_gpio))
- return gpio_get_value(boarddata->wp_gpio);
- else
- return -ENOSYS;
-}
-
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
@@ -212,6 +202,23 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.get_min_clock = esdhc_pltfm_get_min_clock,
};
+static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
+ | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ /* ADMA has issues. Might be fixable */
+ .ops = &sdhci_esdhc_ops,
+};
+
+static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
+{
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+ return gpio_get_value(boarddata->wp_gpio);
+ else
+ return -ENOSYS;
+}
+
static irqreturn_t cd_irq(int irq, void *data)
{
struct sdhci_host *sdhost = (struct sdhci_host *)data;
@@ -220,30 +227,35 @@ static irqreturn_t cd_irq(int irq, void *data)
return IRQ_HANDLED;
};
-static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata)
+static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+ struct sdhci_pltfm_host *pltfm_host;
+ struct sdhci_host *host;
+ struct esdhc_platform_data *boarddata;
struct clk *clk;
int err;
struct pltfm_imx_data *imx_data;
+ host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ pltfm_host = sdhci_priv(host);
+
+ imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ if (!imx_data)
+ return -ENOMEM;
+ pltfm_host->priv = imx_data;
+
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
dev_err(mmc_dev(host->mmc), "clk err\n");
- return PTR_ERR(clk);
+ err = PTR_ERR(clk);
+ goto err_clk_get;
}
clk_enable(clk);
pltfm_host->clk = clk;
- imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
- if (!imx_data) {
- clk_disable(pltfm_host->clk);
- clk_put(pltfm_host->clk);
- return -ENOMEM;
- }
- pltfm_host->priv = imx_data;
-
if (!cpu_is_mx25())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
@@ -257,6 +269,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+ boarddata = host->mmc->parent->platform_data;
if (boarddata) {
err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
if (err) {
@@ -289,6 +302,10 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
+ err = sdhci_add_host(host);
+ if (err)
+ goto err_add_host;
+
return 0;
no_card_detect_irq:
@@ -297,14 +314,23 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
boarddata->cd_gpio = err;
not_supported:
kfree(imx_data);
- return 0;
+ err_add_host:
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+ err_clk_get:
+ sdhci_pltfm_free(pdev);
+ return err;
}
-static void esdhc_pltfm_exit(struct sdhci_host *host)
+static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
struct pltfm_imx_data *imx_data = pltfm_host->priv;
+ int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+
+ sdhci_remove_host(host, dead);
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
gpio_free(boarddata->wp_gpio);
@@ -319,13 +345,37 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
kfree(imx_data);
+
+ sdhci_pltfm_free(pdev);
+
+ return 0;
}
-struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
- | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
- /* ADMA has issues. Might be fixable */
- .ops = &sdhci_esdhc_ops,
- .init = esdhc_pltfm_init,
- .exit = esdhc_pltfm_exit,
+static struct platform_driver sdhci_esdhc_imx_driver = {
+ .driver = {
+ .name = "sdhci-esdhc-imx",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_esdhc_imx_probe,
+ .remove = __devexit_p(sdhci_esdhc_imx_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
};
+
+static int __init sdhci_esdhc_imx_init(void)
+{
+ return platform_driver_register(&sdhci_esdhc_imx_driver);
+}
+module_init(sdhci_esdhc_imx_init);
+
+static void __exit sdhci_esdhc_imx_exit(void)
+{
+ platform_driver_unregister(&sdhci_esdhc_imx_driver);
+}
+module_exit(sdhci_esdhc_imx_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index dbab040..8ccf256 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -22,48 +22,22 @@
* Inspired by sdhci-pci.c, by Pierre Ossman
*/
-#include <linux/delay.h>
-#include <linux/highmem.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-
-#include <linux/mmc/host.h>
-
-#include <linux/io.h>
-#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/err.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
-/*****************************************************************************\
- * *
- * SDHCI core callbacks *
- * *
-\*****************************************************************************/
-
static struct sdhci_ops sdhci_pltfm_ops = {
};
-/*****************************************************************************\
- * *
- * Device probing/removal *
- * *
-\*****************************************************************************/
-
-static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
+struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
+ struct sdhci_pltfm_data *pdata)
{
- const struct platform_device_id *platid = platform_get_device_id(pdev);
- struct sdhci_pltfm_data *pdata;
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
struct resource *iomem;
int ret;
- if (platid && platid->driver_data)
- pdata = (void *)platid->driver_data;
- else
- pdata = pdev->dev.platform_data;
-
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem) {
ret = -ENOMEM;
@@ -71,8 +45,7 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
}
if (resource_size(iomem) < 0x100)
- dev_err(&pdev->dev, "Invalid iomem size. You may "
- "experience problems.\n");
+ dev_err(&pdev->dev, "Invalid iomem size!\n");
/* Some PCI-based MFD need the parent here */
if (pdev->dev.parent != &platform_bus)
@@ -87,7 +60,7 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
- host->hw_name = "platform";
+ host->hw_name = dev_name(&pdev->dev);
if (pdata && pdata->ops)
host->ops = pdata->ops;
else
@@ -110,126 +83,70 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
goto err_remap;
}
- if (pdata && pdata->init) {
- ret = pdata->init(host, pdata);
- if (ret)
- goto err_plat_init;
- }
-
- ret = sdhci_add_host(host);
- if (ret)
- goto err_add_host;
-
platform_set_drvdata(pdev, host);
- return 0;
+ return host;
-err_add_host:
- if (pdata && pdata->exit)
- pdata->exit(host);
-err_plat_init:
- iounmap(host->ioaddr);
err_remap:
release_mem_region(iomem->start, resource_size(iomem));
err_request:
sdhci_free_host(host);
err:
- printk(KERN_ERR"Probing of sdhci-pltfm failed: %d\n", ret);
- return ret;
+ dev_err(&pdev->dev, "%s failed %d\n", __func__, ret);
+ return ERR_PTR(ret);
}
-static int __devexit sdhci_pltfm_remove(struct platform_device *pdev)
+void sdhci_pltfm_free(struct platform_device *pdev)
{
- struct sdhci_pltfm_data *pdata = pdev->dev.platform_data;
struct sdhci_host *host = platform_get_drvdata(pdev);
struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int dead;
- u32 scratch;
-
- dead = 0;
- scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
- if (scratch == (u32)-1)
- dead = 1;
- sdhci_remove_host(host, dead);
- if (pdata && pdata->exit)
- pdata->exit(host);
iounmap(host->ioaddr);
release_mem_region(iomem->start, resource_size(iomem));
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
+}
- return 0;
+int sdhci_pltfm_register(struct platform_device *pdev,
+ struct sdhci_pltfm_data *pdata)
+{
+ struct sdhci_host *host;
+ int ret = 0;
+
+ host = sdhci_pltfm_init(pdev, pdata);
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ sdhci_pltfm_free(pdev);
+
+ return ret;
}
-static const struct platform_device_id sdhci_pltfm_ids[] = {
- { "sdhci", },
-#ifdef CONFIG_MMC_SDHCI_CNS3XXX
- { "sdhci-cns3xxx", (kernel_ulong_t)&sdhci_cns3xxx_pdata },
-#endif
-#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
- { "sdhci-esdhc-imx", (kernel_ulong_t)&sdhci_esdhc_imx_pdata },
-#endif
-#ifdef CONFIG_MMC_SDHCI_DOVE
- { "sdhci-dove", (kernel_ulong_t)&sdhci_dove_pdata },
-#endif
-#ifdef CONFIG_MMC_SDHCI_TEGRA
- { "sdhci-tegra", (kernel_ulong_t)&sdhci_tegra_pdata },
-#endif
- { },
-};
-MODULE_DEVICE_TABLE(platform, sdhci_pltfm_ids);
+int sdhci_pltfm_unregister(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+
+ sdhci_remove_host(host, dead);
+ sdhci_pltfm_free(pdev);
+
+ return 0;
+}
#ifdef CONFIG_PM
-static int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state)
+int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state)
{
struct sdhci_host *host = platform_get_drvdata(dev);
return sdhci_suspend_host(host, state);
}
-static int sdhci_pltfm_resume(struct platform_device *dev)
+int sdhci_pltfm_resume(struct platform_device *dev)
{
struct sdhci_host *host = platform_get_drvdata(dev);
return sdhci_resume_host(host);
}
-#else
-#define sdhci_pltfm_suspend NULL
-#define sdhci_pltfm_resume NULL
#endif /* CONFIG_PM */
-
-static struct platform_driver sdhci_pltfm_driver = {
- .driver = {
- .name = "sdhci",
- .owner = THIS_MODULE,
- },
- .probe = sdhci_pltfm_probe,
- .remove = __devexit_p(sdhci_pltfm_remove),
- .id_table = sdhci_pltfm_ids,
- .suspend = sdhci_pltfm_suspend,
- .resume = sdhci_pltfm_resume,
-};
-
-/*****************************************************************************\
- * *
- * Driver init/exit *
- * *
-\*****************************************************************************/
-
-static int __init sdhci_drv_init(void)
-{
- return platform_driver_register(&sdhci_pltfm_driver);
-}
-
-static void __exit sdhci_drv_exit(void)
-{
- platform_driver_unregister(&sdhci_pltfm_driver);
-}
-
-module_init(sdhci_drv_init);
-module_exit(sdhci_drv_exit);
-
-MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
-MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 2b37016..ff4b7eb 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/types.h>
+#include <linux/platform_device.h>
#include <linux/mmc/sdhci-pltfm.h>
struct sdhci_pltfm_host {
@@ -20,9 +21,17 @@ struct sdhci_pltfm_host {
void *priv; /* to handle quirks across io-accessor calls */
};
-extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
-extern struct sdhci_pltfm_data sdhci_esdhc_imx_pdata;
-extern struct sdhci_pltfm_data sdhci_dove_pdata;
-extern struct sdhci_pltfm_data sdhci_tegra_pdata;
+extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
+ struct sdhci_pltfm_data *pdata);
+extern void sdhci_pltfm_free(struct platform_device *pdev);
+
+extern int sdhci_pltfm_register(struct platform_device *pdev,
+ struct sdhci_pltfm_data *pdata);
+extern int sdhci_pltfm_unregister(struct platform_device *pdev);
+
+#ifdef CONFIG_PM
+extern int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state);
+extern int sdhci_pltfm_resume(struct platform_device *dev);
+#endif
#endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 343c97e..95fce3d 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -116,20 +116,42 @@ static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
return 0;
}
+static struct sdhci_ops tegra_sdhci_ops = {
+ .get_ro = tegra_sdhci_get_ro,
+ .read_l = tegra_sdhci_readl,
+ .read_w = tegra_sdhci_readw,
+ .write_l = tegra_sdhci_writel,
+ .platform_8bit_width = tegra_sdhci_8bit,
+};
+
+static struct sdhci_pltfm_data sdhci_tegra_pdata = {
+ .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+ SDHCI_QUIRK_SINGLE_POWER_WRITE |
+ SDHCI_QUIRK_NO_HISPD_BIT |
+ SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+ .ops = &tegra_sdhci_ops,
+};
-static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
- struct sdhci_pltfm_data *pdata)
+static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+ struct sdhci_pltfm_host *pltfm_host;
struct tegra_sdhci_platform_data *plat;
+ struct sdhci_host *host;
struct clk *clk;
int rc;
+ host = sdhci_pltfm_init(pdev, &sdhci_tegra_pdata);
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ pltfm_host = sdhci_priv(host);
+
plat = pdev->dev.platform_data;
+
if (plat == NULL) {
dev_err(mmc_dev(host->mmc), "missing platform data\n");
- return -ENXIO;
+ rc = -ENXIO;
+ goto err_no_plat;
}
if (gpio_is_valid(plat->power_gpio)) {
@@ -137,7 +159,7 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (rc) {
dev_err(mmc_dev(host->mmc),
"failed to allocate power gpio\n");
- goto out;
+ goto err_power_req;
}
tegra_gpio_enable(plat->power_gpio);
gpio_direction_output(plat->power_gpio, 1);
@@ -148,7 +170,7 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (rc) {
dev_err(mmc_dev(host->mmc),
"failed to allocate cd gpio\n");
- goto out_power;
+ goto err_cd_req;
}
tegra_gpio_enable(plat->cd_gpio);
gpio_direction_input(plat->cd_gpio);
@@ -159,7 +181,7 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (rc) {
dev_err(mmc_dev(host->mmc), "request irq error\n");
- goto out_cd;
+ goto err_cd_irq_req;
}
}
@@ -169,7 +191,7 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (rc) {
dev_err(mmc_dev(host->mmc),
"failed to allocate wp gpio\n");
- goto out_irq;
+ goto err_wp_req;
}
tegra_gpio_enable(plat->wp_gpio);
gpio_direction_input(plat->wp_gpio);
@@ -179,7 +201,7 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (IS_ERR(clk)) {
dev_err(mmc_dev(host->mmc), "clk err\n");
rc = PTR_ERR(clk);
- goto out_wp;
+ goto err_clk_get;
}
clk_enable(clk);
pltfm_host->clk = clk;
@@ -189,38 +211,47 @@ static int tegra_sdhci_pltfm_init(struct sdhci_host *host,
if (plat->is_8bit)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ rc = sdhci_add_host(host);
+ if (rc)
+ goto err_add_host;
+
return 0;
-out_wp:
+err_add_host:
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+err_clk_get:
if (gpio_is_valid(plat->wp_gpio)) {
tegra_gpio_disable(plat->wp_gpio);
gpio_free(plat->wp_gpio);
}
-
-out_irq:
+err_wp_req:
if (gpio_is_valid(plat->cd_gpio))
free_irq(gpio_to_irq(plat->cd_gpio), host);
-out_cd:
+err_cd_irq_req:
if (gpio_is_valid(plat->cd_gpio)) {
tegra_gpio_disable(plat->cd_gpio);
gpio_free(plat->cd_gpio);
}
-
-out_power:
+err_cd_req:
if (gpio_is_valid(plat->power_gpio)) {
tegra_gpio_disable(plat->power_gpio);
gpio_free(plat->power_gpio);
}
-
-out:
+err_power_req:
+err_no_plat:
+ sdhci_pltfm_free(pdev);
return rc;
}
-static void tegra_sdhci_pltfm_exit(struct sdhci_host *host)
+static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
- struct tegra_sdhci_platform_data *plat;
+ struct tegra_sdhci_platform_data *plat;
+ int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+
+ sdhci_remove_host(host, dead);
plat = pdev->dev.platform_data;
@@ -242,22 +273,37 @@ static void tegra_sdhci_pltfm_exit(struct sdhci_host *host)
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
+
+ sdhci_pltfm_free(pdev);
+
+ return 0;
}
-static struct sdhci_ops tegra_sdhci_ops = {
- .get_ro = tegra_sdhci_get_ro,
- .read_l = tegra_sdhci_readl,
- .read_w = tegra_sdhci_readw,
- .write_l = tegra_sdhci_writel,
- .platform_8bit_width = tegra_sdhci_8bit,
+static struct platform_driver sdhci_tegra_driver = {
+ .driver = {
+ .name = "sdhci-tegra",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_tegra_probe,
+ .remove = __devexit_p(sdhci_tegra_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
};
-struct sdhci_pltfm_data sdhci_tegra_pdata = {
- .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
- SDHCI_QUIRK_SINGLE_POWER_WRITE |
- SDHCI_QUIRK_NO_HISPD_BIT |
- SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
- .ops = &tegra_sdhci_ops,
- .init = tegra_sdhci_pltfm_init,
- .exit = tegra_sdhci_pltfm_exit,
-};
+static int __init sdhci_tegra_init(void)
+{
+ return platform_driver_register(&sdhci_tegra_driver);
+}
+module_init(sdhci_tegra_init);
+
+static void __exit sdhci_tegra_exit(void)
+{
+ platform_driver_unregister(&sdhci_tegra_driver);
+}
+module_exit(sdhci_tegra_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for Tegra");
+MODULE_AUTHOR(" Google, Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mmc/sdhci-pltfm.h b/include/linux/mmc/sdhci-pltfm.h
index 548d59d..f1c2ac3 100644
--- a/include/linux/mmc/sdhci-pltfm.h
+++ b/include/linux/mmc/sdhci-pltfm.h
@@ -15,21 +15,15 @@
#define _SDHCI_PLTFM_H
struct sdhci_ops;
-struct sdhci_host;
/**
* struct sdhci_pltfm_data - SDHCI platform-specific information & hooks
* @ops: optional pointer to the platform-provided SDHCI ops
* @quirks: optional SDHCI quirks
- * @init: optional hook that is called during device probe, before the
- * driver tries to access any SDHCI registers
- * @exit: optional hook that is called during device removal
*/
struct sdhci_pltfm_data {
struct sdhci_ops *ops;
unsigned int quirks;
- int (*init)(struct sdhci_host *host, struct sdhci_pltfm_data *pdata);
- void (*exit)(struct sdhci_host *host);
};
#endif /* _SDHCI_PLTFM_H */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 1/7] mmc: sdhci: make sdhci-pltfm device drivers self registered
2011-05-05 13:22 ` [PATCH v2 1/7] mmc: sdhci: make sdhci-pltfm device drivers " Shawn Guo
@ 2011-05-05 14:24 ` Anton Vorontsov
0 siblings, 0 replies; 26+ messages in thread
From: Anton Vorontsov @ 2011-05-05 14:24 UTC (permalink / raw)
To: Shawn Guo
Cc: sameo, Arnd Bergmann, patches, devicetree-discuss, linux-mmc,
Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport, Olof Johansson,
Chris Ball, linuxppc-dev, Albert Herranz, linux-arm-kernel
On Thu, May 05, 2011 at 09:22:52PM +0800, Shawn Guo wrote:
[...]
> +static int __devinit sdhci_cns3xxx_probe(struct platform_device *pdev)
> +{
> + return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
> +}
> +
> +static int __devexit sdhci_cns3xxx_remove(struct platform_device *pdev)
> +{
> + return sdhci_pltfm_unregister(pdev);
> +}
> +
> +static struct platform_driver sdhci_cns3xxx_driver = {
> + .driver = {
> + .name = "sdhci-cns3xxx",
> + .owner = THIS_MODULE,
> + },
> + .probe = sdhci_cns3xxx_probe,
> + .remove = __devexit_p(sdhci_cns3xxx_remove),
> +#ifdef CONFIG_PM
> + .suspend = sdhci_pltfm_suspend,
> + .resume = sdhci_pltfm_resume,
> +#endif
> +};
> +
> +static int __init sdhci_cns3xxx_init(void)
> +{
> + return platform_driver_register(&sdhci_cns3xxx_driver);
> +}
> +module_init(sdhci_cns3xxx_init);
> +
> +static void __exit sdhci_cns3xxx_exit(void)
> +{
> + platform_driver_unregister(&sdhci_cns3xxx_driver);
> +}
> +module_exit(sdhci_cns3xxx_exit);
I don't think I like this duplicate code for each platform sub-
driver. It's repetitive and annoying. :-/
But considering that ARM will be multiplatform soon, we don't
want to have every mach-* stuff in the single sdhci-pltfm.
So... OK. If that compiles, I'm fine with it. :-D
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Thanks!
--
Anton Vorontsov
Email: cbouatmailru@gmail.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
2011-05-05 13:22 ` [PATCH v2 1/7] mmc: sdhci: make sdhci-pltfm device drivers " Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 14:23 ` Anton Vorontsov
2011-05-24 19:26 ` Wolfram Sang
2011-05-05 13:22 ` [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered Shawn Guo
` (5 subsequent siblings)
7 siblings, 2 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
The patch migrates the use of sdhci_of_host and sdhci_of_data to
sdhci_pltfm_host and sdhci_pltfm_data, so that the former pair can
be eliminated.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/mmc/host/sdhci-of-core.c | 30 +++++++++++++++---------------
drivers/mmc/host/sdhci-of-esdhc.c | 36 +++++++++++++++++++-----------------
drivers/mmc/host/sdhci-of-hlwd.c | 20 +++++++++++---------
drivers/mmc/host/sdhci-of.h | 15 +++------------
drivers/mmc/host/sdhci-pltfm.h | 4 ++++
5 files changed, 52 insertions(+), 53 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c
index f9b611f..6b2de9e 100644
--- a/drivers/mmc/host/sdhci-of-core.c
+++ b/drivers/mmc/host/sdhci-of-core.c
@@ -59,7 +59,7 @@ void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
{
- struct sdhci_of_host *of_host = sdhci_priv(host);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
int base = reg & ~0x3;
int shift = (reg & 0x2) * 8;
@@ -69,10 +69,10 @@ void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
- of_host->xfer_mode_shadow = val;
+ pltfm_host->xfer_mode_shadow = val;
return;
case SDHCI_COMMAND:
- sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow,
+ sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
SDHCI_TRANSFER_MODE);
return;
}
@@ -127,7 +127,7 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np)
static int __devinit sdhci_of_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
- struct sdhci_of_data *sdhci_of_data;
+ struct sdhci_pltfm_data *pdata;
struct sdhci_host *host;
struct sdhci_of_host *of_host;
const __be32 *clk;
@@ -136,16 +136,16 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev)
if (!ofdev->dev.of_match)
return -EINVAL;
- sdhci_of_data = ofdev->dev.of_match->data;
+ pdata = ofdev->dev.of_match->data;
if (!of_device_is_available(np))
return -ENODEV;
- host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+ host = sdhci_alloc_host(&ofdev->dev, sizeof(*pltfm_host));
if (IS_ERR(host))
return -ENOMEM;
- of_host = sdhci_priv(host);
+ pltfm_host = sdhci_priv(host);
dev_set_drvdata(&ofdev->dev, host);
host->ioaddr = of_iomap(np, 0);
@@ -161,9 +161,9 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev)
}
host->hw_name = dev_name(&ofdev->dev);
- if (sdhci_of_data) {
- host->quirks = sdhci_of_data->quirks;
- host->ops = &sdhci_of_data->ops;
+ if (pdata) {
+ host->quirks = pdata->quirks;
+ host->ops = &pdata->ops;
}
if (of_get_property(np, "sdhci,auto-cmd12", NULL))
@@ -178,7 +178,7 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev)
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
- of_host->clock = be32_to_cpup(clk);
+ pltfm_host->clock = be32_to_cpup(clk);
ret = sdhci_add_host(host);
if (ret)
@@ -208,12 +208,12 @@ static int __devexit sdhci_of_remove(struct platform_device *ofdev)
static const struct of_device_id sdhci_of_match[] = {
#ifdef CONFIG_MMC_SDHCI_OF_ESDHC
- { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
- { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
- { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc_pdata, },
+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc_pdata, },
+ { .compatible = "fsl,esdhc", .data = &sdhci_esdhc_pdata, },
#endif
#ifdef CONFIG_MMC_SDHCI_OF_HLWD
- { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, },
+ { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd_pdata, },
#endif
{ .compatible = "generic-sdhci", },
{},
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ba40d6d..492bcd7 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -60,32 +60,34 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
{
- struct sdhci_of_host *of_host = sdhci_priv(host);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- return of_host->clock;
+ return pltfm_host->clock;
}
static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
{
- struct sdhci_of_host *of_host = sdhci_priv(host);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- return of_host->clock / 256 / 16;
+ return pltfm_host->clock / 256 / 16;
}
-struct sdhci_of_data sdhci_esdhc = {
+static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_l = sdhci_be32bs_readl,
+ .read_w = esdhc_readw,
+ .read_b = sdhci_be32bs_readb,
+ .write_l = sdhci_be32bs_writel,
+ .write_w = esdhc_writew,
+ .write_b = esdhc_writeb,
+ .set_clock = esdhc_set_clock,
+ .enable_dma = esdhc_of_enable_dma,
+ .get_max_clock = esdhc_of_get_max_clock,
+ .get_min_clock = esdhc_of_get_min_clock,
+};
+
+struct sdhci_pltfm_data sdhci_esdhc_pdata = {
/* card detection could be handled via GPIO */
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
| SDHCI_QUIRK_NO_CARD_NO_RESET,
- .ops = {
- .read_l = sdhci_be32bs_readl,
- .read_w = esdhc_readw,
- .read_b = sdhci_be32bs_readb,
- .write_l = sdhci_be32bs_writel,
- .write_w = esdhc_writew,
- .write_b = esdhc_writeb,
- .set_clock = esdhc_set_clock,
- .enable_dma = esdhc_of_enable_dma,
- .get_max_clock = esdhc_of_get_max_clock,
- .get_min_clock = esdhc_of_get_min_clock,
- },
+ .ops = &sdhci_esdhc_ops,
};
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 68ddb75..380e896 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -51,15 +51,17 @@ static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg)
udelay(SDHCI_HLWD_WRITE_DELAY);
}
-struct sdhci_of_data sdhci_hlwd = {
+static struct sdhci_ops sdhci_hlwd_ops = {
+ .read_l = sdhci_be32bs_readl,
+ .read_w = sdhci_be32bs_readw,
+ .read_b = sdhci_be32bs_readb,
+ .write_l = sdhci_hlwd_writel,
+ .write_w = sdhci_hlwd_writew,
+ .write_b = sdhci_hlwd_writeb,
+};
+
+struct sdhci_pltfm_data sdhci_hlwd_pdata = {
.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_32BIT_DMA_SIZE,
- .ops = {
- .read_l = sdhci_be32bs_readl,
- .read_w = sdhci_be32bs_readw,
- .read_b = sdhci_be32bs_readb,
- .write_l = sdhci_hlwd_writel,
- .write_w = sdhci_hlwd_writew,
- .write_b = sdhci_hlwd_writeb,
- },
+ .ops = &sdhci_hlwd_ops,
};
diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h
index ad09ad9..5bdb5e7 100644
--- a/drivers/mmc/host/sdhci-of.h
+++ b/drivers/mmc/host/sdhci-of.h
@@ -18,16 +18,7 @@
#include <linux/types.h>
#include "sdhci.h"
-
-struct sdhci_of_data {
- unsigned int quirks;
- struct sdhci_ops ops;
-};
-
-struct sdhci_of_host {
- unsigned int clock;
- u16 xfer_mode_shadow;
-};
+#include "sdhci-pltfm.h"
extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg);
extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg);
@@ -36,7 +27,7 @@ extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg);
extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg);
extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg);
-extern struct sdhci_of_data sdhci_esdhc;
-extern struct sdhci_of_data sdhci_hlwd;
+extern struct sdhci_pltfm_data sdhci_esdhc_pdata;
+extern struct sdhci_pltfm_data sdhci_hlwd_pdata;
#endif /* __SDHCI_OF_H */
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index ff4b7eb..3cac450 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -19,6 +19,10 @@
struct sdhci_pltfm_host {
struct clk *clk;
void *priv; /* to handle quirks across io-accessor calls */
+
+ /* migrate from sdhci_of_host */
+ unsigned int clock;
+ u16 xfer_mode_shadow;
};
extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data
2011-05-05 13:22 ` [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data Shawn Guo
@ 2011-05-05 14:23 ` Anton Vorontsov
2011-05-24 19:26 ` Wolfram Sang
1 sibling, 0 replies; 26+ messages in thread
From: Anton Vorontsov @ 2011-05-05 14:23 UTC (permalink / raw)
To: Shawn Guo
Cc: sameo, Arnd Bergmann, patches, devicetree-discuss, linux-mmc,
Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport, Olof Johansson,
Chris Ball, linuxppc-dev, Albert Herranz, linux-arm-kernel
On Thu, May 05, 2011 at 09:22:53PM +0800, Shawn Guo wrote:
> The patch migrates the use of sdhci_of_host and sdhci_of_data to
> sdhci_pltfm_host and sdhci_pltfm_data, so that the former pair can
> be eliminated.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Thanks!
--
Anton Vorontsov
Email: cbouatmailru@gmail.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data
2011-05-05 13:22 ` [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data Shawn Guo
2011-05-05 14:23 ` Anton Vorontsov
@ 2011-05-24 19:26 ` Wolfram Sang
1 sibling, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2011-05-24 19:26 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Anton Vorontsov, linuxppc-dev, Albert Herranz,
linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 648 bytes --]
On Thu, May 05, 2011 at 09:22:53PM +0800, Shawn Guo wrote:
> The patch migrates the use of sdhci_of_host and sdhci_of_data to
> sdhci_pltfm_host and sdhci_pltfm_data, so that the former pair can
> be eliminated.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
We might be able to get rid of the migrated entries in sdhci-pltfm.h, but this
is a task for later IMO.
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
2011-05-05 13:22 ` [PATCH v2 1/7] mmc: sdhci: make sdhci-pltfm device drivers " Shawn Guo
2011-05-05 13:22 ` [PATCH v2 2/7] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 14:23 ` Anton Vorontsov
2011-05-24 19:32 ` Wolfram Sang
2011-05-05 13:22 ` [PATCH v2 4/7] sdhci: rename sdhci-esdhc-imx.c to sdhci-esdhc.c Shawn Guo
` (4 subsequent siblings)
7 siblings, 2 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
The patch turns the sdhci-of-core common stuff into helper functions
added into sdhci-pltfm.c, and makes sdhci-of device drviers self
registered using the same pair of .probe and .remove used by
sdhci-pltfm device drivers.
As a result, sdhci-of-core.c and sdhci-of.h can be eliminated with
those common things merged into sdhci-pltfm.c and sdhci-pltfm.h
respectively.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/mmc/host/Kconfig | 15 +--
drivers/mmc/host/Makefile | 7 +-
drivers/mmc/host/sdhci-of-core.c | 250 -------------------------------------
drivers/mmc/host/sdhci-of-esdhc.c | 53 ++++++++-
drivers/mmc/host/sdhci-of-hlwd.c | 50 +++++++-
drivers/mmc/host/sdhci-of.h | 33 -----
drivers/mmc/host/sdhci-pltfm.c | 104 +++++++++++++++-
drivers/mmc/host/sdhci-pltfm.h | 12 ++
8 files changed, 220 insertions(+), 304 deletions(-)
delete mode 100644 drivers/mmc/host/sdhci-of-core.c
delete mode 100644 drivers/mmc/host/sdhci-of.h
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 799e935..fdd20ad 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -81,19 +81,11 @@ config MMC_RICOH_MMC
If unsure, say Y.
-config MMC_SDHCI_OF
- tristate "SDHCI support on OpenFirmware platforms"
- depends on MMC_SDHCI && OF
- help
- This selects the OF support for Secure Digital Host Controller
- Interfaces.
-
- If unsure, say N.
-
config MMC_SDHCI_OF_ESDHC
bool "SDHCI OF support for the Freescale eSDHC controller"
- depends on MMC_SDHCI_OF
+ depends on MMC_SDHCI
depends on PPC_OF
+ select MMC_SDHCI_PLTFM
select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
help
This selects the Freescale eSDHC controller support.
@@ -102,8 +94,9 @@ config MMC_SDHCI_OF_ESDHC
config MMC_SDHCI_OF_HLWD
bool "SDHCI OF support for the Nintendo Wii SDHCI controllers"
- depends on MMC_SDHCI_OF
+ depends on MMC_SDHCI
depends on PPC_OF
+ select MMC_SDHCI_PLTFM
select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
help
This selects the Secure Digital Host Controller Interface (SDHCI)
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 95fddb8..01d38a1 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -48,11 +48,8 @@ obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
-
-obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
-sdhci-of-y := sdhci-of-core.o
-sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
-sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
+obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
ifeq ($(CONFIG_CB710_DEBUG),y)
CFLAGS-cb710-mmc += -DDEBUG
diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c
deleted file mode 100644
index 6b2de9e..0000000
--- a/drivers/mmc/host/sdhci-of-core.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * OpenFirmware bindings for Secure Digital Host Controller Interface.
- *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
- * Copyright (c) 2009 MontaVista Software, Inc.
- *
- * Authors: Xiaobo Xie <X.Xie@freescale.com>
- * Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * 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; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/mmc/host.h>
-#ifdef CONFIG_PPC
-#include <asm/machdep.h>
-#endif
-#include "sdhci-of.h"
-#include "sdhci.h"
-
-#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
-
-/*
- * These accessors are designed for big endian hosts doing I/O to
- * little endian controllers incorporating a 32-bit hardware byte swapper.
- */
-
-u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
-{
- return in_be32(host->ioaddr + reg);
-}
-
-u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
-{
- return in_be16(host->ioaddr + (reg ^ 0x2));
-}
-
-u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
-{
- return in_8(host->ioaddr + (reg ^ 0x3));
-}
-
-void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
-{
- out_be32(host->ioaddr + reg, val);
-}
-
-void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- int base = reg & ~0x3;
- int shift = (reg & 0x2) * 8;
-
- switch (reg) {
- case SDHCI_TRANSFER_MODE:
- /*
- * Postpone this write, we must do it together with a
- * command write that is down below.
- */
- pltfm_host->xfer_mode_shadow = val;
- return;
- case SDHCI_COMMAND:
- sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
- SDHCI_TRANSFER_MODE);
- return;
- }
- clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
-}
-
-void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
-{
- int base = reg & ~0x3;
- int shift = (reg & 0x3) * 8;
-
- clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
-}
-#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
-
-#ifdef CONFIG_PM
-
-static int sdhci_of_suspend(struct platform_device *ofdev, pm_message_t state)
-{
- struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
- return mmc_suspend_host(host->mmc);
-}
-
-static int sdhci_of_resume(struct platform_device *ofdev)
-{
- struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
- return mmc_resume_host(host->mmc);
-}
-
-#else
-
-#define sdhci_of_suspend NULL
-#define sdhci_of_resume NULL
-
-#endif
-
-static bool __devinit sdhci_of_wp_inverted(struct device_node *np)
-{
- if (of_get_property(np, "sdhci,wp-inverted", NULL))
- return true;
-
- /* Old device trees don't have the wp-inverted property. */
-#ifdef CONFIG_PPC
- return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
-#else
- return false;
-#endif
-}
-
-static int __devinit sdhci_of_probe(struct platform_device *ofdev)
-{
- struct device_node *np = ofdev->dev.of_node;
- struct sdhci_pltfm_data *pdata;
- struct sdhci_host *host;
- struct sdhci_of_host *of_host;
- const __be32 *clk;
- int size;
- int ret;
-
- if (!ofdev->dev.of_match)
- return -EINVAL;
- pdata = ofdev->dev.of_match->data;
-
- if (!of_device_is_available(np))
- return -ENODEV;
-
- host = sdhci_alloc_host(&ofdev->dev, sizeof(*pltfm_host));
- if (IS_ERR(host))
- return -ENOMEM;
-
- pltfm_host = sdhci_priv(host);
- dev_set_drvdata(&ofdev->dev, host);
-
- host->ioaddr = of_iomap(np, 0);
- if (!host->ioaddr) {
- ret = -ENOMEM;
- goto err_addr_map;
- }
-
- host->irq = irq_of_parse_and_map(np, 0);
- if (!host->irq) {
- ret = -EINVAL;
- goto err_no_irq;
- }
-
- host->hw_name = dev_name(&ofdev->dev);
- if (pdata) {
- host->quirks = pdata->quirks;
- host->ops = &pdata->ops;
- }
-
- if (of_get_property(np, "sdhci,auto-cmd12", NULL))
- host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
-
-
- if (of_get_property(np, "sdhci,1-bit-only", NULL))
- host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
-
- if (sdhci_of_wp_inverted(np))
- host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
-
- clk = of_get_property(np, "clock-frequency", &size);
- if (clk && size == sizeof(*clk) && *clk)
- pltfm_host->clock = be32_to_cpup(clk);
-
- ret = sdhci_add_host(host);
- if (ret)
- goto err_add_host;
-
- return 0;
-
-err_add_host:
- irq_dispose_mapping(host->irq);
-err_no_irq:
- iounmap(host->ioaddr);
-err_addr_map:
- sdhci_free_host(host);
- return ret;
-}
-
-static int __devexit sdhci_of_remove(struct platform_device *ofdev)
-{
- struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
- sdhci_remove_host(host, 0);
- sdhci_free_host(host);
- irq_dispose_mapping(host->irq);
- iounmap(host->ioaddr);
- return 0;
-}
-
-static const struct of_device_id sdhci_of_match[] = {
-#ifdef CONFIG_MMC_SDHCI_OF_ESDHC
- { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc_pdata, },
- { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc_pdata, },
- { .compatible = "fsl,esdhc", .data = &sdhci_esdhc_pdata, },
-#endif
-#ifdef CONFIG_MMC_SDHCI_OF_HLWD
- { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd_pdata, },
-#endif
- { .compatible = "generic-sdhci", },
- {},
-};
-MODULE_DEVICE_TABLE(of, sdhci_of_match);
-
-static struct platform_driver sdhci_of_driver = {
- .driver = {
- .name = "sdhci-of",
- .owner = THIS_MODULE,
- .of_match_table = sdhci_of_match,
- },
- .probe = sdhci_of_probe,
- .remove = __devexit_p(sdhci_of_remove),
- .suspend = sdhci_of_suspend,
- .resume = sdhci_of_resume,
-};
-
-static int __init sdhci_of_init(void)
-{
- return platform_driver_register(&sdhci_of_driver);
-}
-module_init(sdhci_of_init);
-
-static void __exit sdhci_of_exit(void)
-{
- platform_driver_unregister(&sdhci_of_driver);
-}
-module_exit(sdhci_of_exit);
-
-MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
-MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
- "Anton Vorontsov <avorontsov@ru.mvista.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 492bcd7..2db6a45 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -16,7 +16,7 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/mmc/host.h>
-#include "sdhci-of.h"
+#include "sdhci-pltfm.h"
#include "sdhci.h"
#include "sdhci-esdhc.h"
@@ -85,9 +85,58 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.get_min_clock = esdhc_of_get_min_clock,
};
-struct sdhci_pltfm_data sdhci_esdhc_pdata = {
+static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
/* card detection could be handled via GPIO */
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
| SDHCI_QUIRK_NO_CARD_NO_RESET,
.ops = &sdhci_esdhc_ops,
};
+
+static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
+{
+ return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
+}
+
+static int __devexit sdhci_esdhc_remove(struct platform_device *pdev)
+{
+ return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_esdhc_of_match[] = {
+ { .compatible = "fsl,mpc8379-esdhc" },
+ { .compatible = "fsl,mpc8536-esdhc" },
+ { .compatible = "fsl,esdhc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
+
+static struct platform_driver sdhci_esdhc_driver = {
+ .driver = {
+ .name = "sdhci-esdhc",
+ .owner = THIS_MODULE,
+ .of_match_table = sdhci_esdhc_of_match,
+ },
+ .probe = sdhci_esdhc_probe,
+ .remove = __devexit_p(sdhci_esdhc_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
+};
+
+static int __init sdhci_esdhc_init(void)
+{
+ return platform_driver_register(&sdhci_esdhc_driver);
+}
+module_init(sdhci_esdhc_init);
+
+static void __exit sdhci_esdhc_exit(void)
+{
+ platform_driver_unregister(&sdhci_esdhc_driver);
+}
+module_exit(sdhci_esdhc_exit);
+
+MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 380e896..faedfce 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -21,7 +21,7 @@
#include <linux/delay.h>
#include <linux/mmc/host.h>
-#include "sdhci-of.h"
+#include "sdhci-pltfm.h"
#include "sdhci.h"
/*
@@ -60,8 +60,54 @@ static struct sdhci_ops sdhci_hlwd_ops = {
.write_b = sdhci_hlwd_writeb,
};
-struct sdhci_pltfm_data sdhci_hlwd_pdata = {
+static struct sdhci_pltfm_data sdhci_hlwd_pdata = {
.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_32BIT_DMA_SIZE,
.ops = &sdhci_hlwd_ops,
};
+
+static int __devinit sdhci_hlwd_probe(struct platform_device *pdev)
+{
+ return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
+}
+
+static int __devexit sdhci_hlwd_remove(struct platform_device *pdev)
+{
+ return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_hlwd_of_match[] = {
+ { .compatible = "nintendo,hollywood-sdhci" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_hlwd_of_match);
+
+static struct platform_driver sdhci_hlwd_driver = {
+ .driver = {
+ .name = "sdhci-hlwd",
+ .owner = THIS_MODULE,
+ .of_match_table = sdhci_hlwd_of_match,
+ },
+ .probe = sdhci_hlwd_probe,
+ .remove = __devexit_p(sdhci_hlwd_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
+};
+
+static int __init sdhci_hlwd_init(void)
+{
+ return platform_driver_register(&sdhci_hlwd_driver);
+}
+module_init(sdhci_hlwd_init);
+
+static void __exit sdhci_hlwd_exit(void)
+{
+ platform_driver_unregister(&sdhci_hlwd_driver);
+}
+module_exit(sdhci_hlwd_exit);
+
+MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver");
+MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h
deleted file mode 100644
index 5bdb5e7..0000000
--- a/drivers/mmc/host/sdhci-of.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * OpenFirmware bindings for Secure Digital Host Controller Interface.
- *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
- * Copyright (c) 2009 MontaVista Software, Inc.
- *
- * Authors: Xiaobo Xie <X.Xie@freescale.com>
- * Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * 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; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef __SDHCI_OF_H
-#define __SDHCI_OF_H
-
-#include <linux/types.h>
-#include "sdhci.h"
-#include "sdhci-pltfm.h"
-
-extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg);
-extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg);
-extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg);
-extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg);
-extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg);
-extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg);
-
-extern struct sdhci_pltfm_data sdhci_esdhc_pdata;
-extern struct sdhci_pltfm_data sdhci_hlwd_pdata;
-
-#endif /* __SDHCI_OF_H */
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 8ccf256..4b22db2 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -23,13 +23,113 @@
*/
#include <linux/err.h>
-
+#include <linux/of.h>
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif
#include "sdhci.h"
#include "sdhci-pltfm.h"
static struct sdhci_ops sdhci_pltfm_ops = {
};
+#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+/*
+ * These accessors are designed for big endian hosts doing I/O to
+ * little endian controllers incorporating a 32-bit hardware byte swapper.
+ */
+u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
+{
+ return in_be32(host->ioaddr + reg);
+}
+
+u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
+{
+ return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
+{
+ return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ out_be32(host->ioaddr + reg, val);
+}
+
+void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ int base = reg & ~0x3;
+ int shift = (reg & 0x2) * 8;
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ pltfm_host->xfer_mode_shadow = val;
+ return;
+ case SDHCI_COMMAND:
+ sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
+ SDHCI_TRANSFER_MODE);
+ return;
+ }
+ clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ int base = reg & ~0x3;
+ int shift = (reg & 0x3) * 8;
+
+ clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
+
+#ifdef CONFIG_OF
+static bool sdhci_of_wp_inverted(struct device_node *np)
+{
+ if (of_get_property(np, "sdhci,wp-inverted", NULL))
+ return true;
+
+ /* Old device trees don't have the wp-inverted property. */
+#ifdef CONFIG_PPC
+ return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
+#else
+ return false;
+#endif
+}
+
+void sdhci_get_of_property(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ const __be32 *clk;
+ int size;
+
+ if (of_device_is_available(np)) {
+ if (of_get_property(np, "sdhci,auto-cmd12", NULL))
+ host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
+
+ if (of_get_property(np, "sdhci,1-bit-only", NULL))
+ host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
+
+ if (sdhci_of_wp_inverted(np))
+ host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+
+ clk = of_get_property(np, "clock-frequency", &size);
+ if (clk && size == sizeof(*clk) && *clk)
+ pltfm_host->clock = be32_to_cpup(clk);
+ }
+}
+#else
+void sdhci_get_of_property(struct platform_device *pdev) {}
+#endif
+
struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
struct sdhci_pltfm_data *pdata)
{
@@ -117,6 +217,8 @@ int sdhci_pltfm_register(struct platform_device *pdev,
if (IS_ERR(host))
return PTR_ERR(host);
+ sdhci_get_of_property(pdev);
+
ret = sdhci_add_host(host);
if (ret)
sdhci_pltfm_free(pdev);
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 3cac450..fe27b83 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/mmc/sdhci.h>
struct sdhci_pltfm_host {
struct clk *clk;
@@ -25,6 +26,17 @@ struct sdhci_pltfm_host {
u16 xfer_mode_shadow;
};
+#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg);
+extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg);
+extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg);
+extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg);
+extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg);
+extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+extern void sdhci_get_of_property(struct platform_device *pdev);
+
extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
struct sdhci_pltfm_data *pdata);
extern void sdhci_pltfm_free(struct platform_device *pdev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered
2011-05-05 13:22 ` [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered Shawn Guo
@ 2011-05-05 14:23 ` Anton Vorontsov
2011-05-06 2:15 ` Shawn Guo
2011-05-24 19:32 ` Wolfram Sang
1 sibling, 1 reply; 26+ messages in thread
From: Anton Vorontsov @ 2011-05-05 14:23 UTC (permalink / raw)
To: Shawn Guo
Cc: sameo, Arnd Bergmann, patches, devicetree-discuss, linux-mmc,
Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport, Olof Johansson,
Chris Ball, linuxppc-dev, Albert Herranz, linux-arm-kernel
On Thu, May 05, 2011 at 09:22:54PM +0800, Shawn Guo wrote:
[...]
> - * Copyright (c) 2007 Freescale Semiconductor, Inc.
> - * Copyright (c) 2009 MontaVista Software, Inc.
> - *
> - * Authors: Xiaobo Xie <X.Xie@freescale.com>
> - * Anton Vorontsov <avorontsov@ru.mvista.com>
[...]
> -#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> -
> -/*
> - * These accessors are designed for big endian hosts doing I/O to
> - * little endian controllers incorporating a 32-bit hardware byte swapper.
> - */
> -
> -u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
> -{
> - return in_be32(host->ioaddr + reg);
> -}
> -
> -u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
> -{
> - return in_be16(host->ioaddr + (reg ^ 0x2));
> -}
> -
> -u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
> -{
> - return in_8(host->ioaddr + (reg ^ 0x3));
> -}
> -
> -void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
> -{
> - out_be32(host->ioaddr + reg, val);
> -}
> -
> -void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
> -{
> - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> - int base = reg & ~0x3;
> - int shift = (reg & 0x2) * 8;
> -
> - switch (reg) {
> - case SDHCI_TRANSFER_MODE:
> - /*
> - * Postpone this write, we must do it together with a
> - * command write that is down below.
> - */
> - pltfm_host->xfer_mode_shadow = val;
> - return;
> - case SDHCI_COMMAND:
> - sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
> - SDHCI_TRANSFER_MODE);
> - return;
> - }
> - clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
> -}
> -
> -void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
> -{
> - int base = reg & ~0x3;
> - int shift = (reg & 0x3) * 8;
> -
> - clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
> -}
> -#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
[...]
> +#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> +/*
> + * These accessors are designed for big endian hosts doing I/O to
> + * little endian controllers incorporating a 32-bit hardware byte swapper.
> + */
> +u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
> +{
> + return in_be32(host->ioaddr + reg);
> +}
> +
> +u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
> +{
> + return in_be16(host->ioaddr + (reg ^ 0x2));
> +}
> +
> +u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
> +{
> + return in_8(host->ioaddr + (reg ^ 0x3));
> +}
> +
> +void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
> +{
> + out_be32(host->ioaddr + reg, val);
> +}
> +
> +void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
> +{
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + int base = reg & ~0x3;
> + int shift = (reg & 0x2) * 8;
> +
> + switch (reg) {
> + case SDHCI_TRANSFER_MODE:
> + /*
> + * Postpone this write, we must do it together with a
> + * command write that is down below.
> + */
> + pltfm_host->xfer_mode_shadow = val;
> + return;
> + case SDHCI_COMMAND:
> + sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
> + SDHCI_TRANSFER_MODE);
> + return;
> + }
> + clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
> +}
> +
> +void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
> +{
> + int base = reg & ~0x3;
> + int shift = (reg & 0x3) * 8;
> +
> + clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
> +}
> +#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
I noticed you're very careful wrt copyright/authorship notices,
except for this case. How about retaining copyright stuff when
you merge these two files?
The patch itself looks great though.
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered
2011-05-05 14:23 ` Anton Vorontsov
@ 2011-05-06 2:15 ` Shawn Guo
0 siblings, 0 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-06 2:15 UTC (permalink / raw)
To: Anton Vorontsov
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Shawn Guo, linuxppc-dev, Albert Herranz,
linux-arm-kernel
On Thu, May 05, 2011 at 06:23:44PM +0400, Anton Vorontsov wrote:
> On Thu, May 05, 2011 at 09:22:54PM +0800, Shawn Guo wrote:
> [...]
> > - * Copyright (c) 2007 Freescale Semiconductor, Inc.
> > - * Copyright (c) 2009 MontaVista Software, Inc.
> > - *
> > - * Authors: Xiaobo Xie <X.Xie@freescale.com>
> > - * Anton Vorontsov <avorontsov@ru.mvista.com>
> [...]
> > -#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> > -
> > -/*
> > - * These accessors are designed for big endian hosts doing I/O to
> > - * little endian controllers incorporating a 32-bit hardware byte swapper.
> > - */
> > -
> > -u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
> > -{
> > - return in_be32(host->ioaddr + reg);
> > -}
> > -
> > -u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
> > -{
> > - return in_be16(host->ioaddr + (reg ^ 0x2));
> > -}
> > -
> > -u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
> > -{
> > - return in_8(host->ioaddr + (reg ^ 0x3));
> > -}
> > -
> > -void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
> > -{
> > - out_be32(host->ioaddr + reg, val);
> > -}
> > -
> > -void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
> > -{
> > - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > - int base = reg & ~0x3;
> > - int shift = (reg & 0x2) * 8;
> > -
> > - switch (reg) {
> > - case SDHCI_TRANSFER_MODE:
> > - /*
> > - * Postpone this write, we must do it together with a
> > - * command write that is down below.
> > - */
> > - pltfm_host->xfer_mode_shadow = val;
> > - return;
> > - case SDHCI_COMMAND:
> > - sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
> > - SDHCI_TRANSFER_MODE);
> > - return;
> > - }
> > - clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
> > -}
> > -
> > -void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
> > -{
> > - int base = reg & ~0x3;
> > - int shift = (reg & 0x3) * 8;
> > -
> > - clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
> > -}
> > -#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
> [...]
> > +#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
> > +/*
> > + * These accessors are designed for big endian hosts doing I/O to
> > + * little endian controllers incorporating a 32-bit hardware byte swapper.
> > + */
> > +u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
> > +{
> > + return in_be32(host->ioaddr + reg);
> > +}
> > +
> > +u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
> > +{
> > + return in_be16(host->ioaddr + (reg ^ 0x2));
> > +}
> > +
> > +u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
> > +{
> > + return in_8(host->ioaddr + (reg ^ 0x3));
> > +}
> > +
> > +void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
> > +{
> > + out_be32(host->ioaddr + reg, val);
> > +}
> > +
> > +void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
> > +{
> > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > + int base = reg & ~0x3;
> > + int shift = (reg & 0x2) * 8;
> > +
> > + switch (reg) {
> > + case SDHCI_TRANSFER_MODE:
> > + /*
> > + * Postpone this write, we must do it together with a
> > + * command write that is down below.
> > + */
> > + pltfm_host->xfer_mode_shadow = val;
> > + return;
> > + case SDHCI_COMMAND:
> > + sdhci_be32bs_writel(host, val << 16 | pltfm_host->xfer_mode_shadow,
> > + SDHCI_TRANSFER_MODE);
> > + return;
> > + }
> > + clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
> > +}
> > +
> > +void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
> > +{
> > + int base = reg & ~0x3;
> > + int shift = (reg & 0x3) * 8;
> > +
> > + clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
> > +}
> > +#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
>
> I noticed you're very careful wrt copyright/authorship notices,
> except for this case. How about retaining copyright stuff when
> you merge these two files?
>
Obviously, need to be more careful. Will add. Thanks.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered
2011-05-05 13:22 ` [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered Shawn Guo
2011-05-05 14:23 ` Anton Vorontsov
@ 2011-05-24 19:32 ` Wolfram Sang
1 sibling, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2011-05-24 19:32 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Anton Vorontsov, linuxppc-dev, Albert Herranz,
linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 2140 bytes --]
On Thu, May 05, 2011 at 09:22:54PM +0800, Shawn Guo wrote:
> The patch turns the sdhci-of-core common stuff into helper functions
> added into sdhci-pltfm.c, and makes sdhci-of device drviers self
> registered using the same pair of .probe and .remove used by
> sdhci-pltfm device drivers.
>
> As a result, sdhci-of-core.c and sdhci-of.h can be eliminated with
> those common things merged into sdhci-pltfm.c and sdhci-pltfm.h
> respectively.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
After taking care of Anton's comment and fixing this minor thingie...
> +#ifdef CONFIG_OF
> +static bool sdhci_of_wp_inverted(struct device_node *np)
> +{
> + if (of_get_property(np, "sdhci,wp-inverted", NULL))
> + return true;
> +
> + /* Old device trees don't have the wp-inverted property. */
> +#ifdef CONFIG_PPC
> + return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
> +#else
> + return false;
> +#endif
/* CONFIG_PPC */ after #endif
> +}
> +
> +void sdhci_get_of_property(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + const __be32 *clk;
> + int size;
> +
> + if (of_device_is_available(np)) {
> + if (of_get_property(np, "sdhci,auto-cmd12", NULL))
> + host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
> +
> + if (of_get_property(np, "sdhci,1-bit-only", NULL))
> + host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
> +
> + if (sdhci_of_wp_inverted(np))
> + host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
> +
> + clk = of_get_property(np, "clock-frequency", &size);
> + if (clk && size == sizeof(*clk) && *clk)
> + pltfm_host->clock = be32_to_cpup(clk);
> + }
> +}
> +#else
> +void sdhci_get_of_property(struct platform_device *pdev) {}
> +#endif
/* CONFIG_OF */
you can add
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 4/7] sdhci: rename sdhci-esdhc-imx.c to sdhci-esdhc.c
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
` (2 preceding siblings ...)
2011-05-05 13:22 ` [PATCH v2 3/7] mmc: sdhci: make sdhci-of device drivers self registered Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 13:22 ` [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx Shawn Guo
` (3 subsequent siblings)
7 siblings, 0 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
The patch renames the file to prepare for the consolidation
sdhci-of-esdhc and sdhci-esdhc-imx.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/mmc/host/Makefile | 2 +-
drivers/mmc/host/sdhci-esdhc-imx.c | 381 ------------------------------------
drivers/mmc/host/sdhci-esdhc.c | 381 ++++++++++++++++++++++++++++++++++++
3 files changed, 382 insertions(+), 382 deletions(-)
delete mode 100644 drivers/mmc/host/sdhci-esdhc-imx.c
create mode 100644 drivers/mmc/host/sdhci-esdhc.c
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 01d38a1..186f0ed 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -45,7 +45,7 @@ obj-$(CONFIG_MMC_USHC) += ushc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
-obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
+obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc.o
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
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
deleted file mode 100644
index 8da57d4..0000000
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Freescale eSDHC i.MX controller driver for the platform bus.
- *
- * derived from the OF-version.
- *
- * Copyright (c) 2010 Pengutronix e.K.
- * Author: Wolfram Sang <w.sang@pengutronix.de>
- *
- * 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; either version 2 of the License.
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdhci-pltfm.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/sdio.h>
-#include <mach/hardware.h>
-#include <mach/esdhc.h>
-#include "sdhci.h"
-#include "sdhci-pltfm.h"
-#include "sdhci-esdhc.h"
-
-/* VENDOR SPEC register */
-#define SDHCI_VENDOR_SPEC 0xC0
-#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
-
-#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
-/*
- * The CMDTYPE of the CMD register (offset 0xE) should be set to
- * "11" when the STOP CMD12 is issued on imx53 to abort one
- * open ended multi-blk IO. Otherwise the TC INT wouldn't
- * be generated.
- * In exact block transfer, the controller doesn't complete the
- * operations automatically as required at the end of the
- * transfer and remains on hold if the abort command is not sent.
- * As a result, the TC flag is not asserted and SW received timeout
- * exeception. Bit1 of Vendor Spec registor is used to fix it.
- */
-#define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)
-
-struct pltfm_imx_data {
- int flags;
- u32 scratchpad;
-};
-
-static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
-{
- void __iomem *base = host->ioaddr + (reg & ~0x3);
- u32 shift = (reg & 0x3) * 8;
-
- writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
-}
-
-static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct pltfm_imx_data *imx_data = pltfm_host->priv;
-
- /* fake CARD_PRESENT flag on mx25/35 */
- u32 val = readl(host->ioaddr + reg);
-
- if (unlikely((reg == SDHCI_PRESENT_STATE)
- && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
- struct esdhc_platform_data *boarddata =
- host->mmc->parent->platform_data;
-
- if (boarddata && gpio_is_valid(boarddata->cd_gpio)
- && gpio_get_value(boarddata->cd_gpio))
- /* no card, if a valid gpio says so... */
- val &= SDHCI_CARD_PRESENT;
- else
- /* ... in all other cases assume card is present */
- val |= SDHCI_CARD_PRESENT;
- }
-
- return val;
-}
-
-static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct pltfm_imx_data *imx_data = pltfm_host->priv;
-
- if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
- && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
- /*
- * these interrupts won't work with a custom card_detect gpio
- * (only applied to mx25/35)
- */
- val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
-
- if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
- && (reg == SDHCI_INT_STATUS)
- && (val & SDHCI_INT_DATA_END))) {
- u32 v;
- v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
- v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
- writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
- }
-
- writel(val, host->ioaddr + reg);
-}
-
-static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
-{
- if (unlikely(reg == SDHCI_HOST_VERSION))
- reg ^= 2;
-
- return readw(host->ioaddr + reg);
-}
-
-static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct pltfm_imx_data *imx_data = pltfm_host->priv;
-
- switch (reg) {
- case SDHCI_TRANSFER_MODE:
- /*
- * Postpone this write, we must do it together with a
- * command write that is down below.
- */
- if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
- && (host->cmd->opcode == SD_IO_RW_EXTENDED)
- && (host->cmd->data->blocks > 1)
- && (host->cmd->data->flags & MMC_DATA_READ)) {
- u32 v;
- v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
- v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
- writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
- }
- imx_data->scratchpad = val;
- return;
- case SDHCI_COMMAND:
- if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
- && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
- val |= SDHCI_CMD_ABORTCMD;
- writel(val << 16 | imx_data->scratchpad,
- host->ioaddr + SDHCI_TRANSFER_MODE);
- return;
- case SDHCI_BLOCK_SIZE:
- val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
- break;
- }
- esdhc_clrset_le(host, 0xffff, val, reg);
-}
-
-static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
-{
- u32 new_val;
-
- switch (reg) {
- case SDHCI_POWER_CONTROL:
- /*
- * FSL put some DMA bits here
- * If your board has a regulator, code should be here
- */
- return;
- case SDHCI_HOST_CONTROL:
- /* FSL messed up here, so we can just keep those two */
- new_val = val & (SDHCI_CTRL_LED | SDHCI_CTRL_4BITBUS);
- /* ensure the endianess */
- new_val |= ESDHC_HOST_CONTROL_LE;
- /* DMA mode bits are shifted */
- new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
-
- esdhc_clrset_le(host, 0xffff, new_val, reg);
- return;
- }
- esdhc_clrset_le(host, 0xff, val, reg);
-}
-
-static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-
- return clk_get_rate(pltfm_host->clk);
-}
-
-static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-
- return clk_get_rate(pltfm_host->clk) / 256 / 16;
-}
-
-static struct sdhci_ops sdhci_esdhc_ops = {
- .read_l = esdhc_readl_le,
- .read_w = esdhc_readw_le,
- .write_l = esdhc_writel_le,
- .write_w = esdhc_writew_le,
- .write_b = esdhc_writeb_le,
- .set_clock = esdhc_set_clock,
- .get_max_clock = esdhc_pltfm_get_max_clock,
- .get_min_clock = esdhc_pltfm_get_min_clock,
-};
-
-static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
- | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
- /* ADMA has issues. Might be fixable */
- .ops = &sdhci_esdhc_ops,
-};
-
-static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
-{
- struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
-
- if (boarddata && gpio_is_valid(boarddata->wp_gpio))
- return gpio_get_value(boarddata->wp_gpio);
- else
- return -ENOSYS;
-}
-
-static irqreturn_t cd_irq(int irq, void *data)
-{
- struct sdhci_host *sdhost = (struct sdhci_host *)data;
-
- tasklet_schedule(&sdhost->card_tasklet);
- return IRQ_HANDLED;
-};
-
-static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
-{
- struct sdhci_pltfm_host *pltfm_host;
- struct sdhci_host *host;
- struct esdhc_platform_data *boarddata;
- struct clk *clk;
- int err;
- struct pltfm_imx_data *imx_data;
-
- host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
- if (IS_ERR(host))
- return PTR_ERR(host);
-
- pltfm_host = sdhci_priv(host);
-
- imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
- if (!imx_data)
- return -ENOMEM;
- pltfm_host->priv = imx_data;
-
- clk = clk_get(mmc_dev(host->mmc), NULL);
- if (IS_ERR(clk)) {
- dev_err(mmc_dev(host->mmc), "clk err\n");
- err = PTR_ERR(clk);
- goto err_clk_get;
- }
- clk_enable(clk);
- pltfm_host->clk = clk;
-
- if (!cpu_is_mx25())
- host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
-
- if (cpu_is_mx25() || cpu_is_mx35()) {
- /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
- host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
- /* write_protect can't be routed to controller, use gpio */
- sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
- }
-
- if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
- imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
-
- boarddata = host->mmc->parent->platform_data;
- if (boarddata) {
- err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
- if (err) {
- dev_warn(mmc_dev(host->mmc),
- "no write-protect pin available!\n");
- boarddata->wp_gpio = err;
- }
-
- err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
- if (err) {
- dev_warn(mmc_dev(host->mmc),
- "no card-detect pin available!\n");
- goto no_card_detect_pin;
- }
-
- /* i.MX5x has issues to be researched */
- if (!cpu_is_mx25() && !cpu_is_mx35())
- goto not_supported;
-
- err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- mmc_hostname(host->mmc), host);
- if (err) {
- dev_warn(mmc_dev(host->mmc), "request irq error\n");
- goto no_card_detect_irq;
- }
-
- imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
- /* Now we have a working card_detect again */
- host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
- }
-
- err = sdhci_add_host(host);
- if (err)
- goto err_add_host;
-
- return 0;
-
- no_card_detect_irq:
- gpio_free(boarddata->cd_gpio);
- no_card_detect_pin:
- boarddata->cd_gpio = err;
- not_supported:
- kfree(imx_data);
- err_add_host:
- clk_disable(pltfm_host->clk);
- clk_put(pltfm_host->clk);
- err_clk_get:
- sdhci_pltfm_free(pdev);
- return err;
-}
-
-static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
-{
- struct sdhci_host *host = platform_get_drvdata(pdev);
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
- struct pltfm_imx_data *imx_data = pltfm_host->priv;
- int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
-
- sdhci_remove_host(host, dead);
-
- if (boarddata && gpio_is_valid(boarddata->wp_gpio))
- gpio_free(boarddata->wp_gpio);
-
- if (boarddata && gpio_is_valid(boarddata->cd_gpio)) {
- gpio_free(boarddata->cd_gpio);
-
- if (!(host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION))
- free_irq(gpio_to_irq(boarddata->cd_gpio), host);
- }
-
- clk_disable(pltfm_host->clk);
- clk_put(pltfm_host->clk);
- kfree(imx_data);
-
- sdhci_pltfm_free(pdev);
-
- return 0;
-}
-
-static struct platform_driver sdhci_esdhc_imx_driver = {
- .driver = {
- .name = "sdhci-esdhc-imx",
- .owner = THIS_MODULE,
- },
- .probe = sdhci_esdhc_imx_probe,
- .remove = __devexit_p(sdhci_esdhc_imx_remove),
-#ifdef CONFIG_PM
- .suspend = sdhci_pltfm_suspend,
- .resume = sdhci_pltfm_resume,
-#endif
-};
-
-static int __init sdhci_esdhc_imx_init(void)
-{
- return platform_driver_register(&sdhci_esdhc_imx_driver);
-}
-module_init(sdhci_esdhc_imx_init);
-
-static void __exit sdhci_esdhc_imx_exit(void)
-{
- platform_driver_unregister(&sdhci_esdhc_imx_driver);
-}
-module_exit(sdhci_esdhc_imx_exit);
-
-MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
-MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-esdhc.c b/drivers/mmc/host/sdhci-esdhc.c
new file mode 100644
index 0000000..8da57d4
--- /dev/null
+++ b/drivers/mmc/host/sdhci-esdhc.c
@@ -0,0 +1,381 @@
+/*
+ * Freescale eSDHC i.MX controller driver for the platform bus.
+ *
+ * derived from the OF-version.
+ *
+ * Copyright (c) 2010 Pengutronix e.K.
+ * Author: Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * 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; either version 2 of the License.
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <mach/hardware.h>
+#include <mach/esdhc.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+#include "sdhci-esdhc.h"
+
+/* VENDOR SPEC register */
+#define SDHCI_VENDOR_SPEC 0xC0
+#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+
+#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
+/*
+ * The CMDTYPE of the CMD register (offset 0xE) should be set to
+ * "11" when the STOP CMD12 is issued on imx53 to abort one
+ * open ended multi-blk IO. Otherwise the TC INT wouldn't
+ * be generated.
+ * In exact block transfer, the controller doesn't complete the
+ * operations automatically as required at the end of the
+ * transfer and remains on hold if the abort command is not sent.
+ * As a result, the TC flag is not asserted and SW received timeout
+ * exeception. Bit1 of Vendor Spec registor is used to fix it.
+ */
+#define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)
+
+struct pltfm_imx_data {
+ int flags;
+ u32 scratchpad;
+};
+
+static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
+{
+ void __iomem *base = host->ioaddr + (reg & ~0x3);
+ u32 shift = (reg & 0x3) * 8;
+
+ writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
+}
+
+static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ /* fake CARD_PRESENT flag on mx25/35 */
+ u32 val = readl(host->ioaddr + reg);
+
+ if (unlikely((reg == SDHCI_PRESENT_STATE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
+ struct esdhc_platform_data *boarddata =
+ host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->cd_gpio)
+ && gpio_get_value(boarddata->cd_gpio))
+ /* no card, if a valid gpio says so... */
+ val &= SDHCI_CARD_PRESENT;
+ else
+ /* ... in all other cases assume card is present */
+ val |= SDHCI_CARD_PRESENT;
+ }
+
+ return val;
+}
+
+static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
+ /*
+ * these interrupts won't work with a custom card_detect gpio
+ * (only applied to mx25/35)
+ */
+ val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+
+ if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (reg == SDHCI_INT_STATUS)
+ && (val & SDHCI_INT_DATA_END))) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+
+ writel(val, host->ioaddr + reg);
+}
+
+static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
+{
+ if (unlikely(reg == SDHCI_HOST_VERSION))
+ reg ^= 2;
+
+ return readw(host->ioaddr + reg);
+}
+
+static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (host->cmd->opcode == SD_IO_RW_EXTENDED)
+ && (host->cmd->data->blocks > 1)
+ && (host->cmd->data->flags & MMC_DATA_READ)) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+ imx_data->scratchpad = val;
+ return;
+ case SDHCI_COMMAND:
+ if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
+ && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+ val |= SDHCI_CMD_ABORTCMD;
+ writel(val << 16 | imx_data->scratchpad,
+ host->ioaddr + SDHCI_TRANSFER_MODE);
+ return;
+ case SDHCI_BLOCK_SIZE:
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ break;
+ }
+ esdhc_clrset_le(host, 0xffff, val, reg);
+}
+
+static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
+{
+ u32 new_val;
+
+ switch (reg) {
+ case SDHCI_POWER_CONTROL:
+ /*
+ * FSL put some DMA bits here
+ * If your board has a regulator, code should be here
+ */
+ return;
+ case SDHCI_HOST_CONTROL:
+ /* FSL messed up here, so we can just keep those two */
+ new_val = val & (SDHCI_CTRL_LED | SDHCI_CTRL_4BITBUS);
+ /* ensure the endianess */
+ new_val |= ESDHC_HOST_CONTROL_LE;
+ /* DMA mode bits are shifted */
+ new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
+
+ esdhc_clrset_le(host, 0xffff, new_val, reg);
+ return;
+ }
+ esdhc_clrset_le(host, 0xff, val, reg);
+}
+
+static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return clk_get_rate(pltfm_host->clk);
+}
+
+static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return clk_get_rate(pltfm_host->clk) / 256 / 16;
+}
+
+static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_l = esdhc_readl_le,
+ .read_w = esdhc_readw_le,
+ .write_l = esdhc_writel_le,
+ .write_w = esdhc_writew_le,
+ .write_b = esdhc_writeb_le,
+ .set_clock = esdhc_set_clock,
+ .get_max_clock = esdhc_pltfm_get_max_clock,
+ .get_min_clock = esdhc_pltfm_get_min_clock,
+};
+
+static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
+ | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ /* ADMA has issues. Might be fixable */
+ .ops = &sdhci_esdhc_ops,
+};
+
+static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
+{
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+ return gpio_get_value(boarddata->wp_gpio);
+ else
+ return -ENOSYS;
+}
+
+static irqreturn_t cd_irq(int irq, void *data)
+{
+ struct sdhci_host *sdhost = (struct sdhci_host *)data;
+
+ tasklet_schedule(&sdhost->card_tasklet);
+ return IRQ_HANDLED;
+};
+
+static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
+{
+ struct sdhci_pltfm_host *pltfm_host;
+ struct sdhci_host *host;
+ struct esdhc_platform_data *boarddata;
+ struct clk *clk;
+ int err;
+ struct pltfm_imx_data *imx_data;
+
+ host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ pltfm_host = sdhci_priv(host);
+
+ imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ if (!imx_data)
+ return -ENOMEM;
+ pltfm_host->priv = imx_data;
+
+ clk = clk_get(mmc_dev(host->mmc), NULL);
+ if (IS_ERR(clk)) {
+ dev_err(mmc_dev(host->mmc), "clk err\n");
+ err = PTR_ERR(clk);
+ goto err_clk_get;
+ }
+ clk_enable(clk);
+ pltfm_host->clk = clk;
+
+ if (!cpu_is_mx25())
+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+ if (cpu_is_mx25() || cpu_is_mx35()) {
+ /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
+ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+ /* write_protect can't be routed to controller, use gpio */
+ sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
+ }
+
+ if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
+ imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+
+ boarddata = host->mmc->parent->platform_data;
+ if (boarddata) {
+ err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
+ if (err) {
+ dev_warn(mmc_dev(host->mmc),
+ "no write-protect pin available!\n");
+ boarddata->wp_gpio = err;
+ }
+
+ err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
+ if (err) {
+ dev_warn(mmc_dev(host->mmc),
+ "no card-detect pin available!\n");
+ goto no_card_detect_pin;
+ }
+
+ /* i.MX5x has issues to be researched */
+ if (!cpu_is_mx25() && !cpu_is_mx35())
+ goto not_supported;
+
+ err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ mmc_hostname(host->mmc), host);
+ if (err) {
+ dev_warn(mmc_dev(host->mmc), "request irq error\n");
+ goto no_card_detect_irq;
+ }
+
+ imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
+ /* Now we have a working card_detect again */
+ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+ }
+
+ err = sdhci_add_host(host);
+ if (err)
+ goto err_add_host;
+
+ return 0;
+
+ no_card_detect_irq:
+ gpio_free(boarddata->cd_gpio);
+ no_card_detect_pin:
+ boarddata->cd_gpio = err;
+ not_supported:
+ kfree(imx_data);
+ err_add_host:
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+ err_clk_get:
+ sdhci_pltfm_free(pdev);
+ return err;
+}
+
+static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+ int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+
+ sdhci_remove_host(host, dead);
+
+ if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+ gpio_free(boarddata->wp_gpio);
+
+ if (boarddata && gpio_is_valid(boarddata->cd_gpio)) {
+ gpio_free(boarddata->cd_gpio);
+
+ if (!(host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION))
+ free_irq(gpio_to_irq(boarddata->cd_gpio), host);
+ }
+
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+ kfree(imx_data);
+
+ sdhci_pltfm_free(pdev);
+
+ return 0;
+}
+
+static struct platform_driver sdhci_esdhc_imx_driver = {
+ .driver = {
+ .name = "sdhci-esdhc-imx",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_esdhc_imx_probe,
+ .remove = __devexit_p(sdhci_esdhc_imx_remove),
+#ifdef CONFIG_PM
+ .suspend = sdhci_pltfm_suspend,
+ .resume = sdhci_pltfm_resume,
+#endif
+};
+
+static int __init sdhci_esdhc_imx_init(void)
+{
+ return platform_driver_register(&sdhci_esdhc_imx_driver);
+}
+module_init(sdhci_esdhc_imx_init);
+
+static void __exit sdhci_esdhc_imx_exit(void)
+{
+ platform_driver_unregister(&sdhci_esdhc_imx_driver);
+}
+module_exit(sdhci_esdhc_imx_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
` (3 preceding siblings ...)
2011-05-05 13:22 ` [PATCH v2 4/7] sdhci: rename sdhci-esdhc-imx.c to sdhci-esdhc.c Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 14:20 ` Anton Vorontsov
` (2 more replies)
2011-05-05 13:22 ` [PATCH v2 6/7] mmc: sdhci: merge two sdhci-pltfm.h into one Shawn Guo
` (2 subsequent siblings)
7 siblings, 3 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
This patch is to consolidate SDHCI driver for Freescale eSDHC
controller found on both MPCxxx and i.MX platforms. It merges
sdhci-of-esdhc.c into sdhci-esdhc.c, so that the same pair of
.probe/.remove hook works with eSDHC for two platforms.
As the results, sdhci-of-esdhc.c and sdhci-esdhc.h are removed, and
header esdhc.h containing the definition of esdhc_platform_data is
put into the public folder.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/mmc/host/Kconfig | 38 ++++---
drivers/mmc/host/Makefile | 3 +-
drivers/mmc/host/sdhci-esdhc.c | 244 +++++++++++++++++++++++++++++++++----
drivers/mmc/host/sdhci-esdhc.h | 81 ------------
drivers/mmc/host/sdhci-of-esdhc.c | 142 ---------------------
include/linux/mmc/esdhc.h | 27 ++++
6 files changed, 273 insertions(+), 262 deletions(-)
delete mode 100644 drivers/mmc/host/sdhci-esdhc.h
delete mode 100644 drivers/mmc/host/sdhci-of-esdhc.c
create mode 100644 include/linux/mmc/esdhc.h
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index fdd20ad..e32cb76 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -81,17 +81,6 @@ config MMC_RICOH_MMC
If unsure, say Y.
-config MMC_SDHCI_OF_ESDHC
- bool "SDHCI OF support for the Freescale eSDHC controller"
- depends on MMC_SDHCI
- depends on PPC_OF
- select MMC_SDHCI_PLTFM
- select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
- help
- This selects the Freescale eSDHC controller support.
-
- If unsure, say N.
-
config MMC_SDHCI_OF_HLWD
bool "SDHCI OF support for the Nintendo Wii SDHCI controllers"
depends on MMC_SDHCI
@@ -122,15 +111,34 @@ config MMC_SDHCI_CNS3XXX
If unsure, say N.
+config MMC_SDHCI_ESDHC
+ bool
+ depends on MMC_SDHCI
+ select MMC_SDHCI_PLTFM
+ help
+ This selects SDHCI driver for Freescale eSDHC controller.
+
+config MMC_SDHCI_ESDHC_MPC
+ bool "SDHCI support for the Freescale eSDHC MPC controller"
+ depends on MMC_SDHCI
+ depends on PPC_OF && PPC_CLOCK
+ select MMC_SDHCI_ESDHC
+ select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+ help
+ This selects the Freescale eSDHC controller support on the
+ MPC platforms.
+
+ If unsure, say N.
+
config MMC_SDHCI_ESDHC_IMX
- tristate "SDHCI platform support for the Freescale eSDHC i.MX controller"
+ tristate "SDHCI support for the Freescale eSDHC i.MX controller"
depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX5
depends on MMC_SDHCI
- select MMC_SDHCI_PLTFM
+ select MMC_SDHCI_ESDHC
select MMC_SDHCI_IO_ACCESSORS
help
- This selects the Freescale eSDHC controller support on the platform
- bus, found on platforms like mx35/51.
+ This selects the Freescale eSDHC controller support on platforms
+ like mx25/mx35/mx5x.
If unsure, say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 186f0ed..a3f1df8 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -45,10 +45,9 @@ obj-$(CONFIG_MMC_USHC) += ushc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
-obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc.o
+obj-$(CONFIG_MMC_SDHCI_ESDHC) += sdhci-esdhc.o
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
ifeq ($(CONFIG_CB710_DEBUG),y)
diff --git a/drivers/mmc/host/sdhci-esdhc.c b/drivers/mmc/host/sdhci-esdhc.c
index 8da57d4..f3b4ff5 100644
--- a/drivers/mmc/host/sdhci-esdhc.c
+++ b/drivers/mmc/host/sdhci-esdhc.c
@@ -1,7 +1,11 @@
/*
- * Freescale eSDHC i.MX controller driver for the platform bus.
+ * Freescale eSDHC i.MX controller driver for MPCxxx and i.MX.
*
- * derived from the OF-version.
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Author: Xiaobo Xie <X.Xie@freescale.com>
+ *
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
*
* Copyright (c) 2010 Pengutronix e.K.
* Author: Wolfram Sang <w.sang@pengutronix.de>
@@ -21,11 +25,40 @@
#include <linux/mmc/sdhci-pltfm.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
+#include <linux/mmc/esdhc.h>
+#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
#include <mach/hardware.h>
-#include <mach/esdhc.h>
+#endif
#include "sdhci.h"
#include "sdhci-pltfm.h"
-#include "sdhci-esdhc.h"
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
+ SDHCI_QUIRK_NO_BUSY_IRQ | \
+ SDHCI_QUIRK_NONSTANDARD_CLOCK | \
+ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
+ SDHCI_QUIRK_PIO_NEEDS_DELAY | \
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+/* OF-specific */
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_DMA_SNOOP 0x00000040
+
+#define ESDHC_HOST_CONTROL_RES 0x05
+
+/* pltfm-specific */
+#define ESDHC_HOST_CONTROL_LE 0x20
/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC 0xC0
@@ -50,6 +83,117 @@ struct pltfm_imx_data {
u32 scratchpad;
};
+static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int pre_div = 2;
+ int div = 1;
+ u32 temp;
+
+ temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+ temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
+ | ESDHC_CLOCK_MASK);
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+
+ if (clock == 0)
+ goto out;
+
+ while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
+ pre_div *= 2;
+
+ while (host->max_clk / pre_div / div > clock && div < 16)
+ div++;
+
+ dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
+ clock, host->max_clk / pre_div / div);
+
+ pre_div >>= 1;
+ div--;
+
+ temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+ temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
+ | (div << ESDHC_DIVIDER_SHIFT)
+ | (pre_div << ESDHC_PREDIV_SHIFT));
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+ mdelay(100);
+out:
+ host->clock = clock;
+}
+
+#ifdef CONFIG_MMC_SDHCI_ESDHC_MPC
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+ u16 ret;
+
+ if (unlikely(reg == SDHCI_HOST_VERSION))
+ ret = in_be16(host->ioaddr + reg);
+ else
+ ret = sdhci_be32bs_readw(host, reg);
+ return ret;
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ if (reg == SDHCI_BLOCK_SIZE) {
+ /*
+ * Two last DMA bits are reserved, and first one is used for
+ * non-standard blksz of 4096 bytes that we don't support
+ * yet. So clear the DMA boundary bits.
+ */
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ }
+ sdhci_be32bs_writew(host, val, reg);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
+ if (reg == SDHCI_HOST_CONTROL)
+ val &= ~ESDHC_HOST_CONTROL_RES;
+ sdhci_be32bs_writeb(host, val, reg);
+}
+
+static int esdhc_of_enable_dma(struct sdhci_host *host)
+{
+ setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+ return 0;
+}
+
+static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return pltfm_host->clock;
+}
+
+static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return pltfm_host->clock / 256 / 16;
+}
+
+static struct sdhci_ops sdhci_esdhc_mpc_ops = {
+ .read_l = sdhci_be32bs_readl,
+ .read_w = esdhc_readw,
+ .read_b = sdhci_be32bs_readb,
+ .write_l = sdhci_be32bs_writel,
+ .write_w = esdhc_writew,
+ .write_b = esdhc_writeb,
+ .set_clock = esdhc_set_clock,
+ .enable_dma = esdhc_of_enable_dma,
+ .get_max_clock = esdhc_of_get_max_clock,
+ .get_min_clock = esdhc_of_get_min_clock,
+};
+
+static struct sdhci_pltfm_data sdhci_esdhc_mpc_pdata = {
+ /* card detection could be handled via GPIO */
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
+ | SDHCI_QUIRK_NO_CARD_NO_RESET,
+ .ops = &sdhci_esdhc_mpc_ops,
+};
+#endif /* CONFIG_MMC_SDHCI_ESDHC_MPC */
+
+#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
{
void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -191,7 +335,7 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk) / 256 / 16;
}
-static struct sdhci_ops sdhci_esdhc_ops = {
+static struct sdhci_ops sdhci_esdhc_imx_ops = {
.read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
.write_l = esdhc_writel_le,
@@ -206,8 +350,35 @@ static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
| SDHCI_QUIRK_BROKEN_CARD_DETECTION,
/* ADMA has issues. Might be fixable */
- .ops = &sdhci_esdhc_ops,
+ .ops = &sdhci_esdhc_imx_ops,
+};
+#endif /* CONFIG_MMC_SDHCI_ESDHC_IMX */
+
+#ifdef CONFIG_OF
+#include <linux/of_device.h>
+static const struct of_device_id sdhci_esdhc_dt_ids[] = {
+#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
+ { .compatible = "fsl,imx-esdhc", .data = &sdhci_esdhc_imx_pdata },
+#endif
+#ifdef CONFIG_MMC_SDHCI_ESDHC_MPC
+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc_mpc_pdata },
+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc_mpc_pdata },
+ { .compatible = "fsl,esdhc", .data = &sdhci_esdhc_mpc_pdata },
+#endif
+ { }
};
+MODULE_DEVICE_TABLE(platform, sdhci_esdhc_dt_ids);
+#else
+#define sdhci_esdhc_dt_ids NULL
+#endif
+
+static const struct platform_device_id sdhci_esdhc_pltfm_ids[] = {
+#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
+ { "sdhci-esdhc-imx", (kernel_ulong_t)&sdhci_esdhc_imx_pdata },
+#endif
+ { }
+};
+MODULE_DEVICE_TABLE(platform, sdhci_esdhc_pltfm_ids);
static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
{
@@ -227,8 +398,20 @@ static irqreturn_t cd_irq(int irq, void *data)
return IRQ_HANDLED;
};
-static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
+#ifndef CONFIG_MMC_SDHCI_ESDHC_IMX
+#define cpu_is_mx25() (0)
+#define cpu_is_mx35() (0)
+#define cpu_is_mx51() (0)
+#define cpu_is_imx() (0)
+#else
+#define cpu_is_imx() (1)
+#endif
+
+static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
{
+ const struct platform_device_id *platid = platform_get_device_id(pdev);
+ const struct of_device_id *dtid = pdev->dev.of_match;
+ struct sdhci_pltfm_data *pdata;
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_host *host;
struct esdhc_platform_data *boarddata;
@@ -236,12 +419,24 @@ static int __devinit 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);
+ if (platid && platid->driver_data)
+ pdata = (void *)platid->driver_data;
+ else if (dtid && dtid->data)
+ pdata = dtid->data;
+ else
+ pdata = pdev->dev.platform_data;
+
+ host = sdhci_pltfm_init(pdev, pdata);
if (IS_ERR(host))
return PTR_ERR(host);
+ sdhci_get_of_property(pdev);
+
pltfm_host = sdhci_priv(host);
+ if (!cpu_is_imx())
+ goto add_host;
+
imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
if (!imx_data)
return -ENOMEM;
@@ -263,7 +458,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
/* write_protect can't be routed to controller, use gpio */
- sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
+ pdata->ops->get_ro = esdhc_pltfm_get_ro;
}
if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
@@ -302,6 +497,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
+ add_host:
err = sdhci_add_host(host);
if (err)
goto err_add_host;
@@ -322,7 +518,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
return err;
}
-static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
+static int __devexit sdhci_esdhc_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -351,31 +547,35 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_driver sdhci_esdhc_imx_driver = {
+static struct platform_driver sdhci_esdhc_driver = {
.driver = {
- .name = "sdhci-esdhc-imx",
+ .name = "sdhci-esdhc",
.owner = THIS_MODULE,
+ .of_match_table = sdhci_esdhc_dt_ids,
},
- .probe = sdhci_esdhc_imx_probe,
- .remove = __devexit_p(sdhci_esdhc_imx_remove),
+ .probe = sdhci_esdhc_probe,
+ .remove = __devexit_p(sdhci_esdhc_remove),
+ .id_table = sdhci_esdhc_pltfm_ids,
#ifdef CONFIG_PM
.suspend = sdhci_pltfm_suspend,
.resume = sdhci_pltfm_resume,
#endif
};
-static int __init sdhci_esdhc_imx_init(void)
+static int __init sdhci_esdhc_init(void)
{
- return platform_driver_register(&sdhci_esdhc_imx_driver);
+ return platform_driver_register(&sdhci_esdhc_driver);
}
-module_init(sdhci_esdhc_imx_init);
+module_init(sdhci_esdhc_init);
-static void __exit sdhci_esdhc_imx_exit(void)
+static void __exit sdhci_esdhc_exit(void)
{
- platform_driver_unregister(&sdhci_esdhc_imx_driver);
+ platform_driver_unregister(&sdhci_esdhc_driver);
}
-module_exit(sdhci_esdhc_imx_exit);
+module_exit(sdhci_esdhc_exit);
-MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
-MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("SDHCI driver for Freescale eSDHC");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>, "
+ "Wolfram Sang <w.sang@pengutronix.de>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
deleted file mode 100644
index c3b08f1..0000000
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Freescale eSDHC controller driver generics for OF and pltfm.
- *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
- * Copyright (c) 2009 MontaVista Software, Inc.
- * Copyright (c) 2010 Pengutronix e.K.
- * Author: Wolfram Sang <w.sang@pengutronix.de>
- *
- * 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; either version 2 of the License.
- */
-
-#ifndef _DRIVERS_MMC_SDHCI_ESDHC_H
-#define _DRIVERS_MMC_SDHCI_ESDHC_H
-
-/*
- * Ops and quirks for the Freescale eSDHC controller.
- */
-
-#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
- SDHCI_QUIRK_NO_BUSY_IRQ | \
- SDHCI_QUIRK_NONSTANDARD_CLOCK | \
- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
- SDHCI_QUIRK_PIO_NEEDS_DELAY | \
- SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
-
-#define ESDHC_SYSTEM_CONTROL 0x2c
-#define ESDHC_CLOCK_MASK 0x0000fff0
-#define ESDHC_PREDIV_SHIFT 8
-#define ESDHC_DIVIDER_SHIFT 4
-#define ESDHC_CLOCK_PEREN 0x00000004
-#define ESDHC_CLOCK_HCKEN 0x00000002
-#define ESDHC_CLOCK_IPGEN 0x00000001
-
-/* pltfm-specific */
-#define ESDHC_HOST_CONTROL_LE 0x20
-
-/* OF-specific */
-#define ESDHC_DMA_SYSCTL 0x40c
-#define ESDHC_DMA_SNOOP 0x00000040
-
-#define ESDHC_HOST_CONTROL_RES 0x05
-
-static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
-{
- int pre_div = 2;
- int div = 1;
- u32 temp;
-
- temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
- temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
- | ESDHC_CLOCK_MASK);
- sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
-
- if (clock == 0)
- goto out;
-
- while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
- pre_div *= 2;
-
- while (host->max_clk / pre_div / div > clock && div < 16)
- div++;
-
- dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
- clock, host->max_clk / pre_div / div);
-
- pre_div >>= 1;
- div--;
-
- temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
- temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
- | (div << ESDHC_DIVIDER_SHIFT)
- | (pre_div << ESDHC_PREDIV_SHIFT));
- sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
- mdelay(100);
-out:
- host->clock = clock;
-}
-
-#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
deleted file mode 100644
index 2db6a45..0000000
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Freescale eSDHC controller driver.
- *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
- * Copyright (c) 2009 MontaVista Software, Inc.
- *
- * Authors: Xiaobo Xie <X.Xie@freescale.com>
- * Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * 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; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/mmc/host.h>
-#include "sdhci-pltfm.h"
-#include "sdhci.h"
-#include "sdhci-esdhc.h"
-
-static u16 esdhc_readw(struct sdhci_host *host, int reg)
-{
- u16 ret;
-
- if (unlikely(reg == SDHCI_HOST_VERSION))
- ret = in_be16(host->ioaddr + reg);
- else
- ret = sdhci_be32bs_readw(host, reg);
- return ret;
-}
-
-static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
-{
- if (reg == SDHCI_BLOCK_SIZE) {
- /*
- * Two last DMA bits are reserved, and first one is used for
- * non-standard blksz of 4096 bytes that we don't support
- * yet. So clear the DMA boundary bits.
- */
- val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
- }
- sdhci_be32bs_writew(host, val, reg);
-}
-
-static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
-{
- /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
- if (reg == SDHCI_HOST_CONTROL)
- val &= ~ESDHC_HOST_CONTROL_RES;
- sdhci_be32bs_writeb(host, val, reg);
-}
-
-static int esdhc_of_enable_dma(struct sdhci_host *host)
-{
- setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
- return 0;
-}
-
-static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-
- return pltfm_host->clock;
-}
-
-static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
-{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-
- return pltfm_host->clock / 256 / 16;
-}
-
-static struct sdhci_ops sdhci_esdhc_ops = {
- .read_l = sdhci_be32bs_readl,
- .read_w = esdhc_readw,
- .read_b = sdhci_be32bs_readb,
- .write_l = sdhci_be32bs_writel,
- .write_w = esdhc_writew,
- .write_b = esdhc_writeb,
- .set_clock = esdhc_set_clock,
- .enable_dma = esdhc_of_enable_dma,
- .get_max_clock = esdhc_of_get_max_clock,
- .get_min_clock = esdhc_of_get_min_clock,
-};
-
-static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
- /* card detection could be handled via GPIO */
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
- | SDHCI_QUIRK_NO_CARD_NO_RESET,
- .ops = &sdhci_esdhc_ops,
-};
-
-static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
-{
- return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
-}
-
-static int __devexit sdhci_esdhc_remove(struct platform_device *pdev)
-{
- return sdhci_pltfm_unregister(pdev);
-}
-
-static const struct of_device_id sdhci_esdhc_of_match[] = {
- { .compatible = "fsl,mpc8379-esdhc" },
- { .compatible = "fsl,mpc8536-esdhc" },
- { .compatible = "fsl,esdhc" },
- { }
-};
-MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
-
-static struct platform_driver sdhci_esdhc_driver = {
- .driver = {
- .name = "sdhci-esdhc",
- .owner = THIS_MODULE,
- .of_match_table = sdhci_esdhc_of_match,
- },
- .probe = sdhci_esdhc_probe,
- .remove = __devexit_p(sdhci_esdhc_remove),
-#ifdef CONFIG_PM
- .suspend = sdhci_pltfm_suspend,
- .resume = sdhci_pltfm_resume,
-#endif
-};
-
-static int __init sdhci_esdhc_init(void)
-{
- return platform_driver_register(&sdhci_esdhc_driver);
-}
-module_init(sdhci_esdhc_init);
-
-static void __exit sdhci_esdhc_exit(void)
-{
- platform_driver_unregister(&sdhci_esdhc_driver);
-}
-module_exit(sdhci_esdhc_exit);
-
-MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC");
-MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
- "Anton Vorontsov <avorontsov@ru.mvista.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mmc/esdhc.h b/include/linux/mmc/esdhc.h
new file mode 100644
index 0000000..e0f6598
--- /dev/null
+++ b/include/linux/mmc/esdhc.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * 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
+ * of the License.
+ */
+
+#ifndef __LINUX_MMC_ESDHC_H
+#define __LINUX_MMC_ESDHC_H
+
+/**
+ * struct esdhc_platform_data - optional platform data for esdhc
+ *
+ * strongly recommended for i.MX25/35, not needed for other variants
+ *
+ * @wp_gpio: gpio for write_protect (-EINVAL if unused)
+ * @cd_gpio: gpio for card_detect interrupt (-EINVAL if unused)
+ */
+
+struct esdhc_platform_data {
+ unsigned int wp_gpio;
+ unsigned int cd_gpio;
+};
+
+#endif /* __LINUX_MMC_ESDHC_H */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-05 13:22 ` [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx Shawn Guo
@ 2011-05-05 14:20 ` Anton Vorontsov
2011-05-19 9:48 ` Wolfram Sang
2011-05-24 19:40 ` Wolfram Sang
2 siblings, 0 replies; 26+ messages in thread
From: Anton Vorontsov @ 2011-05-05 14:20 UTC (permalink / raw)
To: Shawn Guo
Cc: sameo, Arnd Bergmann, patches, devicetree-discuss, linux-mmc,
Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport, Olof Johansson,
Chris Ball, linuxppc-dev, Albert Herranz, linux-arm-kernel
On Thu, May 05, 2011 at 09:22:56PM +0800, Shawn Guo wrote:
> This patch is to consolidate SDHCI driver for Freescale eSDHC
> controller found on both MPCxxx and i.MX platforms. It merges
> sdhci-of-esdhc.c into sdhci-esdhc.c, so that the same pair of
> .probe/.remove hook works with eSDHC for two platforms.
>
> As the results, sdhci-of-esdhc.c and sdhci-esdhc.h are removed, and
> header esdhc.h containing the definition of esdhc_platform_data is
> put into the public folder.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
I'm not sure if that makes sense to merge these two.
I'd rather vote for renaming sdhci-of-esdhc to sdhci-esdhc-mpc. :-)
--
Anton Vorontsov
Email: cbouatmailru@gmail.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-05 13:22 ` [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx Shawn Guo
2011-05-05 14:20 ` Anton Vorontsov
@ 2011-05-19 9:48 ` Wolfram Sang
2011-05-24 19:40 ` Wolfram Sang
2 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2011-05-19 9:48 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Anton Vorontsov, linuxppc-dev, Albert Herranz,
linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 949 bytes --]
> +config MMC_SDHCI_ESDHC
> + bool
> + depends on MMC_SDHCI
> + select MMC_SDHCI_PLTFM
> + help
> + This selects SDHCI driver for Freescale eSDHC controller.
bool is not a good choice here, because if ESDHC_IMX is selected as a
module (-m), it will get converted here to built-in (-y). Same goes for
MMC_SDHCI_PLTFM. If I change both into tristate and then compile, I get
a build error:
ERROR: "sdhci_pltfm_suspend" [drivers/mmc/host/sdhci-esdhc.ko] undefined!
ERROR: "sdhci_get_of_property" [drivers/mmc/host/sdhci-esdhc.ko] undefined!
ERROR: "sdhci_pltfm_init" [drivers/mmc/host/sdhci-esdhc.ko] undefined!
ERROR: "sdhci_pltfm_free" [drivers/mmc/host/sdhci-esdhc.ko] undefined!
So, the module-support seems to be missing for the library.
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-05 13:22 ` [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx Shawn Guo
2011-05-05 14:20 ` Anton Vorontsov
2011-05-19 9:48 ` Wolfram Sang
@ 2011-05-24 19:40 ` Wolfram Sang
2011-05-25 6:06 ` Shawn Guo
2 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2011-05-24 19:40 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Anton Vorontsov, linuxppc-dev, Albert Herranz,
linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 1008 bytes --]
On Thu, May 05, 2011 at 09:22:56PM +0800, Shawn Guo wrote:
> This patch is to consolidate SDHCI driver for Freescale eSDHC
> controller found on both MPCxxx and i.MX platforms. It merges
> sdhci-of-esdhc.c into sdhci-esdhc.c, so that the same pair of
> .probe/.remove hook works with eSDHC for two platforms.
>
> As the results, sdhci-of-esdhc.c and sdhci-esdhc.h are removed, and
> header esdhc.h containing the definition of esdhc_platform_data is
> put into the public folder.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
I agree with Anton about not merging the two...
> +#ifndef CONFIG_MMC_SDHCI_ESDHC_IMX
> +#define cpu_is_mx25() (0)
> +#define cpu_is_mx35() (0)
> +#define cpu_is_mx51() (0)
> +#define cpu_is_imx() (0)
> +#else
> +#define cpu_is_imx() (1)
> +#endif
... e.g. that looks a bit frightening.
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-24 19:40 ` Wolfram Sang
@ 2011-05-25 6:06 ` Shawn Guo
2011-05-25 6:46 ` Uwe Kleine-König
0 siblings, 1 reply; 26+ messages in thread
From: Shawn Guo @ 2011-05-25 6:06 UTC (permalink / raw)
To: Wolfram Sang
Cc: Chris Ball, Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Shawn Guo, linuxppc-dev,
Albert Herranz, linux-arm-kernel
On Tue, May 24, 2011 at 09:40:54PM +0200, Wolfram Sang wrote:
> On Thu, May 05, 2011 at 09:22:56PM +0800, Shawn Guo wrote:
> > This patch is to consolidate SDHCI driver for Freescale eSDHC
> > controller found on both MPCxxx and i.MX platforms. It merges
> > sdhci-of-esdhc.c into sdhci-esdhc.c, so that the same pair of
> > .probe/.remove hook works with eSDHC for two platforms.
> >
> > As the results, sdhci-of-esdhc.c and sdhci-esdhc.h are removed, and
> > header esdhc.h containing the definition of esdhc_platform_data is
> > put into the public folder.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>
> I agree with Anton about not merging the two...
>
> > +#ifndef CONFIG_MMC_SDHCI_ESDHC_IMX
> > +#define cpu_is_mx25() (0)
> > +#define cpu_is_mx35() (0)
> > +#define cpu_is_mx51() (0)
> > +#define cpu_is_imx() (0)
> > +#else
> > +#define cpu_is_imx() (1)
> > +#endif
>
> ... e.g. that looks a bit frightening.
>
Agree.
The use of cpu_is_mx..() in the driver itself seems a churn to me
even without this consolidation patch. Is it possible for us to
eliminate them by using pdata, and eventually device tree? When we
are there, I might want to revisit the consolidation again.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-25 6:06 ` Shawn Guo
@ 2011-05-25 6:46 ` Uwe Kleine-König
2011-05-25 9:36 ` Shawn Guo
0 siblings, 1 reply; 26+ messages in thread
From: Uwe Kleine-König @ 2011-05-25 6:46 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Shawn Guo, linuxppc-dev,
Albert Herranz, linux-arm-kernel
Hello Shawn,
> > > +#ifndef CONFIG_MMC_SDHCI_ESDHC_IMX
> > > +#define cpu_is_mx25() (0)
> > > +#define cpu_is_mx35() (0)
> > > +#define cpu_is_mx51() (0)
> > > +#define cpu_is_imx() (0)
> > > +#else
> > > +#define cpu_is_imx() (1)
> > > +#endif
> >
> > ... e.g. that looks a bit frightening.
> >
> Agree.
>
> The use of cpu_is_mx..() in the driver itself seems a churn to me
> even without this consolidation patch. Is it possible for us to
> eliminate them by using pdata, and eventually device tree? When we
> are there, I might want to revisit the consolidation again.
An alternative that allows letting the logic in the driver and still
getting rid of the cpu_is_ stuff is using platform ids. See
drivers/spi/spi_imx.c for an example. Instead of an index into an array
(as it's for the imx-spi driver) driver_data can hold flags, too, which
should be enough most of the time.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx
2011-05-25 6:46 ` Uwe Kleine-König
@ 2011-05-25 9:36 ` Shawn Guo
0 siblings, 0 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-25 9:36 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Chris Ball, Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Shawn Guo, linuxppc-dev,
Albert Herranz, linux-arm-kernel
Hi Uwe,
On Wed, May 25, 2011 at 08:46:19AM +0200, Uwe Kleine-K=F6nig wrote:
> Hello Shawn,
>=20
> > > > +#ifndef CONFIG_MMC_SDHCI_ESDHC_IMX
> > > > +#define cpu_is_mx25() (0)
> > > > +#define cpu_is_mx35() (0)
> > > > +#define cpu_is_mx51() (0)
> > > > +#define cpu_is_imx() (0)
> > > > +#else
> > > > +#define cpu_is_imx() (1)
> > > > +#endif
> > >=20
> > > ... e.g. that looks a bit frightening.
> > >=20
> > Agree.
> >=20
> > The use of cpu_is_mx..() in the driver itself seems a churn to me
> > even without this consolidation patch. Is it possible for us to
> > eliminate them by using pdata, and eventually device tree? When we
> > are there, I might want to revisit the consolidation again.
> An alternative that allows letting the logic in the driver and still
> getting rid of the cpu_is_ stuff is using platform ids. See
> drivers/spi/spi_imx.c for an example. Instead of an index into an array
> (as it's for the imx-spi driver) driver_data can hold flags, too, which
> should be enough most of the time.
>=20
Yeah, this is definitely a solution I can try later. But for now, I
would drop the esdhc consolidation patch.
--=20
Regards,
Shawn
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 6/7] mmc: sdhci: merge two sdhci-pltfm.h into one
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
` (4 preceding siblings ...)
2011-05-05 13:22 ` [PATCH v2 5/7] mmc: sdhci: consolidate sdhci-of-esdhc and sdhci-esdhc-imx Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-05 14:13 ` Anton Vorontsov
2011-05-05 13:22 ` [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one Shawn Guo
2011-05-19 9:40 ` [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Wolfram Sang
7 siblings, 1 reply; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
The structure sdhci_pltfm_data is not necessarily to be in a public
header like include/linux/mmc/sdhci-pltfm.h, so the patch moves it
into drivers/mmc/host/sdhci-pltfm.h and eliminates the former one.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
---
drivers/mmc/host/sdhci-cns3xxx.c | 1 -
drivers/mmc/host/sdhci-esdhc.c | 1 -
drivers/mmc/host/sdhci-pltfm.h | 6 +++++-
include/linux/mmc/sdhci-pltfm.h | 29 -----------------------------
4 files changed, 5 insertions(+), 32 deletions(-)
delete mode 100644 include/linux/mmc/sdhci-pltfm.h
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index ac4b26f..025d1a5 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mmc/host.h>
-#include <linux/mmc/sdhci-pltfm.h>
#include <mach/cns3xxx.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
diff --git a/drivers/mmc/host/sdhci-esdhc.c b/drivers/mmc/host/sdhci-esdhc.c
index f3b4ff5..f005cb8 100644
--- a/drivers/mmc/host/sdhci-esdhc.c
+++ b/drivers/mmc/host/sdhci-esdhc.c
@@ -22,7 +22,6 @@
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
-#include <linux/mmc/sdhci-pltfm.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/esdhc.h>
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index fe27b83..fd72694 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -14,9 +14,13 @@
#include <linux/clk.h>
#include <linux/types.h>
#include <linux/platform_device.h>
-#include <linux/mmc/sdhci-pltfm.h>
#include <linux/mmc/sdhci.h>
+struct sdhci_pltfm_data {
+ struct sdhci_ops *ops;
+ unsigned int quirks;
+};
+
struct sdhci_pltfm_host {
struct clk *clk;
void *priv; /* to handle quirks across io-accessor calls */
diff --git a/include/linux/mmc/sdhci-pltfm.h b/include/linux/mmc/sdhci-pltfm.h
deleted file mode 100644
index f1c2ac3..0000000
--- a/include/linux/mmc/sdhci-pltfm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Platform data declarations for the sdhci-pltfm driver.
- *
- * Copyright (c) 2010 MontaVista Software, LLC.
- *
- * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * 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; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef _SDHCI_PLTFM_H
-#define _SDHCI_PLTFM_H
-
-struct sdhci_ops;
-
-/**
- * struct sdhci_pltfm_data - SDHCI platform-specific information & hooks
- * @ops: optional pointer to the platform-provided SDHCI ops
- * @quirks: optional SDHCI quirks
- */
-struct sdhci_pltfm_data {
- struct sdhci_ops *ops;
- unsigned int quirks;
-};
-
-#endif /* _SDHCI_PLTFM_H */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 6/7] mmc: sdhci: merge two sdhci-pltfm.h into one
2011-05-05 13:22 ` [PATCH v2 6/7] mmc: sdhci: merge two sdhci-pltfm.h into one Shawn Guo
@ 2011-05-05 14:13 ` Anton Vorontsov
0 siblings, 0 replies; 26+ messages in thread
From: Anton Vorontsov @ 2011-05-05 14:13 UTC (permalink / raw)
To: Shawn Guo
Cc: sameo, Arnd Bergmann, patches, devicetree-discuss, linux-mmc,
Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport, Olof Johansson,
Chris Ball, linuxppc-dev, Albert Herranz, linux-arm-kernel
On Thu, May 05, 2011 at 09:22:57PM +0800, Shawn Guo wrote:
> The structure sdhci_pltfm_data is not necessarily to be in a public
> header like include/linux/mmc/sdhci-pltfm.h, so the patch moves it
> into drivers/mmc/host/sdhci-pltfm.h and eliminates the former one.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
` (5 preceding siblings ...)
2011-05-05 13:22 ` [PATCH v2 6/7] mmc: sdhci: merge two sdhci-pltfm.h into one Shawn Guo
@ 2011-05-05 13:22 ` Shawn Guo
2011-05-06 8:39 ` Uwe Kleine-König
2011-05-19 9:40 ` [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Wolfram Sang
7 siblings, 1 reply; 26+ messages in thread
From: Shawn Guo @ 2011-05-05 13:22 UTC (permalink / raw)
To: linux-mmc
Cc: Chris Ball, sameo, Arnd Bergmann, patches, Shawn Guo,
devicetree-discuss, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Anton Vorontsov, linuxppc-dev,
Albert Herranz, linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
.../plat-mxc/devices/platform-sdhci-esdhc-imx.c | 1 -
arch/arm/plat-mxc/include/mach/devices-common.h | 2 +-
2 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
index 6b2940b..b401689 100644
--- a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
+++ b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
@@ -8,7 +8,6 @@
#include <mach/hardware.h>
#include <mach/devices-common.h>
-#include <mach/esdhc.h>
#define imx_sdhci_esdhc_imx_data_entry_single(soc, _id, hwid) \
{ \
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8658c9c..c95ab13 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -243,7 +243,7 @@ struct imx_mxc_w1_data {
struct platform_device *__init imx_add_mxc_w1(
const struct imx_mxc_w1_data *data);
-#include <mach/esdhc.h>
+#include <linux/mmc/esdhc.h>
struct imx_sdhci_esdhc_imx_data {
int id;
resource_size_t iobase;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one
2011-05-05 13:22 ` [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one Shawn Guo
@ 2011-05-06 8:39 ` Uwe Kleine-König
2011-05-09 6:23 ` Shawn Guo
0 siblings, 1 reply; 26+ messages in thread
From: Uwe Kleine-König @ 2011-05-06 8:39 UTC (permalink / raw)
To: Shawn Guo
Cc: Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, linux-arm-kernel,
kernel, Mike Rapoport, Olof Johansson, Chris Ball, linuxppc-dev,
Albert Herranz, Xiaobo Xie
Hello Shawn,
On Thu, May 05, 2011 at 09:22:58PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
> .../plat-mxc/devices/platform-sdhci-esdhc-imx.c | 1 -
> arch/arm/plat-mxc/include/mach/devices-common.h | 2 +-
what about removing arch/arm/plat-mxc/include/mach/esdhc.h in this
patch as advertised in the subject?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one
2011-05-06 8:39 ` Uwe Kleine-König
@ 2011-05-09 6:23 ` Shawn Guo
0 siblings, 0 replies; 26+ messages in thread
From: Shawn Guo @ 2011-05-09 6:23 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Shawn Guo, sameo, Xiaobo Xie, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Chris Ball, kernel, Mike Rapoport,
Anton Vorontsov, linuxppc-dev, Albert Herranz, linux-arm-kernel
Hi Uwe,
On Fri, May 06, 2011 at 10:39:59AM +0200, Uwe Kleine-K=F6nig wrote:
> Hello Shawn,
>=20
> On Thu, May 05, 2011 at 09:22:58PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> > .../plat-mxc/devices/platform-sdhci-esdhc-imx.c | 1 -
> > arch/arm/plat-mxc/include/mach/devices-common.h | 2 +-
> what about removing arch/arm/plat-mxc/include/mach/esdhc.h in this
> patch as advertised in the subject?
>=20
Yes, will do if the patch #4 will finally stands. People are voting
for it. Let's see Wolfram's position.
--=20
Regards,
Shawn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered
2011-05-05 13:22 [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Shawn Guo
` (6 preceding siblings ...)
2011-05-05 13:22 ` [PATCH v2 7/7] ARM: mxc: remove esdhc.h and use the public one Shawn Guo
@ 2011-05-19 9:40 ` Wolfram Sang
2011-05-19 16:09 ` Shawn Guo
7 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2011-05-19 9:40 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, sameo, Arnd Bergmann, patches, devicetree-discuss,
linux-mmc, Saeed Bishara, Xiaobo Xie, kernel, Mike Rapoport,
Olof Johansson, Anton Vorontsov, linuxppc-dev, Albert Herranz,
linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 1083 bytes --]
Hi Shawn,
> Changes since v1:
> * Rebase on cjb's mmc-next tree
Is it maybe possible that you get access to
http://opensource.freescale.com/git or another machine? A branch to pull
from would be more convenient, because the series does not apply to
mmc-next anymore, so an extra step to go "back in time" is needed.
(minor) When applying I got:
Applying: mmc: sdhci: make sdhci-pltfm device drivers self registered
/home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:384: trailing whitespace.
/home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:817: space before tab in indent.
struct tegra_sdhci_platform_data *plat;
/home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:867: trailing whitespace.
Applying: sdhci: rename sdhci-esdhc-imx.c to sdhci-esdhc.c
/home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:780: trailing whitespace.
See later comments for further issues.
Thanks,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered
2011-05-19 9:40 ` [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered Wolfram Sang
@ 2011-05-19 16:09 ` Shawn Guo
2011-05-19 17:05 ` Wolfram Sang
0 siblings, 1 reply; 26+ messages in thread
From: Shawn Guo @ 2011-05-19 16:09 UTC (permalink / raw)
To: Wolfram Sang
Cc: Chris Ball, Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Shawn Guo, linuxppc-dev,
Albert Herranz, linux-arm-kernel
Hi Wolfram,
On Thu, May 19, 2011 at 11:40:46AM +0200, Wolfram Sang wrote:
> Hi Shawn,
>
> > Changes since v1:
> > * Rebase on cjb's mmc-next tree
>
> Is it maybe possible that you get access to
> http://opensource.freescale.com/git or another machine? A branch to pull
> from would be more convenient, because the series does not apply to
> mmc-next anymore, so an extra step to go "back in time" is needed.
>
> (minor) When applying I got:
>
> Applying: mmc: sdhci: make sdhci-pltfm device drivers self registered
> /home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:384: trailing whitespace.
> /home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:817: space before tab in indent.
> struct tegra_sdhci_platform_data *plat;
> /home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:867: trailing whitespace.
>
> Applying: sdhci: rename sdhci-esdhc-imx.c to sdhci-esdhc.c
> /home/wsa/Kernel/linux-2.6/.git/rebase-apply/patch:780: trailing whitespace.
>
> See later comments for further issues.
>
Should I go for v3 right now to address the patch applying problems
and that ESDHC_IMX build issue, or hold for a while to see if you
have more comments on v2?
And what is your position on patch #5 which merges esdhc imx and mpc
support into one? As Anton has voted a NO there, I would probably
drop the patch if there is another person has strong opinion to get
imx and mpc stay separated.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 0/7] Consolidate sdhci pltfm & OF drivers and get them self registered
2011-05-19 16:09 ` Shawn Guo
@ 2011-05-19 17:05 ` Wolfram Sang
0 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2011-05-19 17:05 UTC (permalink / raw)
To: Shawn Guo
Cc: Chris Ball, Anton Vorontsov, sameo, Arnd Bergmann, patches,
devicetree-discuss, linux-mmc, Saeed Bishara, Xiaobo Xie, kernel,
Mike Rapoport, Olof Johansson, Shawn Guo, linuxppc-dev,
Albert Herranz, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 784 bytes --]
Hi Shawn,
> Should I go for v3 right now to address the patch applying problems
> and that ESDHC_IMX build issue, or hold for a while to see if you
> have more comments on v2?
Please wait a little bit more.
> And what is your position on patch #5 which merges esdhc imx and mpc
> support into one? As Anton has voted a NO there, I would probably
> drop the patch if there is another person has strong opinion to get
> imx and mpc stay separated.
This was the other main issue I spotted so far. I wanted to have another look
tomorrow, yet the tendency is that I agree with Anton.
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread