diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch new file mode 100644 index 0000000000..4f8cc2011f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch @@ -0,0 +1,169 @@ +This patch adds a simple Device Tree binding for the mvsdio driver, as +well as the necessary documentation for it. Compatibility with non-DT +platforms is preserved, by keeping the platform_data based +initialization. + +We introduce a small difference between non-DT and DT platforms: DT +platforms are required to provide a clocks = <...> property, which the +driver uses to get the frequency of the clock that goes to the SDIO +IP. The behaviour on non-DT platforms is kept unchanged: a clock +reference is not mandatory, but the clock frequency must be passed in +the "clock" field of the mvsdio_platform_data structure. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + .../devicetree/bindings/mmc/orion-sdio.txt | 17 ++++++ + drivers/mmc/host/mvsdio.c | 60 +++++++++++++++----- + 2 files changed, 62 insertions(+), 15 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mmc/orion-sdio.txt + +diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +new file mode 100644 +index 0000000..84f0ebd +--- /dev/null ++++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +@@ -0,0 +1,17 @@ ++* Marvell orion-sdio controller ++ ++This file documents differences between the core properties in mmc.txt ++and the properties used by the orion-sdio driver. ++ ++- compatible: Should be "marvell,orion-sdio" ++- clocks: reference to the clock of the SDIO interface ++ ++Example: ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index baf19fc..56954bc 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -21,6 +21,8 @@ + #include <linux/irq.h> + #include <linux/clk.h> + #include <linux/gpio.h> ++#include <linux/of_gpio.h> ++#include <linux/of_irq.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> + +@@ -683,17 +685,17 @@ mv_conf_mbus_windows(struct mvsd_host *host, + + static int __init mvsd_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct mmc_host *mmc = NULL; + struct mvsd_host *host = NULL; +- const struct mvsdio_platform_data *mvsd_data; + const struct mbus_dram_target_info *dram; + struct resource *r; + int ret, irq; ++ int gpio_card_detect, gpio_write_protect; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +- mvsd_data = pdev->dev.platform_data; +- if (!r || irq < 0 || !mvsd_data) ++ if (!r || irq < 0) + return -ENXIO; + + r = request_mem_region(r->start, SZ_1K, DRIVER_NAME); +@@ -710,7 +712,35 @@ static int __init mvsd_probe(struct platform_device *pdev) + host->mmc = mmc; + host->dev = &pdev->dev; + host->res = r; +- host->base_clock = mvsd_data->clock / 2; ++ ++ /* Some non-DT platforms do not pass a clock, and the clock ++ frequency is passed through platform_data. On DT platforms, ++ a clock must always be passed, even if there is no gatable ++ clock associated to the SDIO interface (it can simply be a ++ fixed rate clock). */ ++ host->clk = clk_get(&pdev->dev, NULL); ++ if (!IS_ERR(host->clk)) ++ clk_prepare_enable(host->clk); ++ ++ if (np) { ++ if (IS_ERR(host->clk)) { ++ dev_err(&pdev->dev, "DT platforms must have a clock associated\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ host->base_clock = clk_get_rate(host->clk) / 2; ++ gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0); ++ gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0); ++ } else { ++ const struct mvsdio_platform_data *mvsd_data; ++ mvsd_data = pdev->dev.platform_data; ++ if (!mvsd_data) ++ return -ENXIO; ++ host->base_clock = mvsd_data->clock / 2; ++ gpio_card_detect = mvsd_data->gpio_card_detect; ++ gpio_write_protect = mvsd_data->gpio_write_protect; ++ } + + mmc->ops = &mvsd_ops; + +@@ -750,21 +780,14 @@ static int __init mvsd_probe(struct platform_device *pdev) + } else + host->irq = irq; + +- /* Not all platforms can gate the clock, so it is not +- an error if the clock does not exists. */ +- host->clk = clk_get(&pdev->dev, NULL); +- if (!IS_ERR(host->clk)) { +- clk_prepare_enable(host->clk); +- } +- +- if (gpio_is_valid(mvsd_data->gpio_card_detect)) { +- ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (gpio_is_valid(gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, gpio_card_detect); + if (ret) + goto out; + } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); ++ mmc_gpio_request_ro(mmc, gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -776,7 +799,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + mmc_hostname(mmc), DRIVER_NAME); + if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- mvsd_data->gpio_card_detect); ++ gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -855,12 +878,19 @@ static int mvsd_resume(struct platform_device *dev) + #define mvsd_resume NULL + #endif + ++static const struct of_device_id mvsdio_dt_ids[] = { ++ { .compatible = "marvell,orion-sdio" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mvsdio_dt_ids); ++ + static struct platform_driver mvsd_driver = { + .remove = __exit_p(mvsd_remove), + .suspend = mvsd_suspend, + .resume = mvsd_resume, + .driver = { + .name = DRIVER_NAME, ++ .of_match_table = mvsdio_dt_ids, + }, + }; + +-- +1.7.9.5 |