From patchwork Thu May 5 12:34:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 9024011 Return-Path: X-Original-To: patchwork-linux-samsung-soc@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 81BCFBF29F for ; Thu, 5 May 2016 12:37:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ACB43201E4 for ; Thu, 5 May 2016 12:37:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D2062203AA for ; Thu, 5 May 2016 12:37:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756864AbcEEMfk (ORCPT ); Thu, 5 May 2016 08:35:40 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:29325 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755493AbcEEMfB (ORCPT ); Thu, 5 May 2016 08:35:01 -0400 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O6P004B8EYAGX60@mailout1.w1.samsung.com>; Thu, 05 May 2016 13:34:58 +0100 (BST) X-AuditID: cbfec7f4-f796c6d000001486-46-572b3df2948f Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 8A.B4.05254.2FD3B275; Thu, 5 May 2016 13:34:58 +0100 (BST) Received: from AMDC2174.DIGITAL.local ([106.120.53.17]) by eusync4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O6P00KEEEXN8E00@eusync4.samsung.com>; Thu, 05 May 2016 13:34:58 +0100 (BST) From: Krzysztof Kozlowski To: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-mmc@vger.kernel.org, linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, Ulf Hansson , Sebastian Reichel , Dmitry Eremin-Solenikov , David Woodhouse , Greg Kroah-Hartman , Mark Brown Cc: tjakobi@math.uni-bielefeld.de, m.szyprowski@samsung.com, hverkuil@xs4all.nl, Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [RFC v2 09/13] power: pwrseq: Add support for USB hubs with external power Date: Thu, 05 May 2016 14:34:22 +0200 Message-id: <1462451666-17945-10-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1462451666-17945-1-git-send-email-k.kozlowski@samsung.com> References: <1462451666-17945-1-git-send-email-k.kozlowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrALMWRmVeSWpSXmKPExsVy+t/xa7qfbLXDDd53ilhsnLGe1WLqwyds FpOevGe2mH/kHKvFxJWTmS2aF69nszg1+RmTxesXhhabHl9jtbi8aw6bxZH//YwWn3uPMFrM OL+PyWLRslZmi7VH7rJbnN5dYtG2+gOrxfG14Q5CHjtn3WX32LxCy2PTqk42jzvX9rB57J+7 Bii0pN7j3zF2j74tqxg9Pm+S8zj19TN7AFcUl01Kak5mWWqRvl0CV8af/SdYC9ZLVrzc+Ii1 gXGGaBcjJ4eEgInE5X99zBC2mMSFe+vZuhi5OIQEljJK9O5cyQrhNDJJNM2+zQhSxSZgLLF5 +RKwKhGBG8wSr3ZOZgZxmAV2MEr8XXaHBaRKWCBU4tK0S6wgNouAqsTHif/B4rwCHhJbWmex QOyTkzh5bDJYDSdQ/Oyv+WC2kIC7xKHf0xknMPIuYGRYxSiaWppcUJyUnmuoV5yYW1yal66X nJ+7iRES7l92MC4+ZnWIUYCDUYmH98B8rXAh1sSy4srcQ4wSHMxKIrzywGgR4k1JrKxKLcqP LyrNSS0+xCjNwaIkzjt31/sQIYH0xJLU7NTUgtQimCwTB6dUA2Pq0fhUDuYYNUm/6cVHfzSq Wp8v+e74dU3VBqE700MFjn8JjCjctzyES2BVvsbToPWsmf/63dd8UF0m/+y2P3Nn9Su7G/tU 58hueKRlJq7Bl/FklkHFGtMt3O/CNv/j6CsK8jDQY/kmq1CplFAW0OF3S0KySKr/VfdCfu83 DB090q/96rMXK7EUZyQaajEXFScCAD9NpSFzAgAA Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 Some USB devices on embedded boards have external power supply which has to be reset in certain conditions. Add pwrseq interface for this. Signed-off-by: Krzysztof Kozlowski --- drivers/power/pwrseq/pwrseq.c | 44 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pwrseq.h | 8 ++++++++ 2 files changed, 52 insertions(+) diff --git a/drivers/power/pwrseq/pwrseq.c b/drivers/power/pwrseq/pwrseq.c index 495a19d3c30b..306265f55a10 100644 --- a/drivers/power/pwrseq/pwrseq.c +++ b/drivers/power/pwrseq/pwrseq.c @@ -52,6 +52,43 @@ int mmc_pwrseq_alloc(struct mmc_host *host) } EXPORT_SYMBOL_GPL(mmc_pwrseq_alloc); +struct pwrseq *pwrseq_alloc(struct device *dev) +{ + struct device_node *np; + struct pwrseq *p, *ret = NULL; + + np = of_parse_phandle(dev->of_node, "usb-pwrseq", 0); + if (!np) + return NULL; + + mutex_lock(&pwrseq_list_mutex); + list_for_each_entry(p, &pwrseq_list, pwrseq_node) { + if (p->dev->of_node == np) { + if (!try_module_get(p->owner)) + dev_err(dev, + "increasing module refcount failed\n"); + else + ret = p; + + break; + } + } + + of_node_put(np); + mutex_unlock(&pwrseq_list_mutex); + + /* FIXME: this path can be simplified... */ + if (!ret) { + dev_info(dev, "usb-pwrseq defer\n"); + return ERR_PTR(-EPROBE_DEFER); + } + + dev_info(dev, "allocated usb-pwrseq\n"); + + return ret; +} +EXPORT_SYMBOL_GPL(pwrseq_alloc); + void pwrseq_pre_power_on(struct pwrseq *pwrseq) { if (pwrseq && pwrseq->ops->pre_power_on) @@ -84,6 +121,13 @@ void mmc_pwrseq_free(struct mmc_host *host) } EXPORT_SYMBOL_GPL(mmc_pwrseq_free); +void pwrseq_free(const struct pwrseq *pwrseq) +{ + if (pwrseq) + module_put(pwrseq->owner); +} +EXPORT_SYMBOL_GPL(pwrseq_free); + int pwrseq_register(struct pwrseq *pwrseq) { if (!pwrseq || !pwrseq->ops || !pwrseq->dev) diff --git a/include/linux/pwrseq.h b/include/linux/pwrseq.h index fcc8fd855d4c..c3c91f50e4cb 100644 --- a/include/linux/pwrseq.h +++ b/include/linux/pwrseq.h @@ -31,9 +31,13 @@ void pwrseq_unregister(struct pwrseq *pwrseq); void pwrseq_pre_power_on(struct pwrseq *pwrseq); void pwrseq_post_power_on(struct pwrseq *pwrseq); void pwrseq_power_off(struct pwrseq *pwrseq); + int mmc_pwrseq_alloc(struct mmc_host *host); void mmc_pwrseq_free(struct mmc_host *host); +struct pwrseq *pwrseq_alloc(struct device *dev); +void pwrseq_free(const struct pwrseq *pwrseq); + #else /* CONFIG_POWER_SEQ */ static inline int pwrseq_register(struct pwrseq *pwrseq) @@ -44,9 +48,13 @@ static inline void pwrseq_unregister(struct pwrseq *pwrseq) {} static inline void pwrseq_pre_power_on(struct pwrseq *pwrseq) {} static inline void pwrseq_post_power_on(struct pwrseq *pwrseq) {} static inline void pwrseq_power_off(struct pwrseq *pwrseq) {} + static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; } static inline void mmc_pwrseq_free(struct mmc_host *host) {} +static inline struct pwrseq *pwrseq_alloc(struct device *dev) { return NULL; } +static inline void pwrseq_free(const struct pwrseq *pwrseq) {} + #endif /* CONFIG_POWER_SEQ */ #endif /* _LINUX_PWRSEQ_H */