From patchwork Fri Oct 5 15:36:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628337 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 29D5A933 for ; Fri, 5 Oct 2018 15:39:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 207BC2978A for ; Fri, 5 Oct 2018 15:39:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1501229798; Fri, 5 Oct 2018 15:39:18 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 57FBA2978A for ; Fri, 5 Oct 2018 15:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729001AbeJEWhM (ORCPT ); Fri, 5 Oct 2018 18:37:12 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:37093 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728411AbeJEWhL (ORCPT ); Fri, 5 Oct 2018 18:37:11 -0400 Received: by mail-lj1-f196.google.com with SMTP id 63-v6so12016757ljs.4; Fri, 05 Oct 2018 08:37:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lU0m4dcxkmldXRenrk9EE1odt3YDCqwjd90AyKmVxsA=; b=J1Vq09w/dRr5xEjam4Pr1v9UtnlBzcl1CwhmWK2LQISNYjI8IyEnK9LD+9Roh2n6yA RwF4EOeZ/stN64NVY8JLG7E6N7WEqVvcGliou0zCI+VFbiQJ2LFM6ujIpEb68FdF1BCG xwctbBJb0qZUaUpzDEjrSrAj5s22obWRjrjEXdcA2zQgDRbiXwG106PbYEcjTZl197LY p82ojaZg8GHtJ7fdcx1Fy/ddVUm2jvT5TDRCcOwGwcdEID193LG64RQFZlFfgBIabUxD 17YWIZ/2pDcs618kgrUqpEvs/xoCWFpMHnQ1NFfn3LI0WMTuQ6LKADr0auvK/imaFoEA WiRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lU0m4dcxkmldXRenrk9EE1odt3YDCqwjd90AyKmVxsA=; b=WbnT4ZzGFvf5CZX+k+Kg1HIaxwC6CVH8SUpTLkYqJXc2gEuOhekR4t3xlm7rSJRWNh /2xxi7nLdC/MYVSi37TW0R4PLXVD3euEUuZvvDgwOph736wPXQwFRSESzIdVYBLUUjcv W6QeGZ+V/vhRoWYMhD5c3L3BvDSNTfviTXqi/anxKbGLbwDhkwUxhGE40I48YB2LZJMf I3xd/YGEtb7OnKO3vVMxr8hLyS1s7R3Mpbr/iPWr/1uejacZGHEYJskFooeuIiutmwRa 2kTHNsImXSzyR9BflTbJENqeNmwMIpsFQY+H9WF02Rinlpn//7l4+711Jxw/qPc/hsO6 4UVw== X-Gm-Message-State: ABuFfojhOOY/hetAMxwSr/Ir6y18ikDYMa1i910mhSBWZQ+CrLFz0hRe zn1fqDqXejEjfF+WYg4TwfI= X-Google-Smtp-Source: ACcGV61LHz6eImyJzoCI+1KqMSL6RxiuPCOFZfDYcd1WX/zr3s4QjO84DO2czBRtfy+CKpP5mM2vHQ== X-Received: by 2002:a2e:99d3:: with SMTP id l19-v6mr2089413ljj.132.1538753873872; Fri, 05 Oct 2018 08:37:53 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:53 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 01/11] regulator: core: Add voltage balancing mechanism Date: Fri, 5 Oct 2018 18:36:28 +0300 Message-Id: <20181005153638.1886-2-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Maciej Purski On Odroid XU3/4 and other Exynos5422 based boards there is a case, that different devices on the board are supplied by different regulators with non-fixed voltages. If one of these devices temporarily requires higher voltage, there might occur a situation that the spread between two devices' voltages is so high, that there is a risk of changing 'high' and 'low' states on the interconnection between devices powered by those regulators. Introduce new function regulator_balance_voltage(), which keeps max_spread constraint fulfilled between a group of coupled regulators. It should be called if a regulator changes its voltage or after disabling or enabling. Disabled regulators should follow changes of the enabled ones, but their consumers' demands shouldn't be taken into account while calculating voltage of other coupled regulators. Find voltages, which are closest to suiting all the consumers' demands, while fulfilling max_spread constraint, keeping the following rules: - if one regulator is about to rise its voltage, rise others voltages in order to keep the max_spread - if a regulator, which has caused rising other regulators, is lowered, lower other regulators if possible - if one regulator is about to lower its voltage, but it hasn't caused rising other regulators, change its voltage so that it doesn't break the max_spread Change regulators' voltages step by step, keeping max_spread constraint fulfilled all the time. Function regulator_get_optimal_voltage() should find the best possible change for the regulator, which doesn't break max_spread constraint. In function regulator_balance_voltage() optimize number of steps by finding highest voltage difference on each iteration. If a regulator, which is about to change its voltage, is not coupled, method regulator_get_optimal_voltage() should simply return the lowest voltage fulfilling consumers' demands. Coupling should be checked only if the system is in PM_SUSPEND_ON state. Signed-off-by: Maciej Purski Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 229 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2c66b528aede..a2a513780fd7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -105,6 +105,8 @@ static int _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV); +static int regulator_balance_voltage(struct regulator_dev *rdev, + suspend_state_t state); static struct regulator *create_regulator(struct regulator_dev *rdev, struct device *dev, const char *supply_name); @@ -3126,6 +3128,233 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, return ret; } +static int regulator_get_optimal_voltage(struct regulator_dev *rdev, + int *current_uV, + int *min_uV, int *max_uV, + suspend_state_t state, + int n_coupled) +{ + struct coupling_desc *c_desc = &rdev->coupling_desc; + struct regulator_dev **c_rdevs = c_desc->coupled_rdevs; + struct regulation_constraints *constraints = rdev->constraints; + int max_spread = constraints->max_spread; + int desired_min_uV = 0, desired_max_uV = INT_MAX; + int max_current_uV = 0, min_current_uV = INT_MAX; + int highest_min_uV = 0, target_uV, possible_uV; + int i, ret; + bool done; + + *current_uV = -1; + + /* + * If there are no coupled regulators, simply set the voltage + * demanded by consumers. + */ + if (n_coupled == 1) { + /* + * If consumers don't provide any demands, set voltage + * to min_uV + */ + desired_min_uV = constraints->min_uV; + desired_max_uV = constraints->max_uV; + + ret = regulator_check_consumers(rdev, + &desired_min_uV, + &desired_max_uV, state); + if (ret < 0) + return ret; + + possible_uV = desired_min_uV; + done = true; + + goto finish; + } + + /* Find highest min desired voltage */ + for (i = 0; i < n_coupled; i++) { + int tmp_min = 0; + int tmp_max = INT_MAX; + + lockdep_assert_held_once(&c_rdevs[i]->mutex); + + ret = regulator_check_consumers(c_rdevs[i], + &tmp_min, + &tmp_max, state); + if (ret < 0) + return ret; + + ret = regulator_check_voltage(c_rdevs[i], &tmp_min, &tmp_max); + if (ret < 0) + return ret; + + highest_min_uV = max(highest_min_uV, tmp_min); + + if (i == 0) { + desired_min_uV = tmp_min; + desired_max_uV = tmp_max; + } + } + + /* + * Let target_uV be equal to the desired one if possible. + * If not, set it to minimum voltage, allowed by other coupled + * regulators. + */ + target_uV = max(desired_min_uV, highest_min_uV - max_spread); + + /* + * Find min and max voltages, which currently aren't violating + * max_spread. + */ + for (i = 1; i < n_coupled; i++) { + int tmp_act; + + if (!_regulator_is_enabled(c_rdevs[i])) + continue; + + tmp_act = _regulator_get_voltage(c_rdevs[i]); + if (tmp_act < 0) + return tmp_act; + + min_current_uV = min(tmp_act, min_current_uV); + max_current_uV = max(tmp_act, max_current_uV); + } + + /* There aren't any other regulators enabled */ + if (max_current_uV == 0) { + possible_uV = target_uV; + } else { + /* + * Correct target voltage, so as it currently isn't + * violating max_spread + */ + possible_uV = max(target_uV, max_current_uV - max_spread); + possible_uV = min(possible_uV, min_current_uV + max_spread); + } + + if (possible_uV > desired_max_uV) + return -EINVAL; + + done = (possible_uV == target_uV); + desired_min_uV = possible_uV; + +finish: + /* Set current_uV if wasn't done earlier in the code and if necessary */ + if (n_coupled > 1 && *current_uV == -1) { + + if (_regulator_is_enabled(rdev)) { + ret = _regulator_get_voltage(rdev); + if (ret < 0) + return ret; + + *current_uV = ret; + } else { + *current_uV = desired_min_uV; + } + } + + *min_uV = desired_min_uV; + *max_uV = desired_max_uV; + + return done; +} + +static int regulator_balance_voltage(struct regulator_dev *rdev, + suspend_state_t state) +{ + struct regulator_dev **c_rdevs; + struct regulator_dev *best_rdev; + struct coupling_desc *c_desc = &rdev->coupling_desc; + int i, ret, n_coupled, best_min_uV, best_max_uV, best_c_rdev; + bool best_c_rdev_done, c_rdev_done[MAX_COUPLED]; + unsigned int delta, best_delta; + + c_rdevs = c_desc->coupled_rdevs; + n_coupled = c_desc->n_coupled; + + /* + * If system is in a state other than PM_SUSPEND_ON, don't check + * other coupled regulators. + */ + if (state != PM_SUSPEND_ON) + n_coupled = 1; + + if (c_desc->n_resolved < n_coupled) { + rdev_err(rdev, "Not all coupled regulators registered\n"); + return -EPERM; + } + + for (i = 0; i < n_coupled; i++) + c_rdev_done[i] = false; + + /* + * Find the best possible voltage change on each loop. Leave the loop + * if there isn't any possible change. + */ + do { + best_c_rdev_done = false; + best_delta = 0; + best_min_uV = 0; + best_max_uV = 0; + best_c_rdev = 0; + best_rdev = NULL; + + /* + * Find highest difference between optimal voltage + * and current voltage. + */ + for (i = 0; i < n_coupled; i++) { + /* + * optimal_uV is the best voltage that can be set for + * i-th regulator at the moment without violating + * max_spread constraint in order to balance + * the coupled voltages. + */ + int optimal_uV = 0, optimal_max_uV = 0, current_uV = 0; + + if (c_rdev_done[i]) + continue; + + ret = regulator_get_optimal_voltage(c_rdevs[i], + ¤t_uV, + &optimal_uV, + &optimal_max_uV, + state, n_coupled); + if (ret < 0) + goto out; + + delta = abs(optimal_uV - current_uV); + + if (delta && best_delta <= delta) { + best_c_rdev_done = ret; + best_delta = delta; + best_rdev = c_rdevs[i]; + best_min_uV = optimal_uV; + best_max_uV = optimal_max_uV; + best_c_rdev = i; + } + } + + /* Nothing to change, return successfully */ + if (!best_rdev) { + ret = 0; + goto out; + } +#if 0 + ret = regulator_set_voltage_rdev(best_rdev, best_min_uV, + best_max_uV, state); +#endif + if (ret < 0) + goto out; + + c_rdev_done[best_c_rdev] = best_c_rdev_done; + + } while (n_coupled > 1); + +out: + return ret; +} + /** * regulator_set_voltage - set regulator output voltage * @regulator: regulator source From patchwork Fri Oct 5 15:36:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C666933 for ; Fri, 5 Oct 2018 15:39:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 02FE729797 for ; Fri, 5 Oct 2018 15:39:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EB69129798; Fri, 5 Oct 2018 15:39:18 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 2F0AC29799 for ; Fri, 5 Oct 2018 15:39:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728991AbeJEWhM (ORCPT ); Fri, 5 Oct 2018 18:37:12 -0400 Received: from mail-lf1-f67.google.com ([209.85.167.67]:37200 "EHLO mail-lf1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728906AbeJEWhL (ORCPT ); Fri, 5 Oct 2018 18:37:11 -0400 Received: by mail-lf1-f67.google.com with SMTP id a82-v6so9672189lfa.4; Fri, 05 Oct 2018 08:37:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FdUkeSjiaiJwF8K+QGC+weaHs0MXhzDTELNH8Q0WqMo=; b=Y44eH0w2mnpCITqqApZac0ub6AkWeU4Ubf43qxkyAd6mUHmV43X8B9sSafaSu0YUrd HbcwI3UrnWbrA+Ca56pXzwg0/zqenf/m0MqY0LlbprPKwmkF+IJFpSLomtpLi6xTKnAa /9WjhAiCLY6JStlr/tqHAF2T2Yyd3jhG9Cyf3gzIBS1Fyfmsi+hfuPVeOIuNnGgtZAcz B1r8WLxNynV7CTq6HpcvaO2rMyD9ua0FNdU1eu03rV7wwPnIMxvk8aoHB4pHOIrtvjTN h327/rxGmb66DW8raJL3FArPL+CKaoxP6gOuvIaSH4TkXDPfYkFuRcWVBN8WN7lmPtg8 RnZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FdUkeSjiaiJwF8K+QGC+weaHs0MXhzDTELNH8Q0WqMo=; b=svaoFKwDu89PXUsuBUaxVVimO1qK1hcVDroed7LfkvW/Z0K2ERsVdiGlfkhAxSasBL zFBXJX8GxTCh+pGU/ilFUbZdjpaungl8mxgzjaHBZoN2jodIOO4NlmIQ7WVghV9WVTvH vieta/Z+2qvMAcjJ56Mdz/L5Eor2RH17kjVcoGprsA3AcD8KNSlvCZOqtt23HBACJJyJ gyKn777bFPluD74T8AcnytUHzQPjccDXpEvk7rtKCQLOX6Zvet40Z72rpnV3pQ+oxKdc m1NM//zcuCsrvLdkniKpqVQXx5y6yAWpK2j+6HXtPAAIX1v4Ne/agFqQj/XWHbI8lI0N sJ9A== X-Gm-Message-State: ABuFfojzssfGP72UMNqQfJKxbnx5boLGErPp16BpU52aCgq/j4l1ZbER GTd165V0WS3kC2A7jkAYHoA= X-Google-Smtp-Source: ACcGV62SPuTiYB3ucXCSKhzqasjrqNeooUixrKFjMr++qA8NKwUjGnu3ABYDGz6htQcDBwAnO5wpgw== X-Received: by 2002:a19:645e:: with SMTP id b30-v6mr7009127lfj.5.1538753874945; Fri, 05 Oct 2018 08:37:54 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:54 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 02/11] regulator: core: Change voltage setting path Date: Fri, 5 Oct 2018 18:36:29 +0300 Message-Id: <20181005153638.1886-3-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Maciej Purski On Odroid XU3/4 and other Exynos5422 based boards there is a case, that different devices on the board are supplied by different regulators with non-fixed voltages. If one of these devices temporarily requires higher voltage, there might occur a situation that the spread between two devices' voltages is so high, that there is a risk of changing 'high' and 'low' states on the interconnection between devices powered by those regulators. Uncoupled regulators should be a special case of coupled regulators, so they should share a common voltage setting path. When enabling, disabling or setting voltage of a coupled regulator, all coupled regulators should be locked. Regulator's supplies should be locked, when setting voltage of a single regulator. Enabling a coupled regulator or setting its voltage should not be possible if some of its coupled regulators, has not been registered. Add function for locking coupled regulators and supplies. Extract a new function regulator_set_voltage_rdev() from regulator_set_voltage_unlocked(), which is called when setting voltage of a single regulator. Signed-off-by: Maciej Purski Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 145 ++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 46 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a2a513780fd7..5105eaaf3cef 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -107,6 +107,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV); static int regulator_balance_voltage(struct regulator_dev *rdev, suspend_state_t state); +static int regulator_set_voltage_rdev(struct regulator_dev *rdev, + int min_uV, int max_uV, + suspend_state_t state); static struct regulator *create_regulator(struct regulator_dev *rdev, struct device *dev, const char *supply_name); @@ -198,37 +201,66 @@ static void regulator_unlock(struct regulator_dev *rdev) } } -/** - * regulator_lock_supply - lock a regulator and its supplies - * @rdev: regulator source - */ -static void regulator_lock_supply(struct regulator_dev *rdev) +static int regulator_lock_recursive(struct regulator_dev *rdev, + unsigned int subclass) { + struct regulator_dev *c_rdev; int i; - for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++) - regulator_lock_nested(rdev, i); + for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { + c_rdev = rdev->coupling_desc.coupled_rdevs[i]; + + if (!c_rdev) + continue; + + regulator_lock_nested(c_rdev, subclass++); + + if (c_rdev->supply) + subclass = + regulator_lock_recursive(c_rdev->supply->rdev, + subclass); + } + + return subclass; } /** - * regulator_unlock_supply - unlock a regulator and its supplies - * @rdev: regulator source + * regulator_unlock_dependent - unlock regulator's suppliers and coupled + * regulators + * @rdev: regulator source + * + * Unlock all regulators related with rdev by coupling or suppling. */ -static void regulator_unlock_supply(struct regulator_dev *rdev) +static void regulator_unlock_dependent(struct regulator_dev *rdev) { - struct regulator *supply; + struct regulator_dev *c_rdev; + int i; - while (1) { - regulator_unlock(rdev); - supply = rdev->supply; + for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { + c_rdev = rdev->coupling_desc.coupled_rdevs[i]; - if (!rdev->supply) - return; + if (!c_rdev) + continue; - rdev = supply->rdev; + regulator_unlock(c_rdev); + + if (c_rdev->supply) + regulator_unlock_dependent(c_rdev->supply->rdev); } } +/** + * regulator_lock_dependent - lock regulator's suppliers and coupled regulators + * @rdev: regulator source + * + * This function as a wrapper on regulator_lock_recursive(), which locks + * all regulators related with rdev by coupling or suppling. + */ +static inline void regulator_lock_dependent(struct regulator_dev *rdev) +{ + regulator_lock_recursive(rdev, 0); +} + /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device @@ -2289,9 +2321,16 @@ int regulator_enable(struct regulator *regulator) return ret; } - mutex_lock(&rdev->mutex); + regulator_lock_dependent(rdev); + /* balance only if there are regulators coupled */ + if (rdev->coupling_desc.n_coupled > 1) { + ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); + if (ret != 0) + goto unlock; + } ret = _regulator_enable(rdev); - mutex_unlock(&rdev->mutex); +unlock: + regulator_unlock_dependent(rdev); if (ret != 0 && rdev->supply) regulator_disable(rdev->supply); @@ -2397,9 +2436,11 @@ int regulator_disable(struct regulator *regulator) if (regulator->always_on) return 0; - mutex_lock(&rdev->mutex); + regulator_lock_dependent(rdev); ret = _regulator_disable(rdev); - mutex_unlock(&rdev->mutex); + if (rdev->coupling_desc.n_coupled > 1) + regulator_balance_voltage(rdev, PM_SUSPEND_ON); + regulator_unlock_dependent(rdev); if (ret == 0 && rdev->supply) regulator_disable(rdev->supply); @@ -2448,10 +2489,12 @@ int regulator_force_disable(struct regulator *regulator) struct regulator_dev *rdev = regulator->rdev; int ret; - mutex_lock(&rdev->mutex); + regulator_lock_dependent(rdev); regulator->uA_load = 0; ret = _regulator_force_disable(regulator->rdev); - mutex_unlock(&rdev->mutex); + if (rdev->coupling_desc.n_coupled > 1) + regulator_balance_voltage(rdev, PM_SUSPEND_ON); + regulator_unlock_dependent(rdev); if (rdev->supply) while (rdev->open_count--) @@ -2599,9 +2642,9 @@ int regulator_is_enabled(struct regulator *regulator) if (regulator->always_on) return 1; - mutex_lock(®ulator->rdev->mutex); + regulator_lock_dependent(regulator->rdev); ret = _regulator_is_enabled(regulator->rdev); - mutex_unlock(®ulator->rdev->mutex); + regulator_unlock_dependent(regulator->rdev); return ret; } @@ -3015,8 +3058,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, int ret = 0; int old_min_uV, old_max_uV; int current_uV; - int best_supply_uV = 0; - int supply_change_uV = 0; /* If we're setting the same range as last time the change * should be a noop (some cpufreq implementations use the same @@ -3056,10 +3097,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, voltage->min_uV = min_uV; voltage->max_uV = max_uV; - ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state); + /* for not coupled regulators this will just set the voltage */ + ret = regulator_balance_voltage(rdev, state); if (ret < 0) goto out2; +out: + return 0; +out2: + voltage->min_uV = old_min_uV; + voltage->max_uV = old_max_uV; + + return ret; +} + +static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV, + int max_uV, suspend_state_t state) +{ + int best_supply_uV = 0; + int supply_change_uV = 0; + int ret; + if (rdev->supply && regulator_ops_is_valid(rdev->supply->rdev, REGULATOR_CHANGE_VOLTAGE) && @@ -3071,13 +3129,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, selector = regulator_map_voltage(rdev, min_uV, max_uV); if (selector < 0) { ret = selector; - goto out2; + goto out; } best_supply_uV = _regulator_list_voltage(rdev, selector, 0); if (best_supply_uV < 0) { ret = best_supply_uV; - goto out2; + goto out; } best_supply_uV += rdev->desc->min_dropout_uV; @@ -3085,7 +3143,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, current_supply_uV = _regulator_get_voltage(rdev->supply->rdev); if (current_supply_uV < 0) { ret = current_supply_uV; - goto out2; + goto out; } supply_change_uV = best_supply_uV - current_supply_uV; @@ -3097,7 +3155,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (ret) { dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", ret); - goto out2; + goto out; } } @@ -3107,7 +3165,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ret = _regulator_do_set_suspend_voltage(rdev, min_uV, max_uV, state); if (ret < 0) - goto out2; + goto out; if (supply_change_uV < 0) { ret = regulator_set_voltage_unlocked(rdev->supply, @@ -3120,11 +3178,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, } out: - return ret; -out2: - voltage->min_uV = old_min_uV; - voltage->max_uV = old_max_uV; - return ret; } @@ -3340,10 +3393,10 @@ static int regulator_balance_voltage(struct regulator_dev *rdev, ret = 0; goto out; } -#if 0 + ret = regulator_set_voltage_rdev(best_rdev, best_min_uV, best_max_uV, state); -#endif + if (ret < 0) goto out; @@ -3377,12 +3430,12 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) { int ret = 0; - regulator_lock_supply(regulator->rdev); + regulator_lock_dependent(regulator->rdev); ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, PM_SUSPEND_ON); - regulator_unlock_supply(regulator->rdev); + regulator_unlock_dependent(regulator->rdev); return ret; } @@ -3460,12 +3513,12 @@ int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, if (regulator_check_states(state) || state == PM_SUSPEND_ON) return -EINVAL; - regulator_lock_supply(regulator->rdev); + regulator_lock_dependent(regulator->rdev); ret = _regulator_set_suspend_voltage(regulator, min_uV, max_uV, state); - regulator_unlock_supply(regulator->rdev); + regulator_unlock_dependent(regulator->rdev); return ret; } @@ -3657,11 +3710,11 @@ int regulator_get_voltage(struct regulator *regulator) { int ret; - regulator_lock_supply(regulator->rdev); + regulator_lock_dependent(regulator->rdev); ret = _regulator_get_voltage(regulator->rdev); - regulator_unlock_supply(regulator->rdev); + regulator_unlock_dependent(regulator->rdev); return ret; } From patchwork Fri Oct 5 15:36:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6B95D112B for ; Fri, 5 Oct 2018 15:39:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62A822978A for ; Fri, 5 Oct 2018 15:39:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5726829798; Fri, 5 Oct 2018 15:39:05 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 E99912978A for ; Fri, 5 Oct 2018 15:39:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729083AbeJEWhO (ORCPT ); Fri, 5 Oct 2018 18:37:14 -0400 Received: from mail-lj1-f194.google.com ([209.85.208.194]:45105 "EHLO mail-lj1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728562AbeJEWhN (ORCPT ); Fri, 5 Oct 2018 18:37:13 -0400 Received: by mail-lj1-f194.google.com with SMTP id j4-v6so8219509ljc.12; Fri, 05 Oct 2018 08:37:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WZYrX2cHrRHO72sYFW2dQ4W2aTFd9QrYyocgaRcj5ck=; b=TQl0fNX4yPOWF2SJpV+MT7CIPzVMrllXlQvz7PDLOYb2ERjR3w62saoMlpwc8ZNPXI 6ScVzRt7391Bk/TcSYb/vTjMulT27hAoz5Wfhnx14uP1S9jEY1++c5/3WBtTpHCREQj5 qXpQgcrporgo/RhSxIzwKfvgkDWjVqpxeESt6IflJX4YFefhcu1QX/dPSI5X3CiCwUPX j0HlOnrPTzbg8UvsENr0CRr5+ZYU/6CdU8U2BPQd9K8Fm/OITK2VVDkk/OF0zRsZzqvd aJcXz87MRr8UayzOpeiGX4xqDLWEZo4xlWvds+DX4Qam2ST4reTvmDebR2t8zUYduLrl e2Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WZYrX2cHrRHO72sYFW2dQ4W2aTFd9QrYyocgaRcj5ck=; b=DsepQ2hLhiOJIDUI5+e/KW6a4LSh84bnpExSchk8OBSvKyePHgMszDlWafw/TsIN4u 6rTXuX0/MfoCYh/JFcfEOW//OYbpi4rGnZGaRn4l3dbPDKvvp1LT4mI+/BkuYNe3Hy5f wCRJ4On/sR+6P+rm9n7KqaulwTrD4tjQ3kOSD8lcOlZNvtAN1+GJdx5e4Cv3h6ViI3Z1 QXp4xNo5Of+ZJEGtrs6+R/Mek0ZiAN1Qlh16Z2c/4E88gxBoZQog6yeTVL6tIw5YTFkj 5AK2qylCcdTvu1aAMI4aCNjLrTxlcX2DaUIhvVvUz4d9OYdz3PWBOIjwG1jxYzIs6M00 a2WQ== X-Gm-Message-State: ABuFfohtt0oEzjZ3UdXEE492/e6Jjs8Rbm2jHoFBD0h3mBLTfkEsQMeo cTYp3cBE2/I1JKBF9s7HbPE= X-Google-Smtp-Source: ACcGV62DaIGEh6vJplL1djjMuCC+EO8ZG/zZQCkX3xeVZHKZkoyxJTd5FYJdmVY6RBfEHEwh7Femmw== X-Received: by 2002:a2e:800e:: with SMTP id j14-v6mr831598ljg.114.1538753876464; Fri, 05 Oct 2018 08:37:56 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:55 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 03/11] regulator: core: Mutually resolve regulators coupling Date: Fri, 5 Oct 2018 18:36:30 +0300 Message-Id: <20181005153638.1886-4-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If registered regulator found a couple, then the couple can find the registered regulator too and hence coupling can be mutually resolved at the registration time. Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 54 +++++++++++++--------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5105eaaf3cef..925df9e6f1e3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4439,7 +4439,7 @@ static int regulator_register_resolve_supply(struct device *dev, void *data) return 0; } -static int regulator_fill_coupling_array(struct regulator_dev *rdev) +static void regulator_resolve_coupling(struct regulator_dev *rdev) { struct coupling_desc *c_desc = &rdev->coupling_desc; int n_coupled = c_desc->n_coupled; @@ -4453,33 +4453,21 @@ static int regulator_fill_coupling_array(struct regulator_dev *rdev) c_rdev = of_parse_coupled_regulator(rdev, i - 1); - if (c_rdev) { - c_desc->coupled_rdevs[i] = c_rdev; - c_desc->n_resolved++; - } - } - - if (rdev->coupling_desc.n_resolved < n_coupled) - return -1; - else - return 0; -} + if (!c_rdev) + continue; -static int regulator_register_fill_coupling_array(struct device *dev, - void *data) -{ - struct regulator_dev *rdev = dev_to_rdev(dev); + regulator_lock(c_rdev); - if (!IS_ENABLED(CONFIG_OF)) - return 0; + c_desc->coupled_rdevs[i] = c_rdev; + c_desc->n_resolved++; - if (regulator_fill_coupling_array(rdev)) - rdev_dbg(rdev, "unable to resolve coupling\n"); + regulator_unlock(c_rdev); - return 0; + regulator_resolve_coupling(c_rdev); + } } -static int regulator_resolve_coupling(struct regulator_dev *rdev) +static int regulator_init_coupling(struct regulator_dev *rdev) { int n_phandles; @@ -4519,13 +4507,6 @@ static int regulator_resolve_coupling(struct regulator_dev *rdev) if (!of_check_coupling_data(rdev)) return -EPERM; - /* - * After everything has been checked, try to fill rdevs array - * with pointers to regulators parsed from device tree. If some - * regulators are not registered yet, retry in late init call - */ - regulator_fill_coupling_array(rdev); - return 0; } @@ -4662,11 +4643,8 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret < 0) goto wash; - mutex_lock(®ulator_list_mutex); - ret = regulator_resolve_coupling(rdev); - mutex_unlock(®ulator_list_mutex); - - if (ret != 0) + ret = regulator_init_coupling(rdev); + if (ret < 0) goto wash; /* add consumers devices */ @@ -4700,6 +4678,11 @@ regulator_register(const struct regulator_desc *regulator_desc, rdev_init_debugfs(rdev); + /* try to resolve regulators coupling since a new one was registered */ + mutex_lock(®ulator_list_mutex); + regulator_resolve_coupling(rdev); + mutex_unlock(®ulator_list_mutex); + /* try to resolve regulators supply since a new one was registered */ class_for_each_device(®ulator_class, NULL, NULL, regulator_register_resolve_supply); @@ -5155,9 +5138,6 @@ static int __init regulator_init_complete(void) class_for_each_device(®ulator_class, NULL, NULL, regulator_late_cleanup); - class_for_each_device(®ulator_class, NULL, NULL, - regulator_register_fill_coupling_array); - return 0; } late_initcall_sync(regulator_init_complete); From patchwork Fri Oct 5 15:36:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628331 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F0419933 for ; Fri, 5 Oct 2018 15:38:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E83162978A for ; Fri, 5 Oct 2018 15:38:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCEBD29798; Fri, 5 Oct 2018 15:38:57 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 95A492978A for ; Fri, 5 Oct 2018 15:38:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729121AbeJEWhQ (ORCPT ); Fri, 5 Oct 2018 18:37:16 -0400 Received: from mail-lj1-f194.google.com ([209.85.208.194]:43152 "EHLO mail-lj1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729073AbeJEWhO (ORCPT ); Fri, 5 Oct 2018 18:37:14 -0400 Received: by mail-lj1-f194.google.com with SMTP id r8-v6so11967404ljc.10; Fri, 05 Oct 2018 08:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6MX5kdyZdQhku6iZxytVgwR1XNHtQY92eJ2ce4w79WA=; b=UZGSZ75liUNB+Djc4oaGJ5flzeHbrvtqV4KFpXRdMiy4uSVRN5e3bOYsrbUTYi6LdQ Q5rufLg3DnyCWL0XhCZCkhp/sInJf8qzWVy6Ot/u7mGNo90Hma4kJViDfeST/LsxiLIu TL3nLysh/5VwbN7lTwgk9ARI+CYvefmZxYJhrY2M0H4yQhuFRJtf6zVlntb+DOL/w34U gnRQ7wY5tJSuR1cK8i7DHOHg2vqT3rw0d6HKMYtao90NIZrUJvIFdayWaHshZpl5t7RU a0AHJbCGvXj966Oqm/sGc4YEP2erIMIhlRl4oaOBwpKhRbP/svNGk9RpsnIs3k5PjMnA TvWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6MX5kdyZdQhku6iZxytVgwR1XNHtQY92eJ2ce4w79WA=; b=ZX/QJwAwE78Z/saT7mHpILJt0epFrJFDg2R4joVTISF8nw/igGWkYnLn0qmcKqRj9A BZpX3yD+bfrh0b78AkGtIgH7FZmNTdk9P9g+SAIF4jp+XuV2WhNg302CIroYK+yEr6tD TIckw7tS4CbGaAxm6v9FfQCUOYFY6KiCZAvVPx3en/fcHCjLgAfX/1NJLq2HaK5VSOfU XzmrMqTBqIbbTJ+EZIczY50kVQmHbPXwWx6NBcF8EuT9taa5fy6rceuVmXWP/MRZTMo3 7RiDEek8VIukojpodXHGdA29jy1iBcbL231uuTsZvcQqZNRuSzERl5/jC0wkAE8/Wc8U dwKg== X-Gm-Message-State: ABuFfojLfmO8TfzXxrA16Vkf/pqOmrgjOhdC8ovM9syHQdMszzr7d4EC b3IKgTA/L2Vt90g8mSZhKus= X-Google-Smtp-Source: ACcGV60erpHzvkfdVBlfA2CPXO7xQcJZzk1+GfVXag0/QPiQ/5XuudPqvEawVp9FD4wloQ/m5JrugA== X-Received: by 2002:a2e:9d7:: with SMTP id 206-v6mr8113774ljj.127.1538753878000; Fri, 05 Oct 2018 08:37:58 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:57 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 04/11] regulator: core: Don't allow to get regulator until all couples resolved Date: Fri, 5 Oct 2018 18:36:31 +0300 Message-Id: <20181005153638.1886-5-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Don't allow to get regulator until all of its couples resolved because consumer will get EPERM and coupling shall be transparent for the drivers. Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 925df9e6f1e3..089e8ad8ef57 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1747,6 +1747,16 @@ struct regulator *_regulator_get(struct device *dev, const char *id, return regulator; } + mutex_lock(®ulator_list_mutex); + ret = (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled); + mutex_unlock(®ulator_list_mutex); + + if (ret != 0) { + regulator = ERR_PTR(-EPROBE_DEFER); + put_device(&rdev->dev); + return regulator; + } + ret = regulator_resolve_supply(rdev); if (ret < 0) { regulator = ERR_PTR(ret); From patchwork Fri Oct 5 15:36:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628333 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2BF77112B for ; Fri, 5 Oct 2018 15:39:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2370F2978A for ; Fri, 5 Oct 2018 15:39:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17B0F29798; Fri, 5 Oct 2018 15:39:01 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 BAD422978A for ; Fri, 5 Oct 2018 15:39:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729103AbeJEWhP (ORCPT ); Fri, 5 Oct 2018 18:37:15 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:33440 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729069AbeJEWhP (ORCPT ); Fri, 5 Oct 2018 18:37:15 -0400 Received: by mail-lj1-f196.google.com with SMTP id z21-v6so12009559ljz.0; Fri, 05 Oct 2018 08:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wO8rLezgv03Kc1/H2qOEeUj33zOmxhncF8Ftb8pScZc=; b=NVu2GOkOfb7iY0EvP908xRb2fPjxVvHVVrFXH2aGx8QW2B9pa/wpRJkbwppKvI/znd OWxovxOmmnH7ueeeqMlAB+qWYlulB1h3j8RnSN6ZUcBRbfLGhlk1ZkTGIwRvRaxlPmqp iXbbPCm7uiwqypcMbcz3x396fisS9bsMTrkAtE2B9v7PKvAPZGcYYNlsleiLcKmadKeT rN7aPtpDY06PIpQqmyQTiokHNuQYF1+BDxYLIRsQFKnMXHRgp8K2kWx3KfY2e8V4WT0I T7VQFDtdxmlb5s9j9is/KlSDphjb+x+zgzPinHMJOSjB12iH7k6XcR6B3YCQo5zkRKdV ythQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wO8rLezgv03Kc1/H2qOEeUj33zOmxhncF8Ftb8pScZc=; b=qXkTbhJ3R/BOaZT2Iw8lyEyQ2tJuk3LXmhc2apLiaafmZHyLNZEbMoxDTJb7uEESnp i9gQjB0v/sxqPSmC4pv7clSffSPYTFGr4fg6mSJuaLJ+qTOiyvMZc9tFbPYLQOBy93eK vwYTZWBSDSvg2z8EpT6D/kk53ROk2/KhkyZOfq3bMlhC1rT+jbEex7pBX/PwK0lONNQC JICvdJQCfD1O5xJ15eAY5bsVAA0ZoUjyloXqAqWqy6ab2jJfnP5OoUSO4ZFatDuhgkRZ SCfcdnICLztpbKgnynaVJ0hlAm5OOL4ZEAqximqrwdVeAQGwDYNZRd5Pcf1JdT3RN04v ojRA== X-Gm-Message-State: ABuFfojnJ0dvSwxanYfnCy/K4+fz6RNRwRsnYpNqJJTXNIbEzqZXKi5S XnA7WwUDgjtwqM51VXeHqyk= X-Google-Smtp-Source: ACcGV61tzkAcoe5zkUcESDoYnBzR66PilWuiQizktu3bVLN9FaRF7z0P7b5HSc3thKSnAZE5d0omWg== X-Received: by 2002:a2e:2205:: with SMTP id i5-v6mr6737163lji.15.1538753879137; Fri, 05 Oct 2018 08:37:59 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:58 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 05/11] dt-bindings: regulator: Change regulator-coupled-max-spread property Date: Fri, 5 Oct 2018 18:36:32 +0300 Message-Id: <20181005153638.1886-6-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Redefine binding for regulator-coupled-max-spread property in a way that max-spread values are defined per regulator couple instead of defining single max-spread for the whole group of coupled regulators. With that change the following regulators coupling configuration will be possible: regA: regulatorA { regulator-coupled-with = <®B ®C>; regulator-coupled-max-spread = <100000 300000>; }; regB: regulatorB { regulator-coupled-with = <®A ®C>; regulator-coupled-max-spread = <100000 200000>; }; regC: regulatorC { regulator-coupled-with = <®A ®B>; regulator-coupled-max-spread = <300000 200000>; }; Signed-off-by: Dmitry Osipenko Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/regulator/regulator.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index a7cd36877bfe..9b525b657fca 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -76,8 +76,9 @@ Optional properties: - regulator-coupled-with: Regulators with which the regulator is coupled. The linkage is 2-way - all coupled regulators should be linked with each other. A regulator should not be coupled with its supplier. -- regulator-coupled-max-spread: Max spread between voltages of coupled regulators - in microvolts. +- regulator-coupled-max-spread: Array of maximum spread between voltages of + coupled regulators in microvolts, each value in the array relates to the + corresponding couple specified by the regulator-coupled-with property. Deprecated properties: - regulator-compatible: If a regulator chip contains multiple From patchwork Fri Oct 5 15:36:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C80DA933 for ; Fri, 5 Oct 2018 15:38:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE3BE28A52 for ; Fri, 5 Oct 2018 15:38:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF094296A7; Fri, 5 Oct 2018 15:38:05 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 64FC428A52 for ; Fri, 5 Oct 2018 15:38:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729180AbeJEWhQ (ORCPT ); Fri, 5 Oct 2018 18:37:16 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:33445 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729084AbeJEWhQ (ORCPT ); Fri, 5 Oct 2018 18:37:16 -0400 Received: by mail-lj1-f196.google.com with SMTP id z21-v6so12009647ljz.0; Fri, 05 Oct 2018 08:38:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZCf33qrb2hqSKhelVYfNZnVvCL42nB6oHuNJ9Gt3DlY=; b=Inwj2dY8vBnJ7AB0yZfh5SuMkvaxZSJxN35QsgmULFycrWqf/+fh7/DObQj390h6/p MeI4pw+Co65EXAdyRDktVyTbYB7f8u12/LvejFpKbSpACJZHydYPV2qj7SrYoAIqln20 I7zl6bv/pOFZK6AD+0WYh+VNuF2bMLH+/SGRET3oHL8NogUZGIeSywa+/5E0IPgavcFr cQpjGSfVq4dUW636yICoB+2wfJ/KbD54w2KGnuoXl30oVD0Loy6hB1zeFOwazOVgHogs HBq7WudpYZoYAzEwFBxF0mtflnshR9WW1rYlXOzLVwg0elwCa99YCLJ4Co0sMeuSRSd8 iIjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZCf33qrb2hqSKhelVYfNZnVvCL42nB6oHuNJ9Gt3DlY=; b=d6uOLHLQ4aNcuYmLmKhs6bBsV8fFKCwQTCqZerwzE3VRbIZ5VYXe/73hJatknMQ1J+ 9xlNTDJ1A6kWCGvABbSNrviyoS75m+NqO8iAbFDwRJ5ADQ8Un+gHU1Icb3iCbEygXwPP lw9AUDpiN2rN5ZL06O5DNviafKSKPQZGRz9k71AqWkBjXIeFweebuSBF0s819lYZutJm oNvZnyGUDQ1oESzIrrzvyJIKu9eaUnN4/wy+jhrI4qWzzx2pzKYiTEUfEF0lBTmBUd5R 7kFm8uqta83wgcQ5+9vGECSv7xLzeMFKDpmkfApPDXVZyElkYemaVqohVELdsJghKPrF RN0Q== X-Gm-Message-State: ABuFfojPuUr1O8O/Wvcghv2HeK53OSk0zn6nkqQ1sYTdizvoGxpgxIAf btGbjOCiuJpe+PaabK7HvF8= X-Google-Smtp-Source: ACcGV62LLdVf2OiI+pv6on5I3HDCTFZPqb9sYIy8ScFrhBNYyUv1v16dLXXLRpG46LGEWHCB7BZvFw== X-Received: by 2002:a2e:9549:: with SMTP id t9-v6mr7667499ljh.94.1538753880575; Fri, 05 Oct 2018 08:38:00 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.37.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:37:59 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 06/11] regulator: core: Limit regulators coupling to a single couple Date: Fri, 5 Oct 2018 18:36:33 +0300 Message-Id: <20181005153638.1886-7-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Device tree binding was changed in a way that now max-spread values must be defied per regulator pair. Limit number of pairs in order to adapt to the new binding without changing regulators code. Signed-off-by: Dmitry Osipenko --- include/linux/regulator/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index a9c030192147..a05d37d0efa1 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -15,7 +15,7 @@ #ifndef __LINUX_REGULATOR_DRIVER_H_ #define __LINUX_REGULATOR_DRIVER_H_ -#define MAX_COUPLED 4 +#define MAX_COUPLED 2 #include #include From patchwork Fri Oct 5 15:36:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628329 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1EA22933 for ; Fri, 5 Oct 2018 15:38:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 14CD32978A for ; Fri, 5 Oct 2018 15:38:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0640A29798; Fri, 5 Oct 2018 15:38:45 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 A00AD2978A for ; Fri, 5 Oct 2018 15:38:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727957AbeJEWhu (ORCPT ); Fri, 5 Oct 2018 18:37:50 -0400 Received: from mail-lf1-f68.google.com ([209.85.167.68]:46730 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728562AbeJEWhR (ORCPT ); Fri, 5 Oct 2018 18:37:17 -0400 Received: by mail-lf1-f68.google.com with SMTP id z144-v6so1149790lff.13; Fri, 05 Oct 2018 08:38:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QEkMidX6FxpiZSTFa8KISKNbf0++dhdesLBYR/Rbies=; b=GSrZroaUf5AOHNuqOF41WdXLoyG59HDiX2qeyBcCVtJ71aNkPPezwfR8PcsYKG1AE5 urobSipTdm3rq6y9HjnpqGzV0zNl491rhaO4AD0pol97TJHm1f+QV+hyjyElaLedE1BH gkUaOAXpoAx1QKnMX2/bKDwlsiZe6vWFj9LjMg9cvVI80KICQw3DdejkYuWRHImYLHrc sPjsZ2lZJEaqFCVVt0bsZUqB54obIUgbKi8Dmn9bdcuXDu60Z1iDgqGihjiOHRXLLgFK 9EvPF+IMJ6UN2yxbVpMqQIDlYn8UT8dHLf1YAj4B3/v73C0p2g3VoS6vo5TI9UL35IFP 8P6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QEkMidX6FxpiZSTFa8KISKNbf0++dhdesLBYR/Rbies=; b=oabazvVLKN4edEMmmH3MLFWuZy4Ews3cuyWMn4cRDtm/G+lFO3ay+p3c48RO31/tUH mAJV5vQB+h0hBHEkQiksGyj3/kuxtepYe/9Q7lM90jNISuwOQq9F5SxOrjUL4F3r6x9F asTHB/U3EKgkFiRDyJLL+8Y9cOMfzm41OPweGsy7Y618mdGQeXlpZZm55KuOR/u/FHme XL9m8oW12zeqwslguB5ROgpA3UkT+zVkXdhNOfu1oou5yHSlh8O33BWquNOzyReiapZ1 Lx+cAvHLbWm2XJUxyX8AJ5POC9Vv8Tdeh8Z2NFYOLYMK4qKulEuS4qUo/CMqJg58KEtq TkAA== X-Gm-Message-State: ABuFfoiF6G9AQaT6Ic8hbKFnyg+N5WU5MfzfpYnCZNlDaZoPjuICnXlt s7u00mk6SKa57cPnSNM1fl8= X-Google-Smtp-Source: ACcGV60sUESNjMBioepOaWBIT4jaCs+E/WyNbSCiW4Lg1PT8d7swZtjtBtQiH67UlcQRa3tArGEZLQ== X-Received: by 2002:a19:c650:: with SMTP id w77-v6mr7448587lff.108.1538753881679; Fri, 05 Oct 2018 08:38:01 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.38.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:38:01 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 07/11] dt-bindings: regulator: Document new regulator-max-step-microvolt property Date: Fri, 5 Oct 2018 18:36:34 +0300 Message-Id: <20181005153638.1886-8-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Certain hardware may require supply voltage to be changed in steps. Define new property that allow to describe such hardware. Signed-off-by: Dmitry Osipenko Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/regulator/regulator.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 9b525b657fca..0c3a243c95df 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -79,6 +79,8 @@ Optional properties: - regulator-coupled-max-spread: Array of maximum spread between voltages of coupled regulators in microvolts, each value in the array relates to the corresponding couple specified by the regulator-coupled-with property. +- regulator-max-step-microvolt: Maximum difference between current and target + voltages that can be changed safely in a single step. Deprecated properties: - regulator-compatible: If a regulator chip contains multiple From patchwork Fri Oct 5 15:36:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628325 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EB16C933 for ; Fri, 5 Oct 2018 15:38:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF6A92978A for ; Fri, 5 Oct 2018 15:38:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D3AE82978F; Fri, 5 Oct 2018 15:38:34 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 6236729738 for ; Fri, 5 Oct 2018 15:38:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729212AbeJEWhV (ORCPT ); Fri, 5 Oct 2018 18:37:21 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:42077 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729182AbeJEWhT (ORCPT ); Fri, 5 Oct 2018 18:37:19 -0400 Received: by mail-lf1-f65.google.com with SMTP id s10-v6so9655020lfc.9; Fri, 05 Oct 2018 08:38:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CguVuh97a9Y3y6PgH3GDIr5XBaGX/zUX4wXfiW1S58E=; b=RZ1WOC7Xq3FEq+c682MbN0B+AL0DpP5bWgFQF6hl811THOvS+krYRtsm3O5U7+4HKd xExgXwFhe3lx2JT3m5o6E/dXjdwZkeMo0AJ6tGjTjz3McGOYA56wHzndr+PLcrSqiY1y xXiEYtdN8/1N7I7Vc4LM/bcZb72TfWS5+Q/bZ/vw10YVN/sQZwzZ2/KOHsbVyzYaxb50 Tu01tcIe310hN7U6STrPBUY/cLpkUYSlZ1eNdmTTOOWQMQBmAFPpc7mQ7T8hUDR0d02X 4iHMXjnqNhQFkNhd/BDsJYNXsAVM6ixyTVSqkUO9/RElrVm3ITZyxinykUzWnvr3Il9k ygxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CguVuh97a9Y3y6PgH3GDIr5XBaGX/zUX4wXfiW1S58E=; b=djmJoAh3Jq/PAlekbiaESE0aWyeBg9zgKUJnQ+bp7rGKQsdQozamy/BbzHdzeAI2BO gjnadTMH32zBvssogQADRVP8iZkblZ6NEdff0Ak0ihrOxJDFQw6S4WDdRjTiyTEyQlHI OHo9LNQATDOO3d5mK1S74CMyRvA469Kv9zreUaDvckrJyRwnVjv47EcGXkY8NZh1FVXb vpxcN2MjX9bI0WOL7N3lRmsfGdM9lNIpYTe9VFmAZ8jVTaSn9vVSv1gCyLfOdxzIMrIM itgUuj6YeimL2nhig5X3qbV9seXS8WDDvts3ij0cJE7kMDd9f5ghr9W8SYaARSlf7Xgz CLtQ== X-Gm-Message-State: ABuFfoisYaaSEGmsscX0fRM6n4s02RQVHq7ogn4gqs27r5gy1zNboPhQ JLTOCo8Vxpv8TJ4+SnXwS1A= X-Google-Smtp-Source: ACcGV62cfbreUlEwnz9rPd+BycQycAvxzJxycWIfFeLm9WSaT9ta7vDkyyufeaxzUtQHdunHhDU9wg== X-Received: by 2002:a19:54c1:: with SMTP id b62-v6mr6960846lfl.14.1538753883054; Fri, 05 Oct 2018 08:38:03 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.38.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:38:02 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 08/11] regulator: core: Add new max_uV_step constraint Date: Fri, 5 Oct 2018 18:36:35 +0300 Message-Id: <20181005153638.1886-9-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On NVIDIA Tegra30 there is a requirement for regulator "A" to have voltage higher than voltage of regulator "B" by N microvolts, the N value changes depending on the voltage of regulator "B". This is similar to min-spread between voltages of regulators, the difference is that the spread value isn't fixed. This means that extra carefulness is required for regulator "A" to drop its voltage without violating the requirement, hence its voltage should be changed in steps so that its couple "B" could follow (there is also max-spread requirement). Add new "max_uV_step" constraint that breaks voltage change into several steps, each step is limited by the max_uV_step value. Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 41 +++++++++++++++++++++++++++++++ drivers/regulator/of_regulator.c | 4 +++ include/linux/regulator/machine.h | 3 +++ 3 files changed, 48 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 089e8ad8ef57..ba03bdf3716f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3191,6 +3191,36 @@ static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV, return ret; } +static int regulator_limit_voltage_step(struct regulator_dev *rdev, + int *current_uV, int *min_uV) +{ + struct regulation_constraints *constraints = rdev->constraints; + + /* Limit voltage change only if necessary */ + if (!constraints->max_uV_step || !_regulator_is_enabled(rdev)) + return 1; + + if (*current_uV < 0) { + *current_uV = _regulator_get_voltage(rdev); + + if (*current_uV < 0) + return *current_uV; + } + + if (abs(*current_uV - *min_uV) <= constraints->max_uV_step) + return 1; + + /* Clamp target voltage within the given step */ + if (*current_uV < *min_uV) + *min_uV = min(*current_uV + constraints->max_uV_step, + *min_uV); + else + *min_uV = max(*current_uV - constraints->max_uV_step, + *min_uV); + + return 0; +} + static int regulator_get_optimal_voltage(struct regulator_dev *rdev, int *current_uV, int *min_uV, int *max_uV, @@ -3302,6 +3332,17 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev, desired_min_uV = possible_uV; finish: + /* Apply max_uV_step constraint if necessary */ + if (state == PM_SUSPEND_ON) { + ret = regulator_limit_voltage_step(rdev, current_uV, + &desired_min_uV); + if (ret < 0) + return ret; + + if (ret == 0) + done = false; + } + /* Set current_uV if wasn't done earlier in the code and if necessary */ if (n_coupled > 1 && *current_uV == -1) { diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index c4223b3e0dff..a732f09d207b 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -170,6 +170,10 @@ static void of_get_regulation_constraints(struct device_node *np, &pval)) constraints->max_spread = pval; + if (!of_property_read_u32(np, "regulator-max-step-microvolt", + &pval)) + constraints->max_uV_step = pval; + constraints->over_current_protection = of_property_read_bool(np, "regulator-over-current-protection"); diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index a459a5e973a7..1d34a70ffda2 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -158,6 +158,9 @@ struct regulation_constraints { /* used for coupled regulators */ int max_spread; + /* used for changing voltage in steps */ + int max_uV_step; + /* valid regulator operating modes for this machine */ unsigned int valid_modes_mask; From patchwork Fri Oct 5 15:36:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628327 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E9D9184E for ; Fri, 5 Oct 2018 15:38:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 962E82978A for ; Fri, 5 Oct 2018 15:38:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A4C52979B; Fri, 5 Oct 2018 15:38:35 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 397652978A for ; Fri, 5 Oct 2018 15:38:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729209AbeJEWhV (ORCPT ); Fri, 5 Oct 2018 18:37:21 -0400 Received: from mail-lf1-f66.google.com ([209.85.167.66]:45951 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729084AbeJEWhU (ORCPT ); Fri, 5 Oct 2018 18:37:20 -0400 Received: by mail-lf1-f66.google.com with SMTP id m80-v6so9645156lfi.12; Fri, 05 Oct 2018 08:38:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YhWFQ6MifqW5rbquI58Ij21Y/GKwiXK722JXem6LK/k=; b=oHG52z0dhR7/p5KZ36rP2dZnZsUle7uL5yBktPtBE00MaCeCfhJiepQaOW5Ggv6NuW nfMkeZFB33qaj2xq5df9gWcEopuB6ATZMhPsir1DrayK3WFUPDiEvBcfb0fXvyavmNUb Pf1oZF8A3D7ndtP67BE7Chm1KAMY1zQe0zjqm1r2i8r6Rrieii82mxrEk/cdbmKKDJbg bLs+eYs9JQeRBs2q0b46UgjCmJStloq36xi6Jjj7DWQh0OiHER/XTEL6GtzwRCXNs9t2 t+S9zIrU1p6WuXKoQW2rZNlMSIv4/G+rqrn2JwpMpcIVDo28WogmOP6LCBEtuve1aSyo cJ0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YhWFQ6MifqW5rbquI58Ij21Y/GKwiXK722JXem6LK/k=; b=AmYb+/UrpsSX/URzHsz1A88hENYdybaUVQVwVHGzAq5mvT5MRRev7fEuZB3GYF/8GJ zQ35A6SisTrnwXYQu5hrA+aYibi5yTGJAQvAiqcxDXfRoj+Rn0qTYp21Ebsiq4+hGhMX vq432IXKMFN2DMKkzaaIqL+zWg3f9rJ12ozGyDMcAUPA/O+m4M8xrdHOyTvJhUbctSaT O0fjMk+jHzTVP0XGD9VO1M7AJBVFf6XUznd5DibyQSoB53m/cVJPNyntsz3+43ZDzHoZ Cs28gRrGz8N35LGqm9fHubdzyG5QeigxfsCF1jxsLpD2wiFdNPEam1oBnjt5DCvt2rPG Sksg== X-Gm-Message-State: ABuFfohryFnUSxaijl4u6NRO/zYrXgJECrt6ZraU7WAFM8STkl1aZqnQ Xg0yiKETQIZC4xKuPg7o6Vc= X-Google-Smtp-Source: ACcGV636v75KX5zEdOIXmHFJ7qtH30ImzIq3L2nwQpaHYucxETvPcvSj60kZaQTTlrqih+nAH/6IsA== X-Received: by 2002:a19:df43:: with SMTP id q3-v6mr6755419lfj.53.1538753884439; Fri, 05 Oct 2018 08:38:04 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.38.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:38:03 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 09/11] regulator: core: Decouple regulators on regulator_unregister() Date: Fri, 5 Oct 2018 18:36:36 +0300 Message-Id: <20181005153638.1886-10-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Regulators shall be uncoupled if one of the couples disappear. Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ba03bdf3716f..783ec9c74104 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4518,6 +4518,43 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev) } } +static void regulator_remove_coupling(struct regulator_dev *rdev) +{ + struct coupling_desc *__c_desc, *c_desc = &rdev->coupling_desc; + struct regulator_dev *__c_rdev, *c_rdev; + unsigned int __n_coupled, n_coupled; + int i, k; + + n_coupled = c_desc->n_coupled; + + for (i = 1; i < n_coupled; i++) { + c_rdev = c_desc->coupled_rdevs[i]; + + if (!c_rdev) + continue; + + regulator_lock(c_rdev); + + __c_desc = &c_rdev->coupling_desc; + __n_coupled = __c_desc->n_coupled; + + for (k = 1; k < __n_coupled; k++) { + __c_rdev = __c_desc->coupled_rdevs[k]; + + if (__c_rdev == rdev) { + __c_desc->coupled_rdevs[k] = NULL; + __c_desc->n_resolved--; + break; + } + } + + regulator_unlock(c_rdev); + + c_desc->coupled_rdevs[i] = NULL; + c_desc->n_resolved--; + } +} + static int regulator_init_coupling(struct regulator_dev *rdev) { int n_phandles; @@ -4776,6 +4813,7 @@ void regulator_unregister(struct regulator_dev *rdev) debugfs_remove_recursive(rdev->debugfs); flush_work(&rdev->disable_work.work); WARN_ON(rdev->open_count); + regulator_remove_coupling(rdev); unset_regulator_supplies(rdev); list_del(&rdev->list); regulator_ena_gpio_free(rdev); From patchwork Fri Oct 5 15:36:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628323 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79EEA933 for ; Fri, 5 Oct 2018 15:38:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6FE4E2978A for ; Fri, 5 Oct 2018 15:38:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6261C2978F; Fri, 5 Oct 2018 15:38:25 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 2D8502978A for ; Fri, 5 Oct 2018 15:38:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729292AbeJEWh3 (ORCPT ); Fri, 5 Oct 2018 18:37:29 -0400 Received: from mail-lf1-f66.google.com ([209.85.167.66]:45953 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727798AbeJEWhW (ORCPT ); Fri, 5 Oct 2018 18:37:22 -0400 Received: by mail-lf1-f66.google.com with SMTP id m80-v6so9645209lfi.12; Fri, 05 Oct 2018 08:38:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ubh4UbUQdg43rPdvMObzACDOAsV2Wbn7mw4fc7QHza8=; b=uLcdSapq40Gcd2EeQg5yylt+U5dUMcDs7bElABwN90ktJUObMNwvN/sJtqF5ixUvm0 Seg1HCQWnpkoAGtz5TArEMQTf7Wv4SgLCZEZz1LJCglOiDOfBdHgRnNGzGdna+Gfv0DX 5+K0eEgUhWMzl5ZXcesiXi7Qp2fckhNHn3k408gQqB/PaGRKRc9LVG9HB8vqhDoMzLjN Jc9tUlMXfQFd72jgE0GtZ1XMz1eFj+/qHXUdQc7vmrGNAIRYFIzlNXS/vIfZqBQVG4BB fQqMGbNZb+QHIT5aUe12SWuuFpOlks4qYdgB04LYfsVu/KL7bng8PAofn2cBQEwYiOPM B1IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ubh4UbUQdg43rPdvMObzACDOAsV2Wbn7mw4fc7QHza8=; b=QzNRM4PDA4BG9QtOmmqGJqYSAxjP/B7msaUqPRnI0nT/S/+qN4fAbK4UQ3f8awFbea ffL2cssJZaZkR+Y7yxO5r+Qsh5dXEcDkS1jK7ZBHq7RycIQM1tbslv2CT4+8PgAConuV 194n3By8ncfhIq9WkxzA95WezPkze0upVlb+cSY7Xx0dpJrMJRoc8mYXkpohi0nDDuGj BPV/lT16+D8xUc8EyYJv0ziA9WwIYZut0Tn19ycU25dn5Jc2Pw5lRAFzGDBXZNoBMfFB aXtXpMvX66DiiYx/q2gwJz3wgt1EJOgMK5VKpURC6J2BeU/CAE2Bx7CNSSQsLwiLKKKR +UaQ== X-Gm-Message-State: ABuFfoiu72C73b6lnek65dDLydUXlkSomZVDxNtVzLS6WCAc+G0oL9Ob DO2hxCJhtKEog7K7bprrr7E= X-Google-Smtp-Source: ACcGV61Fnbp35y+nzJQIAR5BlUIge+jAOL9+EjityzQIXXZXw7U6nXHQuo6hBaIYrJrYcc7Y3nDyqg== X-Received: by 2002:a19:d155:: with SMTP id i82-v6mr6849910lfg.127.1538753885527; Fri, 05 Oct 2018 08:38:05 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.38.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:38:04 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 10/11] regulator: core: Use ww_mutex for regulators locking Date: Fri, 5 Oct 2018 18:36:37 +0300 Message-Id: <20181005153638.1886-11-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Wait/wound mutex shall be used in order to avoid lockups on locking of coupled regulators. Signed-off-by: Dmitry Osipenko Suggested-by: Lucas Stach --- drivers/regulator/core.c | 401 +++++++++++++++++++++++-------- include/linux/regulator/driver.h | 3 +- 2 files changed, 307 insertions(+), 97 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 783ec9c74104..a3448636f334 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -50,6 +50,8 @@ #define rdev_dbg(rdev, fmt, ...) \ pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) +static DEFINE_WW_CLASS(regulator_ww_class); +static DEFINE_MUTEX(regulator_nesting_mutex); static DEFINE_MUTEX(regulator_list_mutex); static LIST_HEAD(regulator_map_list); static LIST_HEAD(regulator_ena_gpio_list); @@ -154,7 +156,7 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) /** * regulator_lock_nested - lock a single regulator * @rdev: regulator source - * @subclass: mutex subclass used for lockdep + * @ww_ctx: w/w mutex acquire context * * This function can be called many times by one task on * a single regulator and its mutex will be locked only @@ -162,24 +164,52 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) * than the one, which initially locked the mutex, it will * wait on mutex. */ -static void regulator_lock_nested(struct regulator_dev *rdev, - unsigned int subclass) +static inline int regulator_lock_nested(struct regulator_dev *rdev, + struct ww_acquire_ctx *ww_ctx) { - if (!mutex_trylock(&rdev->mutex)) { - if (rdev->mutex_owner == current) { + bool lock = false; + int ret = 0; + + mutex_lock(®ulator_nesting_mutex); + + if (ww_ctx || !ww_mutex_trylock(&rdev->mutex)) { + if (rdev->mutex_owner == current) rdev->ref_cnt++; - return; + else + lock = true; + + if (lock) { + mutex_unlock(®ulator_nesting_mutex); + ret = ww_mutex_lock(&rdev->mutex, ww_ctx); + mutex_lock(®ulator_nesting_mutex); } - mutex_lock_nested(&rdev->mutex, subclass); + } else { + lock = true; } - rdev->ref_cnt = 1; - rdev->mutex_owner = current; + if (lock && ret != -EDEADLK) { + rdev->ref_cnt++; + rdev->mutex_owner = current; + } + + mutex_unlock(®ulator_nesting_mutex); + + return ret; } -static inline void regulator_lock(struct regulator_dev *rdev) +/** + * regulator_lock - lock a single regulator + * @rdev: regulator source + * + * This function can be called many times by one task on + * a single regulator and its mutex will be locked only + * once. If a task, which is calling this function is other + * than the one, which initially locked the mutex, it will + * wait on mutex. + */ +static void regulator_lock(struct regulator_dev *rdev) { - regulator_lock_nested(rdev, 0); + regulator_lock_nested(rdev, NULL); } /** @@ -191,50 +221,46 @@ static inline void regulator_lock(struct regulator_dev *rdev) */ static void regulator_unlock(struct regulator_dev *rdev) { - if (rdev->ref_cnt != 0) { - rdev->ref_cnt--; + mutex_lock(®ulator_nesting_mutex); - if (!rdev->ref_cnt) { - rdev->mutex_owner = NULL; - mutex_unlock(&rdev->mutex); - } + if (--rdev->ref_cnt == 0) { + rdev->mutex_owner = NULL; + ww_mutex_unlock(&rdev->mutex); } + + WARN_ON_ONCE(rdev->ref_cnt < 0); + + mutex_unlock(®ulator_nesting_mutex); } -static int regulator_lock_recursive(struct regulator_dev *rdev, - unsigned int subclass) +static void regulator_unlock_recursive(struct regulator_dev *rdev, + unsigned int n_coupled) { struct regulator_dev *c_rdev; int i; - for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { - c_rdev = rdev->coupling_desc.coupled_rdevs[i]; + for (i = n_coupled; i > 0; i--) { + c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1]; if (!c_rdev) continue; - regulator_lock_nested(c_rdev, subclass++); - if (c_rdev->supply) - subclass = - regulator_lock_recursive(c_rdev->supply->rdev, - subclass); - } + regulator_unlock_recursive( + c_rdev->supply->rdev, + c_rdev->coupling_desc.n_coupled); - return subclass; + regulator_unlock(c_rdev); + } } -/** - * regulator_unlock_dependent - unlock regulator's suppliers and coupled - * regulators - * @rdev: regulator source - * - * Unlock all regulators related with rdev by coupling or suppling. - */ -static void regulator_unlock_dependent(struct regulator_dev *rdev) +static int regulator_lock_recursive(struct regulator_dev *rdev, + struct regulator_dev **new_contended_rdev, + struct regulator_dev **old_contended_rdev, + struct ww_acquire_ctx *ww_ctx) { struct regulator_dev *c_rdev; - int i; + int i, err; for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { c_rdev = rdev->coupling_desc.coupled_rdevs[i]; @@ -242,23 +268,95 @@ static void regulator_unlock_dependent(struct regulator_dev *rdev) if (!c_rdev) continue; - regulator_unlock(c_rdev); + if (c_rdev != *old_contended_rdev) { + err = regulator_lock_nested(c_rdev, ww_ctx); + if (err) { + if (err == -EDEADLK) { + *new_contended_rdev = c_rdev; + goto err_unlock; + } - if (c_rdev->supply) - regulator_unlock_dependent(c_rdev->supply->rdev); + /* shouldn't happen */ + WARN_ON_ONCE(err != -EALREADY); + } + } else { + *old_contended_rdev = NULL; + } + + if (c_rdev->supply) { + err = regulator_lock_recursive(c_rdev->supply->rdev, + new_contended_rdev, + old_contended_rdev, + ww_ctx); + if (err) { + regulator_unlock(c_rdev); + goto err_unlock; + } + } } + + return 0; + +err_unlock: + regulator_unlock_recursive(rdev, i); + + return err; +} + +/** + * regulator_unlock_dependent - unlock regulator's suppliers and coupled + * regulators + * @rdev: regulator source + * @ww_ctx: w/w mutex acquire context + * + * Unlock all regulators related with rdev by coupling or suppling. + */ +static void regulator_unlock_dependent(struct regulator_dev *rdev, + struct ww_acquire_ctx *ww_ctx) +{ + regulator_unlock_recursive(rdev, rdev->coupling_desc.n_coupled); + ww_acquire_fini(ww_ctx); } /** * regulator_lock_dependent - lock regulator's suppliers and coupled regulators * @rdev: regulator source + * @ww_ctx: w/w mutex acquire context * * This function as a wrapper on regulator_lock_recursive(), which locks * all regulators related with rdev by coupling or suppling. */ -static inline void regulator_lock_dependent(struct regulator_dev *rdev) +static void regulator_lock_dependent(struct regulator_dev *rdev, + struct ww_acquire_ctx *ww_ctx) { - regulator_lock_recursive(rdev, 0); + struct regulator_dev *new_contended_rdev = NULL; + struct regulator_dev *old_contended_rdev = NULL; + int err; + + mutex_lock(®ulator_list_mutex); + + ww_acquire_init(ww_ctx, ®ulator_ww_class); + + do { + if (new_contended_rdev) { + ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); + old_contended_rdev = new_contended_rdev; + old_contended_rdev->ref_cnt++; + } + + err = regulator_lock_recursive(rdev, + &new_contended_rdev, + &old_contended_rdev, + ww_ctx); + + if (old_contended_rdev) + regulator_unlock(old_contended_rdev); + + } while (err == -EDEADLK); + + ww_acquire_done(ww_ctx); + + mutex_unlock(®ulator_list_mutex); } /** @@ -772,7 +870,7 @@ static int drms_uA_update(struct regulator_dev *rdev) int current_uA = 0, output_uV, input_uV, err; unsigned int mode; - lockdep_assert_held_once(&rdev->mutex); + lockdep_assert_held_once(&rdev->mutex.base); /* * first check to see if we can set modes at all, otherwise just @@ -2274,7 +2372,20 @@ static int _regulator_enable(struct regulator_dev *rdev) { int ret; - lockdep_assert_held_once(&rdev->mutex); + lockdep_assert_held_once(&rdev->mutex.base); + + if (rdev->supply) { + ret = _regulator_enable(rdev->supply->rdev); + if (ret < 0) + return ret; + } + + /* balance only if there are regulators coupled */ + if (rdev->coupling_desc.n_coupled > 1) { + ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); + if (ret < 0) + goto err_disable_supply; + } /* check voltage and requested load before enabling */ if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) @@ -2285,18 +2396,20 @@ static int _regulator_enable(struct regulator_dev *rdev) ret = _regulator_is_enabled(rdev); if (ret == -EINVAL || ret == 0) { if (!regulator_ops_is_valid(rdev, - REGULATOR_CHANGE_STATUS)) - return -EPERM; + REGULATOR_CHANGE_STATUS)) { + ret = -EPERM; + goto err_disable_supply; + } ret = _regulator_do_enable(rdev); if (ret < 0) - return ret; + goto err_disable_supply; _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, NULL); } else if (ret < 0) { rdev_err(rdev, "is_enabled() failed: %d\n", ret); - return ret; + goto err_disable_supply; } /* Fallthrough on positive return values - already enabled */ } @@ -2304,6 +2417,12 @@ static int _regulator_enable(struct regulator_dev *rdev) rdev->use_count++; return 0; + +err_disable_supply: + if (rdev->supply) + _regulator_disable(rdev->supply->rdev); + + return ret; } /** @@ -2320,30 +2439,15 @@ static int _regulator_enable(struct regulator_dev *rdev) int regulator_enable(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; + struct ww_acquire_ctx ww_ctx; int ret = 0; if (regulator->always_on) return 0; - if (rdev->supply) { - ret = regulator_enable(rdev->supply); - if (ret != 0) - return ret; - } - - regulator_lock_dependent(rdev); - /* balance only if there are regulators coupled */ - if (rdev->coupling_desc.n_coupled > 1) { - ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); - if (ret != 0) - goto unlock; - } + regulator_lock_dependent(rdev, &ww_ctx); ret = _regulator_enable(rdev); -unlock: - regulator_unlock_dependent(rdev); - - if (ret != 0 && rdev->supply) - regulator_disable(rdev->supply); + regulator_unlock_dependent(rdev, &ww_ctx); return ret; } @@ -2385,7 +2489,7 @@ static int _regulator_disable(struct regulator_dev *rdev) { int ret = 0; - lockdep_assert_held_once(&rdev->mutex); + lockdep_assert_held_once(&rdev->mutex.base); if (WARN(rdev->use_count <= 0, "unbalanced disables for %s\n", rdev_get_name(rdev))) @@ -2423,6 +2527,12 @@ static int _regulator_disable(struct regulator_dev *rdev) rdev->use_count--; } + if (ret == 0 && rdev->coupling_desc.n_coupled > 1) + ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); + + if (ret == 0 && rdev->supply) + ret = _regulator_disable(rdev->supply->rdev); + return ret; } @@ -2441,19 +2551,15 @@ static int _regulator_disable(struct regulator_dev *rdev) int regulator_disable(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; + struct ww_acquire_ctx ww_ctx; int ret = 0; if (regulator->always_on) return 0; - regulator_lock_dependent(rdev); + regulator_lock_dependent(rdev, &ww_ctx); ret = _regulator_disable(rdev); - if (rdev->coupling_desc.n_coupled > 1) - regulator_balance_voltage(rdev, PM_SUSPEND_ON); - regulator_unlock_dependent(rdev); - - if (ret == 0 && rdev->supply) - regulator_disable(rdev->supply); + regulator_unlock_dependent(rdev, &ww_ctx); return ret; } @@ -2464,7 +2570,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev) { int ret = 0; - lockdep_assert_held_once(&rdev->mutex); + lockdep_assert_held_once(&rdev->mutex.base); ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | REGULATOR_EVENT_PRE_DISABLE, NULL); @@ -2497,14 +2603,15 @@ static int _regulator_force_disable(struct regulator_dev *rdev) int regulator_force_disable(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; + struct ww_acquire_ctx ww_ctx; int ret; - regulator_lock_dependent(rdev); + regulator_lock_dependent(rdev, &ww_ctx); regulator->uA_load = 0; ret = _regulator_force_disable(regulator->rdev); if (rdev->coupling_desc.n_coupled > 1) regulator_balance_voltage(rdev, PM_SUSPEND_ON); - regulator_unlock_dependent(rdev); + regulator_unlock_dependent(rdev, &ww_ctx); if (rdev->supply) while (rdev->open_count--) @@ -2518,9 +2625,10 @@ static void regulator_disable_work(struct work_struct *work) { struct regulator_dev *rdev = container_of(work, struct regulator_dev, disable_work.work); + struct ww_acquire_ctx ww_ctx; int count, i, ret; - regulator_lock(rdev); + regulator_lock_dependent(rdev, &ww_ctx); BUG_ON(!rdev->deferred_disables); @@ -2541,7 +2649,10 @@ static void regulator_disable_work(struct work_struct *work) rdev_err(rdev, "Deferred disable failed: %d\n", ret); } - regulator_unlock(rdev); + if (rdev->coupling_desc.n_coupled > 1) + regulator_balance_voltage(rdev, PM_SUSPEND_ON); + + regulator_unlock_dependent(rdev, &ww_ctx); if (rdev->supply) { for (i = 0; i < count; i++) { @@ -2652,9 +2763,9 @@ int regulator_is_enabled(struct regulator *regulator) if (regulator->always_on) return 1; - regulator_lock_dependent(regulator->rdev); + regulator_lock(regulator->rdev); ret = _regulator_is_enabled(regulator->rdev); - regulator_unlock_dependent(regulator->rdev); + regulator_unlock(regulator->rdev); return ret; } @@ -3268,7 +3379,7 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev, int tmp_min = 0; int tmp_max = INT_MAX; - lockdep_assert_held_once(&c_rdevs[i]->mutex); + lockdep_assert_held_once(&c_rdevs[i]->mutex.base); ret = regulator_check_consumers(c_rdevs[i], &tmp_min, @@ -3479,14 +3590,15 @@ static int regulator_balance_voltage(struct regulator_dev *rdev, */ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) { - int ret = 0; + struct ww_acquire_ctx ww_ctx; + int ret; - regulator_lock_dependent(regulator->rdev); + regulator_lock_dependent(regulator->rdev, &ww_ctx); ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, PM_SUSPEND_ON); - regulator_unlock_dependent(regulator->rdev); + regulator_unlock_dependent(regulator->rdev, &ww_ctx); return ret; } @@ -3558,18 +3670,19 @@ static int _regulator_set_suspend_voltage(struct regulator *regulator, int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, int max_uV, suspend_state_t state) { - int ret = 0; + struct ww_acquire_ctx ww_ctx; + int ret; /* PM_SUSPEND_ON is handled by regulator_set_voltage() */ if (regulator_check_states(state) || state == PM_SUSPEND_ON) return -EINVAL; - regulator_lock_dependent(regulator->rdev); + regulator_lock_dependent(regulator->rdev, &ww_ctx); ret = _regulator_set_suspend_voltage(regulator, min_uV, max_uV, state); - regulator_unlock_dependent(regulator->rdev); + regulator_unlock_dependent(regulator->rdev, &ww_ctx); return ret; } @@ -3759,13 +3872,12 @@ static int _regulator_get_voltage(struct regulator_dev *rdev) */ int regulator_get_voltage(struct regulator *regulator) { + struct ww_acquire_ctx ww_ctx; int ret; - regulator_lock_dependent(regulator->rdev); - + regulator_lock_dependent(regulator->rdev, &ww_ctx); ret = _regulator_get_voltage(regulator->rdev); - - regulator_unlock_dependent(regulator->rdev); + regulator_unlock_dependent(regulator->rdev, &ww_ctx); return ret; } @@ -4301,7 +4413,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { - lockdep_assert_held_once(&rdev->mutex); + lockdep_assert_held_once(&rdev->mutex.base); _notifier_call_chain(rdev, event, data); return NOTIFY_DONE; @@ -4669,7 +4781,7 @@ regulator_register(const struct regulator_desc *regulator_desc, rdev->dev.of_node = of_node_get(config->of_node); } - mutex_init(&rdev->mutex); + ww_mutex_init(&rdev->mutex, ®ulator_ww_class); rdev->reg_data = config->driver_data; rdev->owner = regulator_desc->owner; rdev->desc = regulator_desc; @@ -5026,8 +5138,6 @@ static void regulator_summary_show_subtree(struct seq_file *s, if (!rdev) return; - regulator_lock_nested(rdev, level); - opmode = _regulator_get_mode_unlocked(rdev); seq_printf(s, "%*s%-*s %3d %4d %6d %7s ", level * 3 + 1, "", @@ -5084,8 +5194,101 @@ static void regulator_summary_show_subtree(struct seq_file *s, class_for_each_device(®ulator_class, NULL, &summary_data, regulator_summary_show_children); +} + +struct summary_lock_data { + struct ww_acquire_ctx *ww_ctx; + struct regulator_dev **new_contended_rdev; + struct regulator_dev **old_contended_rdev; +}; + +static int regulator_summary_lock_one(struct device *dev, void *data) +{ + struct regulator_dev *rdev = dev_to_rdev(dev); + struct summary_lock_data *lock_data = data; + int ret = 0; + + if (rdev != *lock_data->old_contended_rdev) { + ret = regulator_lock_nested(rdev, lock_data->ww_ctx); + + if (ret == -EDEADLK) + *lock_data->new_contended_rdev = rdev; + else + WARN_ON_ONCE(ret); + } else { + *lock_data->old_contended_rdev = NULL; + } + + return ret; +} + +static int regulator_summary_unlock_one(struct device *dev, void *data) +{ + struct regulator_dev *rdev = dev_to_rdev(dev); + struct summary_lock_data *lock_data = data; + + if (lock_data) { + if (rdev == *lock_data->new_contended_rdev) + return -EDEADLK; + } regulator_unlock(rdev); + + return 0; +} + +static int regulator_summary_lock_all(struct ww_acquire_ctx *ww_ctx, + struct regulator_dev **new_contended_rdev, + struct regulator_dev **old_contended_rdev) +{ + struct summary_lock_data lock_data; + int ret; + + lock_data.ww_ctx = ww_ctx; + lock_data.new_contended_rdev = new_contended_rdev; + lock_data.old_contended_rdev = old_contended_rdev; + + ret = class_for_each_device(®ulator_class, NULL, &lock_data, + regulator_summary_lock_one); + if (ret) + class_for_each_device(®ulator_class, NULL, &lock_data, + regulator_summary_unlock_one); + + return ret; +} + +static void regulator_summary_lock(struct ww_acquire_ctx *ww_ctx) +{ + struct regulator_dev *new_contended_rdev = NULL; + struct regulator_dev *old_contended_rdev = NULL; + int err; + + ww_acquire_init(ww_ctx, ®ulator_ww_class); + + do { + if (new_contended_rdev) { + ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); + old_contended_rdev = new_contended_rdev; + old_contended_rdev->ref_cnt++; + } + + err = regulator_summary_lock_all(ww_ctx, + &new_contended_rdev, + &old_contended_rdev); + + if (old_contended_rdev) + regulator_unlock(old_contended_rdev); + + } while (err == -EDEADLK); + + ww_acquire_done(ww_ctx); +} + +static void regulator_summary_unlock(struct ww_acquire_ctx *ww_ctx) +{ + class_for_each_device(®ulator_class, NULL, NULL, + regulator_summary_unlock_one); + ww_acquire_fini(ww_ctx); } static int regulator_summary_show_roots(struct device *dev, void *data) @@ -5101,12 +5304,18 @@ static int regulator_summary_show_roots(struct device *dev, void *data) static int regulator_summary_show(struct seq_file *s, void *data) { + struct ww_acquire_ctx ww_ctx; + seq_puts(s, " regulator use open bypass opmode voltage current min max\n"); seq_puts(s, "---------------------------------------------------------------------------------------\n"); + regulator_summary_lock(&ww_ctx); + class_for_each_device(®ulator_class, NULL, s, regulator_summary_show_roots); + regulator_summary_unlock(&ww_ctx); + return 0; } diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index a05d37d0efa1..e71f9c314426 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -20,6 +20,7 @@ #include #include #include +#include struct gpio_desc; struct regmap; @@ -462,7 +463,7 @@ struct regulator_dev { struct coupling_desc coupling_desc; struct blocking_notifier_head notifier; - struct mutex mutex; /* consumer lock */ + struct ww_mutex mutex; /* consumer lock */ struct task_struct *mutex_owner; int ref_cnt; struct module *owner; From patchwork Fri Oct 5 15:36:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10628321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B4A76933 for ; Fri, 5 Oct 2018 15:38:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABB132978B for ; Fri, 5 Oct 2018 15:38:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E5C029793; Fri, 5 Oct 2018 15:38:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 4EB052978B for ; Fri, 5 Oct 2018 15:38:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729266AbeJEWhX (ORCPT ); Fri, 5 Oct 2018 18:37:23 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:37215 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729207AbeJEWhW (ORCPT ); Fri, 5 Oct 2018 18:37:22 -0400 Received: by mail-lf1-f65.google.com with SMTP id a82-v6so9672661lfa.4; Fri, 05 Oct 2018 08:38:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UZHpftr3JSRuEiiI9LoXz1EWRn5YkY8aK0AfN/Lg3qU=; b=beRsK5HLfk7ef+GH66rRGsLw0jY6BoicGoJvVLy61Ccvk2ZsAn98F1m/+nhD3Yztjc J1x85KKZIiZMoHxRhSFcYL6KuNE3MqbyJ8o5VuOvBiLuNTA/h0bg9wL5rBDKnz+6HAbC PyOsmqGlTvzywQ5LZoz04RblKyBG2fdid59MHl3P3jxjg/I+aDxVh5MilqwQdhpZUBZ0 GcZyL2hnDr3WfT+wGHTkujvr7G6LzXyHJPhpjZlUaqov2lVUJeDQvFFQPNOr0vNKkc0q zf67CpKc/xAJuz4brxAuYU7ZTW8ihAaaG+J+DxbvwiztWYiYKgEuoqP4rULNdRNb8hrQ 8zHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UZHpftr3JSRuEiiI9LoXz1EWRn5YkY8aK0AfN/Lg3qU=; b=F86sX6V4hrcbC7fXKfDQI/jLopzEedxvVp6RQiwfNyIhxM+9fk4RYxnJGCy7fUt0eM 4GCAxcnMP+e701Ki/45NKz30zqJ5RFm/z4MTfxBdhdbHFnmiR31dyDZ/SBDBTfCDn0S1 4OsQbVUhkhbaJ17L9sT8ipkf+C9pyKgc/FEAH7Y8XCq355/ANn9ChkRE6eUvkfe0HH7D 6K+3hQGDJA/JVEP6RrOxAJ0ltkCF4U0JCLV1d6RV2txmSJ15ruF6G7RTO8zCBsoIrNsF w9jSHw64oyjALn+4t9qMvcER0EgkjiXvG2sZQ6qmVC1WeyFNXJJ4S0OPwyYjnDz7oxiT G74g== X-Gm-Message-State: ABuFfogYR+vz2JZP5WfEypdn03bqlCSvLN+WWvJ0+bnxRCQpGlvVFWKX c58hZi/9uvxU0YT/oKXvxAM= X-Google-Smtp-Source: ACcGV62/aQ0mOeWHjKv3Vc+cgbZ8RvPlRMWhzEY4FL5C55MZSawrxPO3uU3eS8IIjCILVqTHigmOFg== X-Received: by 2002:ac2:4299:: with SMTP id m25-v6mr6873095lfh.115.1538753886533; Fri, 05 Oct 2018 08:38:06 -0700 (PDT) Received: from localhost.localdomain (109-252-91-213.nat.spd-mgts.ru. [109.252.91.213]) by smtp.gmail.com with ESMTPSA id w22-v6sm1879373lfd.72.2018.10.05.08.38.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 08:38:06 -0700 (PDT) From: Dmitry Osipenko To: Mark Brown , Rob Herring , Maciej Purski Cc: Thierry Reding , Jonathan Hunter , Peter De Schrijver , Lucas Stach , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v1 11/11] regulator: core: Properly handle case where supply is the couple Date: Fri, 5 Oct 2018 18:36:38 +0300 Message-Id: <20181005153638.1886-12-digetx@gmail.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005153638.1886-1-digetx@gmail.com> References: <20181005153638.1886-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Check whether supply regulator is the couple to avoid infinite recursion during of locking. Signed-off-by: Dmitry Osipenko --- drivers/regulator/core.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a3448636f334..46e816cb80b5 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -233,6 +233,21 @@ static void regulator_unlock(struct regulator_dev *rdev) mutex_unlock(®ulator_nesting_mutex); } +static bool regulator_supply_is_couple(struct regulator_dev *rdev) +{ + struct regulator_dev *c_rdev; + int i; + + for (i = 1; i < rdev->coupling_desc.n_coupled; i++) { + c_rdev = rdev->coupling_desc.coupled_rdevs[i]; + + if (rdev->supply->rdev == c_rdev) + return true; + } + + return false; +} + static void regulator_unlock_recursive(struct regulator_dev *rdev, unsigned int n_coupled) { @@ -245,7 +260,7 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev, if (!c_rdev) continue; - if (c_rdev->supply) + if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) regulator_unlock_recursive( c_rdev->supply->rdev, c_rdev->coupling_desc.n_coupled); @@ -283,7 +298,7 @@ static int regulator_lock_recursive(struct regulator_dev *rdev, *old_contended_rdev = NULL; } - if (c_rdev->supply) { + if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) { err = regulator_lock_recursive(c_rdev->supply->rdev, new_contended_rdev, old_contended_rdev,