From patchwork Fri May 23 12:33:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 4232021 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 59E32BF90B for ; Fri, 23 May 2014 12:33:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 45CEF20295 for ; Fri, 23 May 2014 12:33:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1DCEE20386 for ; Fri, 23 May 2014 12:33:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751655AbaEWMdZ (ORCPT ); Fri, 23 May 2014 08:33:25 -0400 Received: from metis.ext.pengutronix.de ([92.198.50.35]:43524 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751577AbaEWMdZ (ORCPT ); Fri, 23 May 2014 08:33:25 -0400 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:a236:9fff:fe00:814]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1Wnoeg-0006lw-Jj; Fri, 23 May 2014 14:32:58 +0200 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.82) (envelope-from ) id 1Wnoen-0001YV-Je; Fri, 23 May 2014 14:33:05 +0200 From: Sascha Hauer To: linux-mmc@vger.kernel.org Cc: Shawn Guo , , kernel@pengutronix.de, Sascha Hauer Subject: [PATCH 4/5] mmc: sdhci-esdhc-imx: use mmc_of_parse Date: Fri, 23 May 2014 14:33:03 +0200 Message-Id: <1400848384-3226-5-git-send-email-s.hauer@pengutronix.de> X-Mailer: git-send-email 2.0.0.rc0 In-Reply-To: <1400848384-3226-1-git-send-email-s.hauer@pengutronix.de> References: <1400848384-3226-1-git-send-email-s.hauer@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:2:a236:9fff:fe00:814 X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-mmc@vger.kernel.org Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP mmc_of_parse allows us to use the generic devicetree bindings instead of parsing the properties manually. To do so we have to refactor the driver. The driver currently parses the dt properties into platform_data which is then translated into struct mmc_host caps. This changes the driver so that it - parses dt data into mmc_host caps directly via mmc_of_parse - parses platform_data into mmc_host caps directly - parses the flags for which no mmc_host caps exist into driver private data This makes platform_data used for its original purpose and irrelevant for the devicetree case. Signed-off-by: Sascha Hauer --- drivers/mmc/host/sdhci-esdhc-imx.c | 175 +++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 620cbcd..8c0af44 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -151,8 +151,9 @@ struct pltfm_imx_data { struct pinctrl_state *pins_100mhz; struct pinctrl_state *pins_200mhz; const struct esdhc_soc_data *socdata; - struct esdhc_platform_data boarddata; unsigned long f_max; + unsigned int delay_line; + bool support_vsel; struct clk *clk_ipg; struct clk *clk_ahb; struct clk *clk_per; @@ -161,6 +162,7 @@ struct pltfm_imx_data { MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */ WAIT_FOR_INT, /* sent CMD12, waiting for response INT */ } multiblock_status; + enum wp_types wp_type; u32 uhs_mode; u32 is_ddr; }; @@ -651,9 +653,8 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; - struct esdhc_platform_data *boarddata = &imx_data->boarddata; - switch (boarddata->wp_type) { + switch (imx_data->wp_type) { case ESDHC_WP_GPIO: return mmc_gpio_get_ro(host->mmc); case ESDHC_WP_CONTROLLER: @@ -839,7 +840,6 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; - struct esdhc_platform_data *boarddata = &imx_data->boarddata; switch (uhs) { case MMC_TIMING_UHS_SDR12: @@ -861,9 +861,9 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) ESDHC_MIX_CTRL_DDREN, host->ioaddr + ESDHC_MIX_CTRL); imx_data->is_ddr = 1; - if (boarddata->delay_line) { + if (imx_data->delay_line) { u32 v; - v = boarddata->delay_line << + v = imx_data->delay_line << ESDHC_DLL_OVERRIDE_VAL_SHIFT | (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT); if (is_imx53_esdhc(imx_data)) @@ -900,49 +900,50 @@ static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { #ifdef CONFIG_OF static int sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, - struct pltfm_imx_data *imx_data) + struct sdhci_host *host, struct pltfm_imx_data *imx_data) { - struct esdhc_platform_data *boarddata = &imx_data->boarddata; struct device_node *np = pdev->dev.of_node; + int ret; if (!np) return -ENODEV; - if (of_get_property(np, "non-removable", NULL)) - boarddata->cd_type = ESDHC_CD_PERMANENT; + ret = mmc_of_parse(host->mmc); + if (ret) + return ret; - if (of_get_property(np, "fsl,cd-controller", NULL)) - boarddata->cd_type = ESDHC_CD_CONTROLLER; + if (host->mmc->caps & MMC_CAP_NONREMOVABLE) + host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; if (of_get_property(np, "fsl,wp-controller", NULL)) - boarddata->wp_type = ESDHC_WP_CONTROLLER; + imx_data->wp_type = ESDHC_WP_CONTROLLER; - boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); - if (gpio_is_valid(boarddata->cd_gpio)) - boarddata->cd_type = ESDHC_CD_GPIO; + if (mmc_gpio_get_ro(host->mmc) >= 0) + imx_data->wp_type = ESDHC_WP_GPIO; - boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); - if (gpio_is_valid(boarddata->wp_gpio)) - boarddata->wp_type = ESDHC_WP_GPIO; + /* This flag only means: Do not set the MMC_CAP_4_BIT_DATA flag */ + host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; - of_property_read_u32(np, "bus-width", &boarddata->max_bus_width); - - of_property_read_u32(np, "max-frequency", &boarddata->f_max); + /* + * mmc_of_parse sets host->mmc->f_max, but it gets overwritten + * by the sdhci driver later, so we have to save the value + */ + imx_data->f_max = host->mmc->f_max; if (of_find_property(np, "no-1-8-v", NULL)) - boarddata->support_vsel = false; + imx_data->support_vsel = false; else - boarddata->support_vsel = true; + imx_data->support_vsel = true; - if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) - boarddata->delay_line = 0; + if (of_property_read_u32(np, "fsl,delay-line", &imx_data->delay_line)) + imx_data->delay_line = 0; return 0; } #else static inline int sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, - struct pltfm_imx_data *imx_data) + struct sdhci_host *host, struct pltfm_imx_data *imx_data) { return -ENODEV; } @@ -950,16 +951,67 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, static int sdhci_esdhc_imx_probe_boarddata(struct platform_device *pdev, - struct pltfm_imx_data *imx_data) + struct sdhci_host *host, struct pltfm_imx_data *imx_data) { struct esdhc_platform_data *pdata = pdev->dev.platform_data; + int err; if (!pdata) { dev_err(&pdev->dev, "no boarddata\n"); return -EINVAL; } - imx_data->boarddata = *pdata; + /* card_detect */ + switch (pdata->cd_type) { + case ESDHC_CD_GPIO: + err = mmc_gpio_request_cd(host->mmc, pdata->cd_gpio, 0); + if (err) { + dev_err(mmc_dev(host->mmc), + "failed to request card-detect gpio!\n"); + return err; + } + break; + + case ESDHC_CD_CONTROLLER: + break; + + case ESDHC_CD_PERMANENT: + host->mmc->caps |= MMC_CAP_NONREMOVABLE; + host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; + break; + + case ESDHC_CD_NONE: + host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; + break; + } + + /* write_protect */ + imx_data->wp_type = pdata->wp_type; + if (pdata->wp_type == ESDHC_WP_GPIO) { + err = mmc_gpio_request_ro(host->mmc, pdata->wp_gpio); + if (err) { + dev_err(mmc_dev(host->mmc), + "failed to request write-protect gpio!\n"); + return err; + } + host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + } + + switch (pdata->max_bus_width) { + case 8: + host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; + break; + case 4: + host->mmc->caps |= MMC_CAP_4_BIT_DATA; + break; + case 1: + default: + host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; + break; + } + + imx_data->delay_line = pdata->delay_line; + imx_data->support_vsel = pdata->support_vsel; return 0; } @@ -970,9 +1022,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) of_match_device(imx_esdhc_dt_ids, &pdev->dev); struct sdhci_pltfm_host *pltfm_host; struct sdhci_host *host; - struct esdhc_platform_data *boarddata; int err; struct pltfm_imx_data *imx_data; + unsigned long f_max; host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0); if (IS_ERR(host)) @@ -1052,67 +1104,20 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP, host->ioaddr + ESDHC_TUNING_CTRL); - boarddata = &imx_data->boarddata; - if (sdhci_esdhc_imx_probe_dt(pdev, imx_data) < 0) { - err = sdhci_esdhc_imx_probe_boarddata(pdev, imx_data); + if (sdhci_esdhc_imx_probe_dt(pdev, host, imx_data) < 0) { + err = sdhci_esdhc_imx_probe_boarddata(pdev, host, imx_data); if (err) goto disable_clk; } - imx_data->f_max = clk_get_rate(imx_data->clk_per); - if (boarddata->f_max && boarddata->f_max < imx_data->f_max) - imx_data->f_max = boarddata->f_max; - - /* write_protect */ - if (boarddata->wp_type == ESDHC_WP_GPIO) { - err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio); - if (err) { - dev_err(mmc_dev(host->mmc), - "failed to request write-protect gpio!\n"); - goto disable_clk; - } - host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; - } - - /* card_detect */ - switch (boarddata->cd_type) { - case ESDHC_CD_GPIO: - err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0); - if (err) { - dev_err(mmc_dev(host->mmc), - "failed to request card-detect gpio!\n"); - goto disable_clk; - } - break; - - case ESDHC_CD_CONTROLLER: - break; - - case ESDHC_CD_PERMANENT: - host->mmc->caps |= MMC_CAP_NONREMOVABLE; - host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; - break; - - case ESDHC_CD_NONE: - host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; - break; - } - - switch (boarddata->max_bus_width) { - case 8: - host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; - break; - case 4: - host->mmc->caps |= MMC_CAP_4_BIT_DATA; - break; - case 1: - default: - host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; - break; - } + f_max = clk_get_rate(imx_data->clk_per); + if (imx_data->f_max) + imx_data->f_max = min(f_max, imx_data->f_max); + else + imx_data->f_max = f_max; /* sdr50 and sdr104 needs work on 1.8v signal voltage */ - if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data)) { + if ((imx_data->support_vsel) && esdhc_is_usdhc(imx_data)) { imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, ESDHC_PINCTRL_STATE_100MHZ); imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,