From 51e7e8b632d8e564ba494dfa61358ac1a97e4ceb Mon Sep 17 00:00:00 2001 From: Bernie Thompson Date: Wed, 27 Feb 2013 12:19:17 -0800 Subject: mmc: core: Add in support to expose PRV for v4 MMCs The JEDEC MMC v4 spec defines a new PRV value in place of the original fwrev and hwrev specified in v1. We can expose this in the kernel to enable user space to more easily determine the product revision of a given MMC. Signed-off-by: Bernie Thompson Reviewed-by: Ulf Hansson Signed-off-by: Chris Ball --- Documentation/mmc/mmc-dev-attrs.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt index 0d98fac8893b..189bab09255a 100644 --- a/Documentation/mmc/mmc-dev-attrs.txt +++ b/Documentation/mmc/mmc-dev-attrs.txt @@ -22,6 +22,7 @@ All attributes are read-only. manfid Manufacturer ID (from CID Register) name Product Name (from CID Register) oemid OEM/Application ID (from CID Register) + prv Product Revision (from CID Register) (SD and MMCv4 only) serial Product Serial Number (from CID Register) erase_size Erase group size preferred_erase_size Preferred erase size -- cgit v1.2.3 From e19499ae10903807acbaa07a28d4b56d508ac339 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 6 Mar 2013 17:06:16 +0530 Subject: mmc: sdhci-s3c: let device core setup the default pin configuration With device core now able to setup the default pin configuration, the call to devm_pinctrl_get_select_default can be removed. And the pin configuration code based on the deprecated Samsung specific gpio bindings is also removed. Signed-off-by: Thomas Abraham Acked-by: Linus Walleij Signed-off-by: Chris Ball --- .../devicetree/bindings/mmc/samsung-sdhci.txt | 35 ++--------- drivers/mmc/host/sdhci-s3c.c | 71 +++------------------- 2 files changed, 12 insertions(+), 94 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt index 3b3a1ee055ff..328e990d2546 100644 --- a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt @@ -5,13 +5,6 @@ MMC, SD and eMMC storage mediums. This file documents differences between the core mmc properties described by mmc.txt and the properties used by the Samsung implmentation of the SDHCI controller. -Note: The mmc core bindings documentation states that if none of the core -card-detect bindings are used, then the standard sdhci card detect mechanism -is used. The Samsung's SDHCI controller bindings extends this as listed below. - -[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the - "Optional Board Specific Properties" section below. - Required SoC Specific Properties: - compatible: should be one of the following - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci @@ -20,18 +13,8 @@ Required SoC Specific Properties: controller. Required Board Specific Properties: -- Samsung GPIO variant (will be completely replaced by pinctrl): - - gpios: Should specify the gpios used for clock, command and data lines. The - gpio specifier format depends on the gpio controller. -- Pinctrl variant (preferred if available): - - pinctrl-0: Should specify pin control groups used for this controller. - - pinctrl-names: Should contain only one value - "default". - -Optional Board Specific Properties: -- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed - through a pinmux to the card-detect pin of the card slot. This property - should be used only if none of the mmc core card-detect properties are - used. Only for Samsung GPIO variant. +- pinctrl-0: Should specify pin control groups used for this controller. +- pinctrl-names: Should contain only one value - "default". Example: sdhci@12530000 { @@ -39,19 +22,9 @@ Example: reg = <0x12530000 0x100>; interrupts = <0 75 0>; bus-width = <4>; - cd-gpios = <&gpk2 2 2 3 3>; - - /* Samsung GPIO variant */ - gpios = <&gpk2 0 2 0 3>, /* clock line */ - <&gpk2 1 2 0 3>, /* command line */ - <&gpk2 3 2 3 3>, /* data line 0 */ - <&gpk2 4 2 3 3>, /* data line 1 */ - <&gpk2 5 2 3 3>, /* data line 2 */ - <&gpk2 6 2 3 3>; /* data line 3 */ - - /* Pinctrl variant */ - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; + cd-gpios = <&gpk2 2 0>; pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; }; Note: This example shows both SoC specific and board specific properties diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 128b65030a0c..8cd966d25bec 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -45,7 +44,6 @@ * @ioarea: The resource created when we claimed the IO area. * @pdata: The platform data for this controller. * @cur_clk: The index of the current bus clock. - * @gpios: List of gpio numbers parsed from device tree. * @clk_io: The clock for the internal bus interface. * @clk_bus: The clocks that are available for the SD/MMC bus clock. */ @@ -57,8 +55,6 @@ struct sdhci_s3c { unsigned int cur_clk; int ext_cd_irq; int ext_cd_gpio; - int *gpios; - struct pinctrl *pctrl; struct clk *clk_io; struct clk *clk_bus[MAX_BUS_CLK]; @@ -447,88 +443,39 @@ static int sdhci_s3c_parse_dt(struct device *dev, struct device_node *node = dev->of_node; struct sdhci_s3c *ourhost = to_s3c(host); u32 max_width; - int gpio, cnt, ret; + int gpio; /* if the bus-width property is not specified, assume width as 1 */ if (of_property_read_u32(node, "bus-width", &max_width)) max_width = 1; pdata->max_width = max_width; - ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) * - sizeof(int), GFP_KERNEL); - if (!ourhost->gpios) - return -ENOMEM; - /* get the card detection method */ if (of_get_property(node, "broken-cd", NULL)) { pdata->cd_type = S3C_SDHCI_CD_NONE; - goto setup_bus; + return 0; } if (of_get_property(node, "non-removable", NULL)) { pdata->cd_type = S3C_SDHCI_CD_PERMANENT; - goto setup_bus; + return 0; } gpio = of_get_named_gpio(node, "cd-gpios", 0); if (gpio_is_valid(gpio)) { pdata->cd_type = S3C_SDHCI_CD_GPIO; - goto found_cd; - } else if (gpio != -ENOENT) { - dev_err(dev, "invalid card detect gpio specified\n"); - return -EINVAL; - } - - gpio = of_get_named_gpio(node, "samsung,cd-pinmux-gpio", 0); - if (gpio_is_valid(gpio)) { - pdata->cd_type = S3C_SDHCI_CD_INTERNAL; - goto found_cd; - } else if (gpio != -ENOENT) { - dev_err(dev, "invalid card detect gpio specified\n"); - return -EINVAL; - } - - /* assuming internal card detect that will be configured by pinctrl */ - pdata->cd_type = S3C_SDHCI_CD_INTERNAL; - goto setup_bus; - - found_cd: - if (pdata->cd_type == S3C_SDHCI_CD_GPIO) { pdata->ext_cd_gpio = gpio; ourhost->ext_cd_gpio = -1; if (of_get_property(node, "cd-inverted", NULL)) pdata->ext_cd_gpio_invert = 1; - } else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { - ret = devm_gpio_request(dev, gpio, "sdhci-cd"); - if (ret) { - dev_err(dev, "card detect gpio request failed\n"); - return -EINVAL; - } - ourhost->ext_cd_gpio = gpio; - } - - setup_bus: - if (!IS_ERR(ourhost->pctrl)) return 0; - - /* get the gpios for command, clock and data lines */ - for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) { - gpio = of_get_gpio(node, cnt); - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio[%d]\n", cnt); - return -EINVAL; - } - ourhost->gpios[cnt] = gpio; - } - - for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) { - ret = devm_gpio_request(dev, ourhost->gpios[cnt], "sdhci-gpio"); - if (ret) { - dev_err(dev, "gpio[%d] request failed\n", cnt); - return -EINVAL; - } + } else if (gpio != -ENOENT) { + dev_err(dev, "invalid card detect gpio specified\n"); + return -EINVAL; } + /* assuming internal card detect that will be configured by pinctrl */ + pdata->cd_type = S3C_SDHCI_CD_INTERNAL; return 0; } #else @@ -589,8 +536,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev) goto err_pdata_io_clk; } - sc->pctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (pdev->dev.of_node) { ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata); if (ret) -- cgit v1.2.3 From b3b665b0a9d13d731a61aeed92a02c1c9c55cd70 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 21 Mar 2013 16:27:19 +0800 Subject: mmc: sdhci-sirf: add mmc host sdhci-pltfm based driver for SiRF SoCs This patch adds the new driver for CSR SiRF SoCs: SiRFprimaII: unicore ARM Cortex-A9 SiRFatlas6: unicore ARM Cortex-A9 SiRFmarco: dual core ARM Cortex-A9 SMP Signed-off-by: Barry Song Signed-off-by: Bin Shi Acked-by: Arnd Bergmann Signed-off-by: Chris Ball --- .../devicetree/bindings/mmc/sdhci-sirf.txt | 18 ++ MAINTAINERS | 1 + drivers/mmc/host/Kconfig | 11 ++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-sirf.c | 193 +++++++++++++++++++++ 5 files changed, 224 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-sirf.txt create mode 100644 drivers/mmc/host/sdhci-sirf.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt b/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt new file mode 100644 index 000000000000..dd6ed464bcb8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt @@ -0,0 +1,18 @@ +* SiRFprimII/marco/atlas6 SDHCI Controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-sirf driver. + +Required properties: +- compatible: sirf,prima2-sdhc + +Optional properties: +- cd-gpios: card detect gpio, with zero flags. + +Example: + + sd0: sdhci@56000000 { + compatible = "sirf,prima2-sdhc"; + reg = <0xcd000000 0x100000>; + cd-gpios = <&gpio 6 0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index e95b1e944eb7..21b1678ab790 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -805,6 +805,7 @@ S: Maintained F: arch/arm/mach-prima2/ F: drivers/dma/sirf-dma.c F: drivers/i2c/busses/i2c-sirf.c +F: drivers/mmc/host/sdhci-sirf.c F: drivers/pinctrl/pinctrl-sirf.c F: drivers/spi/spi-sirf.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9c581c2ed349..f83f2454e33b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -190,6 +190,17 @@ config MMC_SDHCI_S3C If unsure, say N. +config MMC_SDHCI_SIRF + tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs" + depends on ARCH_SIRF + depends on MMC_SDHCI_PLTFM + help + This selects the SDHCI support for SiRF System-on-Chip devices. + + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_PXAV3 tristate "Marvell MMP2 SD Host Controller support (PXAV3)" depends on CLKDEV_LOOKUP diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c380e3cf0a3b..cd3228075553 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o +obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c new file mode 100644 index 000000000000..09805af0526d --- /dev/null +++ b/drivers/mmc/host/sdhci-sirf.c @@ -0,0 +1,193 @@ +/* + * SDHCI support for SiRF primaII and marco SoCs + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdhci-pltfm.h" + +struct sdhci_sirf_priv { + struct clk *clk; + int gpio_cd; +}; + +static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_sirf_priv *priv = pltfm_host->priv; + return clk_get_rate(priv->clk); +} + +static struct sdhci_ops sdhci_sirf_ops = { + .get_max_clock = sdhci_sirf_get_max_clk, +}; + +static struct sdhci_pltfm_data sdhci_sirf_pdata = { + .ops = &sdhci_sirf_ops, + .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_INVERTED_WRITE_PROTECT | + SDHCI_QUIRK_DELAY_AFTER_POWER, +}; + +static int sdhci_sirf_probe(struct platform_device *pdev) +{ + struct sdhci_host *host; + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_sirf_priv *priv; + struct pinctrl *pinctrl; + int ret; + + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + dev_err(&pdev->dev, "unable to get pinmux"); + return PTR_ERR(pinctrl); + } + + priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_sirf_priv), + GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "unable to allocate private data"); + return -ENOMEM; + } + + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "unable to get clock"); + return PTR_ERR(priv->clk); + } + + if (pdev->dev.of_node) { + priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node, + "cd-gpios", 0); + } else { + priv->gpio_cd = -EINVAL; + } + + host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata); + if (IS_ERR(host)) { + ret = PTR_ERR(host); + goto err_sdhci_pltfm_init; + } + + pltfm_host = sdhci_priv(host); + pltfm_host->priv = priv; + + sdhci_get_of_property(pdev); + + clk_prepare_enable(priv->clk); + + ret = sdhci_add_host(host); + if (ret) + goto err_sdhci_add; + + /* + * We must request the IRQ after sdhci_add_host(), as the tasklet only + * gets setup in sdhci_add_host() and we oops. + */ + if (gpio_is_valid(priv->gpio_cd)) { + ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd); + if (ret) { + dev_err(&pdev->dev, "card detect irq request failed: %d\n", + ret); + goto err_request_cd; + } + } + + return 0; + +err_request_cd: + sdhci_remove_host(host, 0); +err_sdhci_add: + clk_disable_unprepare(priv->clk); + sdhci_pltfm_free(pdev); +err_sdhci_pltfm_init: + return ret; +} + +static int sdhci_sirf_remove(struct platform_device *pdev) +{ + struct sdhci_host *host = platform_get_drvdata(pdev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_sirf_priv *priv = pltfm_host->priv; + + sdhci_pltfm_unregister(pdev); + + if (gpio_is_valid(priv->gpio_cd)) + mmc_gpio_free_cd(host->mmc); + + clk_disable_unprepare(priv->clk); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int sdhci_sirf_suspend(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_sirf_priv *priv = pltfm_host->priv; + int ret; + + ret = sdhci_suspend_host(host); + if (ret) + return ret; + + clk_disable(priv->clk); + + return 0; +} + +static int sdhci_sirf_resume(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_sirf_priv *priv = pltfm_host->priv; + int ret; + + ret = clk_enable(priv->clk); + if (ret) { + dev_dbg(dev, "Resume: Error enabling clock\n"); + return ret; + } + + return sdhci_resume_host(host); +} + +static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops, sdhci_sirf_suspend, sdhci_sirf_resume); +#endif + +static const struct of_device_id sdhci_sirf_of_match[] = { + { .compatible = "sirf,prima2-sdhc" }, + { } +}; +MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match); + +static struct platform_driver sdhci_sirf_driver = { + .driver = { + .name = "sdhci-sirf", + .owner = THIS_MODULE, + .of_match_table = sdhci_sirf_of_match, +#ifdef CONFIG_PM_SLEEP + .pm = &sdhci_sirf_pm_ops, +#endif + }, + .probe = sdhci_sirf_probe, + .remove = sdhci_sirf_remove, +}; + +module_platform_driver(sdhci_sirf_driver); + +MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco"); +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 7ff747c45908abb4fb894b21a8752a3e48acf02b Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sun, 31 Mar 2013 20:07:38 +0200 Subject: mmc: mxcmmc: DT support Adding devicetree support for imx21-mmc and imx31-mmc. Based on generic gpio helper functions by Guennadi and generic DMA devicetree bindings. Signed-off-by: Markus Pargmann Signed-off-by: Anatolij Gustschin Acked-by: Arnd Bergmann Signed-off-by: Chris Ball --- .../devicetree/bindings/mmc/fsl-imx-mmc.txt | 24 +++++++ drivers/mmc/host/mxcmmc.c | 79 +++++++++++++++++----- 2 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt new file mode 100644 index 000000000000..db442355cd24 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt @@ -0,0 +1,24 @@ +* Freescale Secure Digital Host Controller for i.MX2/3 series + +This file documents differences to the properties defined in mmc.txt. + +Required properties: +- compatible : Should be "fsl,-mmc", chip can be imx21 or imx31 + +Optional properties: +- dmas: One DMA phandle with arguments as defined by the devicetree bindings + of the used DMA controller. +- dma-names: Has to be "rx-tx". + +Example: + +sdhci1: sdhci@10014000 { + compatible = "fsl,imx27-mmc", "fsl,imx21-mmc"; + reg = <0x10014000 0x1000>; + interrupts = <11>; + dmas = <&dma 7>; + dma-names = "rx-tx"; + bus-width = <4>; + cd-gpios = <&gpio3 29>; + status = "okay"; +}; diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 28e527ebde75..848ab2c2ff05 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -34,6 +34,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -173,6 +177,19 @@ static struct platform_device_id mxcmci_devtype[] = { }; MODULE_DEVICE_TABLE(platform, mxcmci_devtype); +static const struct of_device_id mxcmci_of_match[] = { + { + .compatible = "fsl,imx21-mmc", + .data = &mxcmci_devtype[IMX21_MMC], + }, { + .compatible = "fsl,imx31-mmc", + .data = &mxcmci_devtype[IMX31_MMC], + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, mxcmci_of_match); + static inline int is_imx31_mmc(struct mxcmci_host *host) { return host->devtype == IMX31_MMC; @@ -935,10 +952,15 @@ static int mxcmci_probe(struct platform_device *pdev) struct mxcmci_host *host = NULL; struct resource *iores, *r; int ret = 0, irq; + bool dat3_card_detect = false; dma_cap_mask_t mask; + const struct of_device_id *of_id; + struct imxmmc_platform_data *pdata = pdev->dev.platform_data; pr_info("i.MX SDHC driver\n"); + of_id = of_match_device(mxcmci_of_match, &pdev->dev); + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!iores || irq < 0) @@ -954,8 +976,14 @@ static int mxcmci_probe(struct platform_device *pdev) goto out_release_mem; } + mmc_of_parse(mmc); mmc->ops = &mxcmci_ops; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + + /* For devicetree parsing, the bus width is read from devicetree */ + if (pdata) + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + else + mmc->caps |= MMC_CAP_SDIO_IRQ; /* MMC core transfer sizes tunable parameters */ mmc->max_segs = 64; @@ -971,14 +999,25 @@ static int mxcmci_probe(struct platform_device *pdev) goto out_free; } + if (of_id) { + const struct platform_device_id *id_entry = of_id->data; + host->devtype = id_entry->driver_data; + } else { + host->devtype = pdev->id_entry->driver_data; + } host->mmc = mmc; - host->pdata = pdev->dev.platform_data; - host->devtype = pdev->id_entry->driver_data; + host->pdata = pdata; spin_lock_init(&host->lock); + if (pdata) + dat3_card_detect = pdata->dat3_card_detect; + else if (!(mmc->caps & MMC_CAP_NONREMOVABLE) + && !of_property_read_bool(pdev->dev.of_node, "cd-gpios")) + dat3_card_detect = true; + mxcmci_init_ocr(host); - if (host->pdata && host->pdata->dat3_card_detect) + if (dat3_card_detect) host->default_irq_mask = INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN; else @@ -1020,21 +1059,24 @@ static int mxcmci_probe(struct platform_device *pdev) writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); - r = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (r) { - host->dmareq = r->start; - host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; - host->dma_data.priority = DMA_PRIO_LOW; - host->dma_data.dma_request = host->dmareq; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - host->dma = dma_request_channel(mask, filter, host); - if (host->dma) - mmc->max_seg_size = dma_get_max_seg_size( - host->dma->device->dev); + if (!host->pdata) { + host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx"); + } else { + r = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (r) { + host->dmareq = r->start; + host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; + host->dma_data.priority = DMA_PRIO_LOW; + host->dma_data.dma_request = host->dmareq; + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + host->dma = dma_request_channel(mask, filter, host); + } } - - if (!host->dma) + if (host->dma) + mmc->max_seg_size = dma_get_max_seg_size( + host->dma->device->dev); + else dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n"); INIT_WORK(&host->datawork, mxcmci_datawork); @@ -1153,6 +1195,7 @@ static struct platform_driver mxcmci_driver = { #ifdef CONFIG_PM .pm = &mxcmci_pm_ops, #endif + .of_match_table = mxcmci_of_match, } }; -- cgit v1.2.3