From patchwork Mon Mar 25 15:34:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Pargmann X-Patchwork-Id: 2332001 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 4354FE00E6 for ; Mon, 25 Mar 2013 15:40:06 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UK9S7-0006JF-J0; Mon, 25 Mar 2013 15:36:51 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UK9S1-0006Eb-77 for linux-arm-kernel@lists.infradead.org; Mon, 25 Mar 2013 15:36:46 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1UK9Ro-00080m-Fo; Mon, 25 Mar 2013 16:36:32 +0100 Received: from mpa by dude.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1UK9Rl-0005iZ-MY; Mon, 25 Mar 2013 16:36:29 +0100 From: Markus Pargmann To: cjb@laptop.org Subject: [PATCH v2] mmc: mxcmmc: DT support Date: Mon, 25 Mar 2013 16:34:19 +0100 Message-Id: <1364225659-29677-1-git-send-email-mpa@pengutronix.de> X-Mailer: git-send-email 1.8.2.rc2 X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: mpa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130325_113645_717339_F0672B65 X-CRM114-Status: GOOD ( 19.62 ) X-Spam-Score: -3.2 (---) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-3.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.3 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: rob@landley.net, devicetree-discuss@lists.ozlabs.org, linux-mmc@vger.kernel.org, rob.herring@calxeda.com, kernel@pengutronix.de, Markus Pargmann , Anatolij Gustschin , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 Cc: Anatolij Gustschin --- Notes: Changes in v2: - Documentation fix - Use dma_request_slave_channel instead of of_* .../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 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 0000000..db44235 --- /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 a72936e..f477b4f 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, } };