From patchwork Fri Jan 16 10:47:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 5647131 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2377A9F3A0 for ; Fri, 16 Jan 2015 10:52:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3537A201C0 for ; Fri, 16 Jan 2015 10:52:14 +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 57A2620122 for ; Fri, 16 Jan 2015 10:52:13 +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 1YC4Tp-00008n-6N; Fri, 16 Jan 2015 10:50:17 +0000 Received: from mail-la0-f53.google.com ([209.85.215.53]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YC4S8-0006NW-Ik for linux-arm-kernel@lists.infradead.org; Fri, 16 Jan 2015 10:48:35 +0000 Received: by mail-la0-f53.google.com with SMTP id gm9so18279123lab.12 for ; Fri, 16 Jan 2015 02:48:10 -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=GmQYw8/AGwCkVnA+8Iz+3NkoKgHC9s4zPBdHg7Zl3Nw=; b=RXqJyv+VaMpIyJHKVvMQCnhr/toSpj6uENNvynMxjFcmF9uxsqYim8tlKtM7XqIMaD tRrNUWF7AxJ2xSSF+uz1TRWQRL/MVcDwj4SjSfxnI0ZrMGzh/nC9Prim65sUGKmZfJwl 64M43hP2alFGhky2TI0LnnBb1t3el1Wh5tBREVDW1NWHw84v8H7+RKGoZ3hpvNlb9K3r 4QqbONtYNMoP9tHgFQmubJBUs1lZSkY8c1lQQdqocihvnBzgYDMgm5ogOzYSwN/lWFTN u8wQNNo5W7w5uZHNTfcU4iIJBH3HAjkpBx3mXOs+G3zIcCaOy5ZZ0ec7DYEt2yOMTBGZ RtTA== X-Gm-Message-State: ALoCoQkqJ7pCrFXXI/MPqvd/WkAan2xrLvmawtzGG7Nleg2iXI/euUkWJKApMY2taRHdvC+KvRKy X-Received: by 10.152.2.8 with SMTP id 8mr14441725laq.97.1421405290105; Fri, 16 Jan 2015 02:48:10 -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 r5sm1363664lae.34.2015.01.16.02.48.07 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 16 Jan 2015 02:48:08 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Subject: [PATCH V3 4/4] mmc: pwrseq_simple: Add support for a reset GPIO pin Date: Fri, 16 Jan 2015 11:47:53 +0100 Message-Id: <1421405273-19117-5-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1421405273-19117-1-git-send-email-ulf.hansson@linaro.org> References: <1421405273-19117-1-git-send-email-ulf.hansson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150116_024832_843081_B6E3E828 X-CRM114-Status: GOOD ( 15.91 ) X-Spam-Score: -0.7 (/) Cc: Mark Rutland , devicetree@vger.kernel.org, Hans de Goede , Russell King , Tomeu Vizoso , 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 reset GPIOs has several times been pointed out from erlier posted patchsets. Especially some WLAN chips which are attached to an SDIO interface may use a GPIO reset. The reset GPIO is asserted at initialization and prior we start the power up procedure. The GPIO will be de-asserted right after the power has been provided to the card, from the ->post_power_on() callback. Note, the reset GPIO is optional. Thus we don't return an error even if we can't find a GPIO for the consumer. Signed-off-by: Ulf Hansson --- Changes in v3: - Updated commit message to make it clear that we support one reset GPIO. --- drivers/mmc/core/pwrseq_simple.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 7f87bc1..42d9836 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_pre_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, 1); +} + +static void mmc_pwrseq_simple_post_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 = { + .pre_power_on = mmc_pwrseq_simple_pre_power_on, + .post_power_on = mmc_pwrseq_simple_post_power_on, + .power_off = mmc_pwrseq_simple_pre_power_on, .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; }