From patchwork Mon Jan 5 11:48:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 5567111 Return-Path: X-Original-To: patchwork-linux-samsung-soc@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 67F119F357 for ; Mon, 5 Jan 2015 11:51:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 701D720166 for ; Mon, 5 Jan 2015 11:51:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5C4832014A for ; Mon, 5 Jan 2015 11:51:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753130AbbAELux (ORCPT ); Mon, 5 Jan 2015 06:50:53 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:50307 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753287AbbAELuv (ORCPT ); Mon, 5 Jan 2015 06:50:51 -0500 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NHP00L9XD3HV580@mailout2.w1.samsung.com>; Mon, 05 Jan 2015 11:54:53 +0000 (GMT) X-AuditID: cbfec7f4-b7f126d000001e9a-77-54aa7a98f38f Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 49.65.07834.89A7AA45; Mon, 05 Jan 2015 11:50:48 +0000 (GMT) Received: from AMDC1943.digital.local ([106.116.151.171]) by eusync1.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NHP00IYMCWKJI90@eusync1.samsung.com>; Mon, 05 Jan 2015 11:50:48 +0000 (GMT) From: Krzysztof Kozlowski To: Liam Girdwood , Mark Brown , linux-kernel@vger.kernel.org, Kukjin Kim , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org Cc: Kyungmin Park , Bartlomiej Zolnierkiewicz , Krzysztof Kozlowski Subject: [PATCH v5 2/5] regulator: Allow parsing custom properties when using simplified DT parsing Date: Mon, 05 Jan 2015 12:48:42 +0100 Message-id: <1420458525-22576-3-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1420458525-22576-1-git-send-email-k.kozlowski@samsung.com> References: <1420458525-22576-1-git-send-email-k.kozlowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmplluLIzCtJLcpLzFFi42I5/e/4Zd0ZVatCDA6uVrLYOGM9q8XUh0/Y LOYfOcdq8fqFoUX/49fMFmeb3rBbfLvSwWSx6fE1VovLu+awWcw4v4/Jgctj56y77B6bVnWy eWxeUu/Rt2UVo8fnTXIBrFFcNimpOZllqUX6dglcGe/uXmMuWKBScWzJZZYGxvcyXYycHBIC JhKLmnazQNhiEhfurWfrYuTiEBJYyiixZvomJginj0niwrxd7CBVbALGEpuXLwGrEhH4wCix atIPVhCHWWAao8SFU9+ZQaqEBVIl5jxrYAKxWQRUJb4evQO2g1fAXWLGr+lQ++QkTh6bzApi cwp4SHQ9/QTWKwRUM21nM/MERt4FjAyrGEVTS5MLipPScw31ihNzi0vz0vWS83M3MUKC7ssO xsXHrA4xCnAwKvHwepxYGSLEmlhWXJl7iFGCg1lJhPdV+qoQId6UxMqq1KL8+KLSnNTiQ4xM HJxSDYzpE7d4Ff3RF12wQ9k7Yt479RztTU8MnrPGnYh19/JQ+vP50VG2ymiW2kr7qem10TuP z3jKnetkkmrkll7Alj5tj9KjlUw/mPZ63BZ3yOy0vJTaM1Hqa/5yu5DD7Jq6MrzvF/5lY5eY uOG99NqKy1J+qlya3kZ+IvcZd26wiJ0W3vBpnqdutRJLcUaioRZzUXEiADqjsxUYAgAA 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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 When drivers use simplified DT parsing method (they provide 'regulator_desc.of_match') they still may want to parse custom properties for some of the regulators. For example some of the regulators support GPIO enable control. Add a driver-supplied callback for such case. This way the regulator core parses common bindings offloading a lot of code from drivers and still custom properties may be used. The callback, called for each parsed regulator, may modify the 'regulator_config' initially passed to regulator_register(). Signed-off-by: Krzysztof Kozlowski --- drivers/regulator/core.c | 2 +- drivers/regulator/internal.h | 2 ++ drivers/regulator/of_regulator.c | 11 +++++++++++ include/linux/regulator/driver.h | 13 +++++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c13b557a560e..5fae8cabd254 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3635,7 +3635,7 @@ regulator_register(const struct regulator_desc *regulator_desc, return ERR_PTR(-ENOMEM); } - init_data = regulator_of_get_init_data(dev, regulator_desc, + init_data = regulator_of_get_init_data(dev, regulator_desc, config, &rdev->dev.of_node); if (!init_data) { init_data = config->init_data; diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 80ba2a35a04b..c74ac8734023 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -38,11 +38,13 @@ struct regulator { #ifdef CONFIG_OF struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node); #else static inline struct regulator_init_data * regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node) { return NULL; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 91eaaf010524..24e812c48d93 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match); struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node) { struct device_node *search, *child; @@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, break; } + if (desc->of_parse_cb) { + if (desc->of_parse_cb(child, desc, config)) { + dev_err(dev, + "driver callback failed to parse DT for regulator %s\n", + child->name); + init_data = NULL; + break; + } + } + of_node_get(child); *node = child; break; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 5f1e9ca47417..d4ad5b5a02bb 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -21,6 +21,7 @@ struct regmap; struct regulator_dev; +struct regulator_config; struct regulator_init_data; struct regulator_enable_gpio; @@ -205,6 +206,15 @@ enum regulator_type { * @supply_name: Identifying the regulator supply * @of_match: Name used to identify regulator in DT. * @regulators_node: Name of node containing regulator definitions in DT. + * @of_parse_cb: Optional callback called only if of_match is present. + * Will be called for each regulator parsed from DT, during + * init_data parsing. + * The regulator_config passed as argument to the callback will + * be a copy of config passed to regulator_register, valid only + * for this particular call. Callback may freely change the + * config but it cannot store it for later usage. + * Callback should return 0 on success or negative ERRNO + * indicating failure. * @id: Numerical identifier for the regulator. * @ops: Regulator operations table. * @irq: Interrupt number for the regulator. @@ -251,6 +261,9 @@ struct regulator_desc { const char *supply_name; const char *of_match; const char *regulators_node; + int (*of_parse_cb)(struct device_node *, + const struct regulator_desc *, + struct regulator_config *); int id; bool continuous_voltage_range; unsigned n_voltages;