From patchwork Fri Jan 2 16:14:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 5559931 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 97399BF6C3 for ; Fri, 2 Jan 2015 16:17:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BCAA820220 for ; Fri, 2 Jan 2015 16:17:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D2AE520212 for ; Fri, 2 Jan 2015 16:17:29 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y74sj-00014D-TE; Fri, 02 Jan 2015 16:15:21 +0000 Received: from mail-la0-f51.google.com ([209.85.215.51]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y74s9-000854-9z for linux-arm-kernel@lists.infradead.org; Fri, 02 Jan 2015 16:14:46 +0000 Received: by mail-la0-f51.google.com with SMTP id ms9so15499252lab.24 for ; Fri, 02 Jan 2015 08:14:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TKiKbZONC3oPqPkCUgKYrFOWmX7lBUESzxiSw80di3w=; b=JaZNm+E8kVmdyr67wKcgKEoxe+yz/VH/Wz6bRC+gMn5bSRCgWdjZh7P5WIMVSQoXGZ SibLfRKSYsj1R1bq7s/dgnl062H62hp55n3D+TnjlBlo8XKESCzozA7FmHm3ms5ETW5u uVo0XMFA0TCNvrivBLkBihaplpJj26H+P6vMctYI2zG7Kt/YVgzZQLDkjlx0EheONrAj qNeOXFZkXviJ4s+NcC3EjZ277b6szu/27ldFezTQ/pfC/1dUBWih3ySqlDX509Oajtah jACEt66SfmNmF5920PsZsrg64nUbLTYJADivAyzjDsfFBQ6etEK6d6qj82ud/NNDePAT XQfw== X-Gm-Message-State: ALoCoQlDBCJo7z1njzkMIt2Xe4N4G3flj0/LKswaZ1Lxdkkrmq8hfZTXk4y3WOssqt0P6LzwmBMr X-Received: by 10.112.156.132 with SMTP id we4mr52554992lbb.59.1420215268649; Fri, 02 Jan 2015 08:14:28 -0800 (PST) Received: from uffe-Latitude-E6430s.lan (90-231-160-185-no158.tbcn.telia.com. [90.231.160.185]) by mx.google.com with ESMTPSA id y5sm12786551lag.7.2015.01.02.08.14.26 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 02 Jan 2015 08:14:27 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Subject: [PATCH 4/4] mmc: pwrseq_simple: Add support for a reset GPIO pin Date: Fri, 2 Jan 2015 17:14:08 +0100 Message-Id: <1420215248-20650-5-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1420215248-20650-1-git-send-email-ulf.hansson@linaro.org> References: <1420215248-20650-1-git-send-email-ulf.hansson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150102_081445_573784_6FA0F137 X-CRM114-Status: GOOD ( 16.64 ) X-Spam-Score: -0.7 (/) Cc: devicetree@vger.kernel.org, Hans de Goede , Russell King , Arnd Bergmann , Alexandre Courbot , NeilBrown , Linus Walleij , Doug Anderson , Olof Johansson , Mark Brown , Arend van Spriel , Ulf Hansson , Sascha Hauer , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 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 X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 The need for a reset GPIO has several times been pointed out from earlier posted patchsets. Especially some WLAN chips which are attached to an SDIO interface may use a GPIO reset. In this first version, one reset pin is supported. We may want to extend the support to cover more pins, but let's leave that as a future change. The added DT binding for the reset GPIO can easily be extended to manage several pins. The reset GPIO is asserted at initialization and prior we start the power up procedure. It will then be de-asserted right after the power has been provided for the external chip/card, from the ->power_on() callback. Note, the reset GPIO is optional. Thus we don't return an error even if we can't find a GPIO pin for the consumer. Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/mmc,pwrseq-simple.txt | 5 +++ drivers/mmc/core/pwrseq_simple.c | 38 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/mmc,pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc,pwrseq-simple.txt index e1b7f9c..6fe0cd6 100644 --- a/Documentation/devicetree/bindings/mmc/mmc,pwrseq-simple.txt +++ b/Documentation/devicetree/bindings/mmc/mmc,pwrseq-simple.txt @@ -11,8 +11,13 @@ for several SOC designs. Required properties: - compatible : contains "mmc,pwrseq-simple". +Optional properties: +- reset-gpios : contains a list of GPIO specifiers, though currently only one + specifier is supported. + Example: sdhci0_pwrseq { compatible = "mmc,pwrseq-simple"; + reset-gpios = <&gpio1 12 0>; } diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 7f87bc1..97112b1 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -18,31 +19,68 @@ struct mmc_pwrseq_simple { struct mmc_pwrseq pwrseq; + struct gpio_desc *reset_gpio; }; +static void mmc_pwrseq_simple_power_up(struct mmc_host *host) +{ + struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, + struct mmc_pwrseq_simple, pwrseq); + + if (!IS_ERR(pwrseq->reset_gpio)) + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); +} + +static void mmc_pwrseq_simple_power_on(struct mmc_host *host) +{ + struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, + struct mmc_pwrseq_simple, pwrseq); + + if (!IS_ERR(pwrseq->reset_gpio)) + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); +} + static void mmc_pwrseq_simple_free(struct mmc_host *host) { struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, struct mmc_pwrseq_simple, pwrseq); + if (!IS_ERR(pwrseq->reset_gpio)) + gpiod_put(pwrseq->reset_gpio); + kfree(&pwrseq); host->pwrseq = NULL; } static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { + .power_up = mmc_pwrseq_simple_power_up, + .power_on = mmc_pwrseq_simple_power_on, + .power_off = mmc_pwrseq_simple_power_up, .free = mmc_pwrseq_simple_free, }; int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev) { struct mmc_pwrseq_simple *pwrseq; + int ret = 0; pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple), GFP_KERNEL); if (!pwrseq) return -ENOMEM; + pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_HIGH); + if (IS_ERR(pwrseq->reset_gpio) && + PTR_ERR(pwrseq->reset_gpio) != -ENOENT && + PTR_ERR(pwrseq->reset_gpio) != -ENOSYS) { + ret = PTR_ERR(pwrseq->reset_gpio); + goto free; + } + pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; host->pwrseq = &pwrseq->pwrseq; return 0; +free: + kfree(&pwrseq); + return ret; }