From patchwork Thu Jun 9 09:44:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 9166655 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 0BA6660832 for ; Thu, 9 Jun 2016 09:53:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF6D228047 for ; Thu, 9 Jun 2016 09:53:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E442A28338; Thu, 9 Jun 2016 09:53:06 +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=unavailable 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 61A2928328 for ; Thu, 9 Jun 2016 09:53:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161784AbcFIJwT (ORCPT ); Thu, 9 Jun 2016 05:52:19 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:27334 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932820AbcFIJo4 (ORCPT ); Thu, 9 Jun 2016 05:44:56 -0400 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O8I001SF0ENCH70@mailout3.w1.samsung.com>; Thu, 09 Jun 2016 10:44:47 +0100 (BST) X-AuditID: cbfec7f5-f792a6d000001302-19-57593a8e89c3 Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 4D.F4.04866.E8A39575; Thu, 9 Jun 2016 10:44:46 +0100 (BST) Received: from AMDC2174.DIGITAL.local ([106.120.53.17]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O8I006RA0EHZZ10@eusync1.samsung.com>; Thu, 09 Jun 2016 10:44:46 +0100 (BST) From: Krzysztof Kozlowski To: Ulf Hansson , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Krzysztof Kozlowski , Sebastian Reichel , Dmitry Eremin-Solenikov , David Woodhouse , Liam Girdwood , Mark Brown , Greg Kroah-Hartman , Hans de Goede , Jean-Christophe Plagniol-Villard , Tomi Valkeinen , Heiko Stuebner , linux-mmc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, hzpeterchen@gmail.com Cc: Bartlomiej Zolnierkiewicz Subject: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Date: Thu, 09 Jun 2016 11:44:18 +0200 Message-id: <1465465471-28740-2-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1465465471-28740-1-git-send-email-k.kozlowski@samsung.com> References: <1465465471-28740-1-git-send-email-k.kozlowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCIsWRmVeSWpSXmKPExsVy+t/xy7r9VpHhBl+5LDbOWM9qMfXhEzaL SU/eM1vMP3KO1WLiysnMFv1vFrJaNC9ez2bx5vh0Jov/j16zWnRd3cRmce7VSkaL1y8MLb5d 6WCy2PT4GqvFib4PrBaXd81hszjyv5/R4nPvEUaLGef3MVksWtbKbLH0+kUmiwnT17JYrHv4 gsmide8RdovTu0ss1s+/xWZxfG24g7THmnlrGD0u9/UyeeycdZfdY+XyL2wem1doeby6cIfF Y9OqTjaPO9f2sHnsn7uG3WPzknqP9/uusnn0bVnF6LH92jxmj+M3tjN5fN4kF8AfxWWTkpqT WZZapG+XwJXxbSJ/wQKlih9vmlgbGKdJdzFyckgImEgcOrmRFcIWk7hwbz1bFyMXh5DAUkaJ iTOns0I4jUwS199/ZgOpYhMwlti8fAlYlYjAJXaJG5e2M4EkmAUsJLZuXc0OYgsLeElsfbYc rIFFQFVi3p/vYDavgLvE44Yd7BDr5CROHpsMtppTwEPi0b3HzCC2EFDN3sWT2SYw8i5gZFjF KJpamlxQnJSea6RXnJhbXJqXrpecn7uJERJ3X3cwLj1mdYhRgINRiYdXIyUiXIg1say4MvcQ owQHs5II7w/zyHAh3pTEyqrUovz4otKc1OJDjNIcLErivDN3vQ8REkhPLEnNTk0tSC2CyTJx cEo1MM498JVh/wXZ3wfuvO0rT63cOeu/+u5s23KOH3bbJY3Wcjz23hqupx/0baVx5RJxh7LE E7KmC7vj5x9WXrWRy0Ti8UtlJctOVpPozDMihqINueUPuR5vjgz8MS9y5ex9pnbTj29onBiw YIasyMxbFRucg7tnSmvdz9ty963wDt7kRI8mZp4obyWW4oxEQy3mouJEAB7+VwW3AgAA Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Few drivers have a need of getting regulator supplies without knowing their names: 1. The Simple Framebuffer driver works on setup provided by bootloader (outside of scope of kernel); 2. Generic power sequence driver may be attached to any device node. Add a Device Tree helper for parsing "-supply" properties and returning allocated bulk regulator consumers. Signed-off-by: Krzysztof Kozlowski --- drivers/regulator/of_regulator.c | 86 ++++++++++++++++++++++++++++++++++ include/linux/regulator/of_regulator.h | 13 +++++ 2 files changed, 99 insertions(+) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index cd828dbf9d52..0d2c8dd0ebc0 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -350,3 +350,89 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, return init_data; } + +/** + * devm_of_regulator_all_get - get all regulator consumers + * + * @dev: Device to supply + * @num_consumers Number of consumers registered (only on success) + * @consumers: Configuration of consumers; names of supplies and clients + * are stored here; allocated only on success (NULL otherwise); + * + * @return 0 on success, an errno on failure. + * + * This helper function allows drivers to get all regulator consumers + * for given device in one operation. The names of regulator supplies + * do not have to be provided. If any of the regulators cannot be + * acquired then any regulators that were allocated will be freed + * before returning to the caller. + */ +int devm_of_regulator_all_get(struct device *dev, unsigned int *num_consumers, + struct regulator_bulk_data **consumers) +{ + struct device_node *np = dev->of_node; + struct regulator_bulk_data *bulk; + unsigned int count = 0, i = 0; + struct property *prop; + const char *p; + int ret; + + if (!np) { + ret = 0; + goto err; /* Not really an error */ + } + + /* Count the number of regulator supplies */ + for_each_property_of_node(np, prop) { + p = strstr(prop->name, "-supply"); + if (p && p != prop->name) + count++; + } + + if (!count) { + ret = 0; + goto err; /* Not really an error */ + } + + bulk = devm_kcalloc(dev, count, sizeof(**consumers), GFP_KERNEL); + if (!bulk) { + ret = -ENOMEM; + goto err; + } + + /* Get all the names for supplies */ + for_each_property_of_node(np, prop) { + char *name; + int len; + + p = strstr(prop->name, "-supply"); + if (!p || p == prop->name) + continue; + + len = strlen(prop->name) - strlen("-supply") + 1; + name = devm_kzalloc(dev, len, GFP_KERNEL); + if (!name) { + ret = -ENOMEM; + goto err; + } + + strlcpy(name, prop->name, len); + bulk[i++].supply = name; + } + + ret = devm_regulator_bulk_get(dev, i, bulk); + if (ret) + goto err; + + *consumers = bulk; + *num_consumers = i; + + return 0; + +err: + *num_consumers = 0; + *consumers = NULL; + + return ret; +} +EXPORT_SYMBOL_GPL(devm_of_regulator_all_get); diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h index 763953f7e3b8..93a3b7fe92e8 100644 --- a/include/linux/regulator/of_regulator.h +++ b/include/linux/regulator/of_regulator.h @@ -7,6 +7,7 @@ #define __LINUX_OF_REG_H struct regulator_desc; +struct regulator_bulk_data; struct of_regulator_match { const char *name; @@ -24,6 +25,9 @@ extern struct regulator_init_data extern int of_regulator_match(struct device *dev, struct device_node *node, struct of_regulator_match *matches, unsigned int num_matches); +extern int devm_of_regulator_all_get(struct device *dev, + unsigned int *num_consumers, + struct regulator_bulk_data **consumers); #else static inline struct regulator_init_data *of_get_regulator_init_data(struct device *dev, @@ -40,6 +44,15 @@ static inline int of_regulator_match(struct device *dev, { return 0; } +static inline int devm_of_regulator_all_get(struct device *dev, + unsigned int *num_consumers, + struct regulator_bulk_data **consumers) +{ + *num_consumers = 0; + *consumers = NULL; + + return 0; +} #endif /* CONFIG_OF */ #endif /* __LINUX_OF_REG_H */