From patchwork Mon Aug 14 22:19:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhoujie Wu X-Patchwork-Id: 9900345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 711F3602D9 for ; Mon, 14 Aug 2017 22:16:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 526CE28757 for ; Mon, 14 Aug 2017 22:16:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4548028756; Mon, 14 Aug 2017 22:16:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A19EF28756 for ; Mon, 14 Aug 2017 22:16:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752514AbdHNWQZ (ORCPT ); Mon, 14 Aug 2017 18:16:25 -0400 Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:54049 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752275AbdHNWQZ (ORCPT ); Mon, 14 Aug 2017 18:16:25 -0400 Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v7EMEMCd003335; Mon, 14 Aug 2017 15:16:20 -0700 Received: from sc-exch03.marvell.com ([199.233.58.183]) by mx0b-0016f401.pphosted.com with ESMTP id 2ca16efhqm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 14 Aug 2017 15:16:20 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Mon, 14 Aug 2017 15:16:17 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server id 15.0.1210.3 via Frontend Transport; Mon, 14 Aug 2017 15:16:18 -0700 Received: from an-git01.marvell.com (unknown [10.80.127.149]) by maili.marvell.com (Postfix) with ESMTP id 6FF4B3F703F; Mon, 14 Aug 2017 15:16:18 -0700 (PDT) From: Zhoujie Wu To: , , CC: , , , , , , , , , , , , , Zhoujie Wu Subject: [PATCH] mmc: sdhci-xenon: add gpio hard reset support Date: Mon, 14 Aug 2017 15:19:16 -0700 Message-ID: <1502749156-22798-1-git-send-email-zjwu@marvell.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-08-14_19:, , signatures=0 X-Proofpoint-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1708140366 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On some platforms, like armada3700, SD card need to do hard reset by gpio toggling to make it work properly after warm reset the board. Add gpio hard reset feature for this purpose. Signed-off-by: Zhoujie Wu --- drivers/mmc/host/sdhci-xenon.c | 49 +++++++++++++++++++++++++++++++++++++++--- drivers/mmc/host/sdhci-xenon.h | 4 ++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c index edd4d915..54a7057 100644 --- a/drivers/mmc/host/sdhci-xenon.c +++ b/drivers/mmc/host/sdhci-xenon.c @@ -18,6 +18,8 @@ #include #include #include +#include + #include "sdhci-pltfm.h" #include "sdhci-xenon.h" @@ -210,12 +212,25 @@ static void xenon_set_uhs_signaling(struct sdhci_host *host, sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); } +static void xenon_hw_reset(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); + + if (priv->reset_gpio) { + gpiod_set_value_cansleep(priv->reset_gpio, 0); + msleep(30); + gpiod_set_value_cansleep(priv->reset_gpio, 1); + } +} + static const struct sdhci_ops sdhci_xenon_ops = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, .reset = xenon_reset, .set_uhs_signaling = xenon_set_uhs_signaling, .get_max_clock = sdhci_pltfm_clk_get_max_clock, + .hw_reset = xenon_hw_reset, }; static const struct sdhci_pltfm_data sdhci_xenon_pdata = { @@ -373,10 +388,15 @@ static int xenon_probe_dt(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct sdhci_host *host = platform_get_drvdata(pdev); struct mmc_host *mmc = host->mmc; + struct device *dev = mmc_dev(mmc); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); u32 sdhc_id, nr_sdhc; u32 tuning_count; + int reset_gpio, ret; + enum of_gpio_flags flags; + char *reset_name; + unsigned long gpio_flags; /* Disable HS200 on Armada AP806 */ if (of_device_is_compatible(np, "marvell,armada-ap806-sdhci")) @@ -387,7 +407,7 @@ static int xenon_probe_dt(struct platform_device *pdev) nr_sdhc = sdhci_readl(host, XENON_SYS_CFG_INFO); nr_sdhc &= XENON_NR_SUPPORTED_SLOT_MASK; if (unlikely(sdhc_id > nr_sdhc)) { - dev_err(mmc_dev(mmc), "SDHC Index %d exceeds Number of SDHCs %d\n", + dev_err(dev, "SDHC Index %d exceeds Number of SDHCs %d\n", sdhc_id, nr_sdhc); return -EINVAL; } @@ -398,14 +418,37 @@ static int xenon_probe_dt(struct platform_device *pdev) if (!of_property_read_u32(np, "marvell,xenon-tun-count", &tuning_count)) { if (unlikely(tuning_count >= XENON_TMR_RETUN_NO_PRESENT)) { - dev_err(mmc_dev(mmc), "Wrong Re-tuning Count. Set default value %d\n", + dev_err(dev, "Wrong Re-tuning Count. Set default value %d\n", XENON_DEF_TUNING_COUNT); tuning_count = XENON_DEF_TUNING_COUNT; } } priv->tuning_count = tuning_count; - return xenon_phy_parse_dt(np, host); + ret = xenon_phy_parse_dt(np, host); + + reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags); + if (gpio_is_valid(reset_gpio)) { + if (flags & OF_GPIO_ACTIVE_LOW) + gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_HIGH; + else + gpio_flags = GPIOF_OUT_INIT_LOW; + + reset_name = devm_kasprintf(dev, GFP_KERNEL, "%s-reset", + dev_name(dev)); + if (!reset_name) + return -ENOMEM; + ret = devm_gpio_request_one(dev, reset_gpio, gpio_flags, + reset_name); + if (ret) { + dev_err(dev, "Failed to request reset gpio\n"); + return ret; + } + + priv->reset_gpio = gpio_to_desc(reset_gpio); + } + + return ret; } static int xenon_sdhc_prepare(struct sdhci_host *host) diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h index 73debb4..cffb0fe 100644 --- a/drivers/mmc/host/sdhci-xenon.h +++ b/drivers/mmc/host/sdhci-xenon.h @@ -90,6 +90,10 @@ struct xenon_priv { */ void *phy_params; struct xenon_emmc_phy_regs *emmc_phy_regs; + /* + * gpio pin for hw reset + */ + struct gpio_desc *reset_gpio; }; int xenon_phy_adj(struct sdhci_host *host, struct mmc_ios *ios);