From patchwork Thu Dec 21 06:25:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122507 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485372qgn; Wed, 20 Dec 2017 22:25:53 -0800 (PST) X-Google-Smtp-Source: ACJfBotHifvQeHxX3o0jiGQbGma06fd5fGofXHXhTwTF0bXJNjQJCM7m5Sz1ZQqx/frbZwZv/hST X-Received: by 10.101.87.196 with SMTP id q4mr8523716pgr.97.1513837553505; Wed, 20 Dec 2017 22:25:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837553; cv=none; d=google.com; s=arc-20160816; b=tfNYTkji2xP5ohlDA19geJ0O0GfWKRIOode3/0w36pGuLQ3zq52qyHPpgEnl7K2wwX 10j88oIG/tretkXKbxOrOvsZAmQBG3+XYztCJf1TjXhd4L+oGJv+wVtaDJwRHpRmAlqY tHfDCBXJWyjL3y7XMqgTEyqYIo9+fDT8mcMks75jP+YfecyKuNAcwWbV8+GyzJb2koOv lrqaClHAISvK9X1mIiaLbP/oQQauMlHwKAybdmeSlE3x0o1QMqE9zKB4sCnYCX71XNRd OWBeRlQsVq9uJKznK2uLASMhlyESBbCX4i5ltYw+s0DjCzzP1iZGVjLBUoUXmsuddsuv Qadg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=lwxr/JX9up7CZWToUBwiLBHijg8812UOtJKl7VnVStM=; b=kL84t2A5dU2cyewZvvvH+SzTBJeSPNQkX9L8Hghtl1U+FR9U3JrDdUBUZF7kwOxJRn MPAc/CIgGpXiCrLzc0A67J7xF+T8LiPC+SVA8WOoeB4Z4j32u42+b07VVOA77JzlIE9p IHzPFrJqs8PdFuPYwsvg+ENomJmgXrPtWBc41BrFUIvoOvCZvpiM7CONNdoAbjImMLmf RsfdArkWMRy8c+ibNemoGcDq4sD5dCrChqxuFu6MaX6EzxoehoXB6ZoqXqYC0kxQ6lkk I/upZZ5ltnTol1RbsxInmgCy9RBd77ZiGQ/hvmJaRa10KBonFesoF9zU07e0ojFYcsZB l4ng== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=E7YnqXxh; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si1638719pgf.122.2017.12.20.22.25.53; Wed, 20 Dec 2017 22:25:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=E7YnqXxh; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751664AbdLUGZe (ORCPT + 6 others); Thu, 21 Dec 2017 01:25:34 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:42513 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751573AbdLUGZb (ORCPT ); Thu, 21 Dec 2017 01:25:31 -0500 Received: by mail-pg0-f66.google.com with SMTP id q67so3676789pga.9 for ; Wed, 20 Dec 2017 22:25:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UvcyV8RmS5y5eeeYbAr1fqc8e4aEZkeqcBrkNVTHW6g=; b=E7YnqXxhtRJT47pMFsN3+OfTlj3d8n7f0DQL8THxkpyHj+1KTEWDGHvEd4oLh7oU3O 0QuhZqGwSGfinqVo4dMQz722QN1SBpRFqfA1hZxIsjjwzDuJ2AL9m9S1dLg/mOX3b1Na vpLZXjew48/mdAreza5vEkV73/ni2xh9RmLXs= 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; bh=UvcyV8RmS5y5eeeYbAr1fqc8e4aEZkeqcBrkNVTHW6g=; b=P09FAR7GNnlMDLXaGBWXcQxGCUiDJ/IeJbIMB0d1fJcwCMo1TvorAVwQ81GJCf6JLW NypCmZzOq6ZqwxKpKPqquTFMQFDlDmhNQZDwI12Gj0DvkklMKTmI7Y8JLz7LZyUbKYNK CKedU8PpIHvmtpPTWpHIKcUUZzGLbZijSoOs5FxmoOLItJ6/Tzvgfcsr4CHk1/pHliik 2AeVAsYHgaqZboBjgQTwDpGd/jFl/nKCxYcQfCN8U9S/uw6iWJISSvUQ1XvHf716nwrd jsEdXvtj7VUA7YZCwK5ww5jsXLZRDw9K66MGYes/z0KlrUgxdGkkEjb8NKOH9ES1ze9u D46w== X-Gm-Message-State: AKGB3mIyUv9MoH3r/8d0HRSJGIldc7xCUV6TSIyJ8vbTRaAJEpwVOJG8 BCzVUbY7vkrfs+0J3RcKqk0JSXkKJaU= X-Received: by 10.101.101.148 with SMTP id u20mr8731491pgv.12.1513837530649; Wed, 20 Dec 2017 22:25:30 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:29 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 1/5] bindings: regulator: added support for suspend states Date: Thu, 21 Dec 2017 14:25:02 +0800 Message-Id: <1513837506-26543-2-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Documented a few new added properties which are used for supporting regulator suspend states. Signed-off-by: Chunyan Zhang --- Documentation/devicetree/bindings/regulator/regulator.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 378f6dc..618a322 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -42,8 +42,15 @@ Optional properties: - regulator-state-[mem/disk] node has following common properties: - regulator-on-in-suspend: regulator should be on in suspend state. - regulator-off-in-suspend: regulator should be off in suspend state. - - regulator-suspend-microvolt: regulator should be set to this voltage - in suspend. + - regulator-suspend-min-microvolt: minimum voltage may be set in + suspend state. + - regulator-suspend-max-microvolt: maximum voltage may be set in + suspend state. + - regulator-suspend-microvolt: the default voltage which regulator + should be set in suspend, this can be adjusted among + + - regulator-changeable-in-suspend: whether the default voltage and + the regulator on/off in suspend can be changed in runtime. - regulator-mode: operating mode in the given suspend state. The set of possible operating modes depends on the capabilities of every hardware so the valid modes are documented on each regulator From patchwork Thu Dec 21 06:25:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122508 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485377qgn; Wed, 20 Dec 2017 22:25:53 -0800 (PST) X-Google-Smtp-Source: ACJfBotsqVz4m5mEHBFC9l4OT5ToSzS12wq4SYEk6wap9DQ5qHPZzOlryxSJvhjl4QJSD7YlLx9e X-Received: by 10.98.152.25 with SMTP id q25mr9522993pfd.58.1513837553799; Wed, 20 Dec 2017 22:25:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837553; cv=none; d=google.com; s=arc-20160816; b=tQe+iNVmEre9RqOwgjCQ2P+d0gJc5Q4IN61bChh0Epmr9DVSlKdrr9zs08COgTzquF Noi/P3t2+SQCK6vAQD0MJyTZCRuSOaFN2xne2GTyBs+PuBqoXmTCMGZ+8kuAvc6H5MUB j2Ugm31RTjkEvJPAxLm7N1l9VHI9itW6qkfg9PHlas/7EWaPSKuWWrFPR/8HN0yCw8dI S0kW3Zl1ZKBVDHN3u7AmBgRroq34Hde3HpWTJ5hVhNQ47xvT/x4ebGAjeolSWfTvePFV eCpYfOttCe4iwv8bM03SG7mZ96UMz0qTTFCjW1MROAAf6Y713tRfXzU3LjAKXuA0JGmT 6GJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=3fGcyQm5MzO+IikfJbd6xonOoxnRNHYtVLII8nMPgX0=; b=D45o04ZpeMAHIJ9LqJtTrPeaaGI3XFx7ki+xnqvdG280L/O6hCp1pDkNPLyF8ymUil 10w04aynEv6DJt0pQw0/hpsrRxjZvDeqzB1v/SoDODzc+mbm8mQC7yVVIAltgewDCWo2 8HDv8Nv+gDR8jE1KYfJWyPD6pbmSXGGUaHY8nAtoluRJJVHN0CWT0B0uSM58nLFuJlB8 U35uV4lGVLRzjLnRt4pKxwYhoeAc5SeNnGkq73ZLmPD+ZSc+IVOY/6vzK5rJ53s6jOwY 1e6RGpZv5rDJfWnTCRUDk6kstyuZbTpNcxNRzUpqFWx9VXRLXqc4y6W1NJeOQSFtKw8Y D0cA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eX6Vge1q; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si1638719pgf.122.2017.12.20.22.25.53; Wed, 20 Dec 2017 22:25:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eX6Vge1q; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751845AbdLUGZj (ORCPT + 6 others); Thu, 21 Dec 2017 01:25:39 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:37217 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751716AbdLUGZe (ORCPT ); Thu, 21 Dec 2017 01:25:34 -0500 Received: by mail-pg0-f66.google.com with SMTP id o13so2162052pgp.4 for ; Wed, 20 Dec 2017 22:25:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=eX6Vge1qKc8YJXP+/p2ZXlXm9/VKCs70YVs1h35EWr43H9RgTCQyvSI6umkV0cfPKB J3C4gBvphZH9ZWNZ2JTirgwV4/emwTAIPEd9pG69n7RtB/nBC6r4kq9Lgr/Y2GB+kZ/T ML04qIFj+9rVKvH96oZztMPM3bIRy4bSkZZNo= 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; bh=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=GX3c4M5G+D+OqVdSTcCgayICQLGeurtz3uKoexxMzuuqi83IYp9OUM1YnjsTh9JnWC UQEvOhy4xqiXHCKvM5qyDuX4waFJpRTIO4Ut/J6moQ1o8DskCpmrDmzce67LpWwaiM+4 oN1x5/rHPdKeVgPrKyafhd8lFEyHLvVfps28U1kgrObXiRA7wclqGcs6RrSkFV76SHQ6 ttnQSBC4U2BSI1i8/ghdDrpRqdkbLYXch1aHkiuOnLwsVfVrAZyMeYTYR0HbSVsAxwYb hk2dM131+Ek61VxFqPGfDB8fEiIg/GL+095HnOD4yd28zG8rtPxT7YnGM5xPC/5b5vtu 3Qeg== X-Gm-Message-State: AKGB3mIlHyqMf57acKnRl1cC75MXTGK8jRlwLkse/n4nKMEGgahffN5Y +sTZA/TGVkcrJbnFyM8i0Q1ijw== X-Received: by 10.98.109.65 with SMTP id i62mr9359319pfc.139.1513837534213; Wed, 20 Dec 2017 22:25:34 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:33 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 2/5] regulator: make regulator voltage be an array to support more states Date: Thu, 21 Dec 2017 14:25:03 +0800 Message-Id: <1513837506-26543-3-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Some regulator consumers would like to make the regulator device keeping a voltage range output when the system entering into suspend states. Making regulator voltage be an array can allow consumers to set voltage for normal state as well as for suspend states through the same code. Signed-off-by: Chunyan Zhang --- drivers/regulator/core.c | 63 ++++++++++++++++++++++++-------------------- drivers/regulator/internal.h | 18 +++++++++++-- 2 files changed, 51 insertions(+), 30 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b64b791..97bc9f7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -240,22 +240,25 @@ static int regulator_check_voltage(struct regulator_dev *rdev, * regulator consumers */ static int regulator_check_consumers(struct regulator_dev *rdev, - int *min_uV, int *max_uV) + int *min_uV, int *max_uV, + suspend_state_t state) { struct regulator *regulator; + struct regulator_voltage *voltage; list_for_each_entry(regulator, &rdev->consumer_list, list) { + voltage = ®ulator->voltage[state]; /* * Assume consumers that didn't say anything are OK * with anything in the constraint range. */ - if (!regulator->min_uV && !regulator->max_uV) + if (!voltage->min_uV && !voltage->max_uV) continue; - if (*max_uV > regulator->max_uV) - *max_uV = regulator->max_uV; - if (*min_uV < regulator->min_uV) - *min_uV = regulator->min_uV; + if (*max_uV > voltage->max_uV) + *max_uV = voltage->max_uV; + if (*min_uV < voltage->min_uV) + *min_uV = voltage->min_uV; } if (*min_uV > *max_uV) { @@ -1356,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, debugfs_create_u32("uA_load", 0444, regulator->debugfs, ®ulator->uA_load); debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->min_uV); + ®ulator->voltage[PM_SUSPEND_ON].min_uV); debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->max_uV); + ®ulator->voltage[PM_SUSPEND_ON].max_uV); debugfs_create_file("constraint_flags", 0444, regulator->debugfs, regulator, &constraint_flags_fops); @@ -2898,9 +2901,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, } static int regulator_set_voltage_unlocked(struct regulator *regulator, - int min_uV, int max_uV) + int min_uV, int max_uV, + suspend_state_t state) { struct regulator_dev *rdev = regulator->rdev; + struct regulator_voltage *voltage = ®ulator->voltage[state]; int ret = 0; int old_min_uV, old_max_uV; int current_uV; @@ -2911,7 +2916,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, * should be a noop (some cpufreq implementations use the same * voltage for multiple frequencies, for example). */ - if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) + if (voltage->min_uV == min_uV && voltage->max_uV == max_uV) goto out; /* If we're trying to set a range that overlaps the current voltage, @@ -2921,8 +2926,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) { current_uV = _regulator_get_voltage(rdev); if (min_uV <= current_uV && current_uV <= max_uV) { - regulator->min_uV = min_uV; - regulator->max_uV = max_uV; + voltage->min_uV = min_uV; + voltage->max_uV = max_uV; goto out; } } @@ -2940,12 +2945,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, goto out; /* restore original values in case of error */ - old_min_uV = regulator->min_uV; - old_max_uV = regulator->max_uV; - regulator->min_uV = min_uV; - regulator->max_uV = max_uV; + old_min_uV = voltage->min_uV; + old_max_uV = voltage->max_uV; + voltage->min_uV = min_uV; + voltage->max_uV = max_uV; - ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state); if (ret < 0) goto out2; @@ -2982,7 +2987,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (supply_change_uV > 0) { ret = regulator_set_voltage_unlocked(rdev->supply, - best_supply_uV, INT_MAX); + best_supply_uV, INT_MAX, state); if (ret) { dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", ret); @@ -2996,7 +3001,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (supply_change_uV < 0) { ret = regulator_set_voltage_unlocked(rdev->supply, - best_supply_uV, INT_MAX); + best_supply_uV, INT_MAX, state); if (ret) dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", ret); @@ -3007,8 +3012,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, out: return ret; out2: - regulator->min_uV = old_min_uV; - regulator->max_uV = old_max_uV; + voltage->min_uV = old_min_uV; + voltage->max_uV = old_max_uV; return ret; } @@ -3037,7 +3042,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) regulator_lock_supply(regulator->rdev); - ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV); + ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, + PM_SUSPEND_ON); regulator_unlock_supply(regulator->rdev); @@ -3138,6 +3144,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); int regulator_sync_voltage(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; + struct regulator_voltage *voltage = ®ulator->voltage[PM_SUSPEND_ON]; int ret, min_uV, max_uV; mutex_lock(&rdev->mutex); @@ -3149,20 +3156,20 @@ int regulator_sync_voltage(struct regulator *regulator) } /* This is only going to work if we've had a voltage configured. */ - if (!regulator->min_uV && !regulator->max_uV) { + if (!voltage->min_uV && !voltage->max_uV) { ret = -EINVAL; goto out; } - min_uV = regulator->min_uV; - max_uV = regulator->max_uV; + min_uV = voltage->min_uV; + max_uV = voltage->max_uV; /* This should be a paranoia check... */ ret = regulator_check_voltage(rdev, &min_uV, &max_uV); if (ret < 0) goto out; - ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0); if (ret < 0) goto out; @@ -4424,8 +4431,8 @@ static void regulator_summary_show_subtree(struct seq_file *s, switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%37dmV %5dmV", - consumer->min_uV / 1000, - consumer->max_uV / 1000); + consumer->voltage[PM_SUSPEND_ON].min_uV / 1000, + consumer->voltage[PM_SUSPEND_ON].max_uV / 1000); break; case REGULATOR_CURRENT: break; diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 66a8ea0..aba8e414 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -16,10 +16,25 @@ #ifndef __REGULATOR_INTERNAL_H #define __REGULATOR_INTERNAL_H +#include + +#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1) + +struct regulator_voltage { + int min_uV; + int max_uV; +}; + /* * struct regulator * * One for each consumer device. + * @voltage - a voltage array for each state of runtime, i.e.: + * PM_SUSPEND_ON + * PM_SUSPEND_TO_IDLE + * PM_SUSPEND_STANDBY + * PM_SUSPEND_MEM + * PM_SUSPEND_MAX */ struct regulator { struct device *dev; @@ -27,8 +42,7 @@ struct regulator { unsigned int always_on:1; unsigned int bypass:1; int uA_load; - int min_uV; - int max_uV; + struct regulator_voltage voltage[REGULATOR_STATES_NUM]; const char *supply_name; struct device_attribute dev_attr; struct regulator_dev *rdev; From patchwork Thu Dec 21 06:25:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122509 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485390qgn; Wed, 20 Dec 2017 22:25:54 -0800 (PST) X-Google-Smtp-Source: ACJfBovSZc8FCKCyQXGm0T2hp93wUgl6g35TjHHjY7H5sJRC1KNqhyYhomItSjBI8FL9CbPzh2sn X-Received: by 10.101.100.199 with SMTP id t7mr8848844pgv.316.1513837554787; Wed, 20 Dec 2017 22:25:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837554; cv=none; d=google.com; s=arc-20160816; b=Dtqbf7iXHqjqgoL0ps4gy2hnSeAyQxLyyYASl/gXeaCtkUOuZWU8x6am4wsP8dvOrk EYIWbInfynPE7d+gKzrmQTMzxIDaRYjPxNEdqjf/EXbTBHmhgbvMyOR/7PHlUPAV6Am/ c/5W/K9EuAp3TokakswWmgCjpmHBljpdzznAxX3+lSKbfLVwBtKvhMYaGEJqPaevz0ds PHZxMWhIdxZVWHmYYQsuxkbfqRCIGEuqhuJvDzajzkYCaKUtO3V4GAbv5WC6f2enLQc8 GXxo9cRKdVf5yuAt3kYgpq0nPrZndpQBu/hG7bLKcSMh7JJF8rB9o5jghyVxTfEG7SMV EbOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=jkvcWkCfs/3yJIIexrdCvn3amSwEvdN47NDvBiInvw4=; b=vjFTJK1dBbLHv6xAqLTRyC+L6UXEgR0SXnkHeyV2fQP/EkkdN1I0QzJuln4uhjz2Xt tY1wSWJVpfBPQ2ko7LyGEzEdLDNdWxDIxdTXT5FRdMFNQFdOflVt8yBhmwS+ipIPSqVH xU04VEe+FKfx73SNW1W4TlN11RBfRg25O91E+X4o1/pkEo/kluXRPABVAHeROEszKpmf Gqsa3j1EvxbY69aGMehcfi1Ji153QXGGnQgGBBH/ST5OTDnbm55y3/ePU6C1Zc/U89OR jeb3gJk8MBpchyeIqz1GLzWcgFQF3XNE6wb9UqBnkTZWDK+eUZM3666CiSvgHypeTAdi fjzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=E+Wo7OsH; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si1638719pgf.122.2017.12.20.22.25.54; Wed, 20 Dec 2017 22:25:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=E+Wo7OsH; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932086AbdLUGZq (ORCPT + 6 others); Thu, 21 Dec 2017 01:25:46 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:42522 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751838AbdLUGZj (ORCPT ); Thu, 21 Dec 2017 01:25:39 -0500 Received: by mail-pg0-f67.google.com with SMTP id q67so3676890pga.9 for ; Wed, 20 Dec 2017 22:25:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9azF0a/CRva7kzQyUrrdYveI6VR5wsw/N+Df49tk6LE=; b=E+Wo7OsHXkqF3GZo2d2MX6ssnUyTUjv3g5/Z9bC+MnmY6kbDXku8/muHKzrcr2ayTy 11SqJQTzdGYBMoXPtXPlcRWjDf7JW2ubxniMhYpCD3RPGQthONTsW0vWTP1xoJdXmrcH IuHEBkDRX8MwFPjbfZK728KBri2j1umI3qEgM= 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; bh=9azF0a/CRva7kzQyUrrdYveI6VR5wsw/N+Df49tk6LE=; b=AYfyS4jcpq1jBvRajRM6n4/a+xc3WQDz/4qkHBwN10kpNzYiLuouiFxn7xxUhdqXdN ES48F2CnHE0B05XM35sD5xWc2++hY7o1ktREvXGmtOsjoc39GOpeGHDy0B6xUHbWH6km PPkfjTL+M0qLq8F2nRL0/+3+wmi+3l17EPCsYxchVp0GauSOpNfPVKyFjzmQ1QiGoA7U W/7n48E1XnIXWGgSqgfudX8EF/WWAOlzw7uqyRneyJLL7cLJfmxC4Iq+bq51rTyFC0zw 1uU2Kgnb03a+p8UDXD2YB9UxPmtS0T70fpYHexn23gX3r1QBDqXfyIu5FNpOW7aCxN3U TYeQ== X-Gm-Message-State: AKGB3mJd9StFwRiaDKfQA4gn81Ak5rEch4kN0vOoAOhCct4BSHzkweK5 c7B4Ve303mjrmXhpiLtCcXi48w== X-Received: by 10.99.157.206 with SMTP id i197mr8522605pgd.409.1513837538899; Wed, 20 Dec 2017 22:25:38 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:38 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 3/5] drivers: regulator: leave one item to record whether regulator is enabled Date: Thu, 21 Dec 2017 14:25:04 +0800 Message-Id: <1513837506-26543-4-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The items "disabled" and "enabled" are a little redundant, since only one of them would be set to record if the regulator device should keep on or be switched to off in suspend states. So in this patch, the "disabled" was removed, only leave the "enabled": - enabled == 1 for regulator-on-in-suspend - enabled == 0 for regulator-off-in-suspend - enabled == -1 means do nothing when entering suspend mode. Signed-off-by: Chunyan Zhang --- drivers/regulator/core.c | 14 ++++++-------- drivers/regulator/of_regulator.c | 6 ++++-- include/linux/regulator/machine.h | 12 +++++++++--- 3 files changed, 19 insertions(+), 13 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 97bc9f7..5ea80e9 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -742,21 +742,19 @@ static int suspend_set_state(struct regulator_dev *rdev, * only warn if the driver implements set_suspend_voltage or * set_suspend_mode callback. */ - if (!rstate->enabled && !rstate->disabled) { + if (rstate->enabled != ENABLE_IN_SUSPEND && + rstate->enabled != DISABLE_IN_SUSPEND) { if (rdev->desc->ops->set_suspend_voltage || rdev->desc->ops->set_suspend_mode) rdev_warn(rdev, "No configuration\n"); return 0; } - if (rstate->enabled && rstate->disabled) { - rdev_err(rdev, "invalid configuration\n"); - return -EINVAL; - } - - if (rstate->enabled && rdev->desc->ops->set_suspend_enable) + if (rstate->enabled == ENABLE_IN_SUSPEND && + rdev->desc->ops->set_suspend_enable) ret = rdev->desc->ops->set_suspend_enable(rdev); - else if (rstate->disabled && rdev->desc->ops->set_suspend_disable) + else if (rstate->enabled == DISABLE_IN_SUSPEND && + rdev->desc->ops->set_suspend_disable) ret = rdev->desc->ops->set_suspend_disable(rdev); else /* OK if set_suspend_enable or set_suspend_disable is NULL */ ret = 0; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 14637a0..41dad42 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -177,10 +177,12 @@ static void of_get_regulation_constraints(struct device_node *np, if (of_property_read_bool(suspend_np, "regulator-on-in-suspend")) - suspend_state->enabled = true; + suspend_state->enabled = ENABLE_IN_SUSPEND; else if (of_property_read_bool(suspend_np, "regulator-off-in-suspend")) - suspend_state->disabled = true; + suspend_state->enabled = DISABLE_IN_SUSPEND; + else + suspend_state->enabled = DO_NOTHING_IN_SUSPEND; if (!of_property_read_u32(suspend_np, "regulator-suspend-microvolt", &pval)) diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 9cd4fef..e50519f 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -42,6 +42,11 @@ struct regulator; #define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_BYPASS 0x20 +/* operations in suspend mode */ +#define DO_NOTHING_IN_SUSPEND (-1) +#define DISABLE_IN_SUSPEND 0 +#define ENABLE_IN_SUSPEND 1 + /* Regulator active discharge flags */ enum regulator_active_discharge { REGULATOR_ACTIVE_DISCHARGE_DEFAULT, @@ -58,14 +63,15 @@ enum regulator_active_discharge { * * @uV: Operating voltage during suspend. * @mode: Operating mode during suspend. - * @enabled: Enabled during suspend. - * @disabled: Disabled during suspend. + * @enabled: operations during suspend. + * - DO_NOTHING_IN_SUSPEND + * - DISABLE_IN_SUSPEND + * - ENABLE_IN_SUSPEND */ struct regulator_state { int uV; /* suspend voltage */ unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ - int disabled; /* is the regulator disabled in this suspend state */ }; /** From patchwork Thu Dec 21 06:25:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122511 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485795qgn; Wed, 20 Dec 2017 22:26:29 -0800 (PST) X-Google-Smtp-Source: ACJfBou0nElrNh0+PKLKRwQd8XIm7eECH85Zfsrw28ZcRujgE1wu8oodQCTV5QOGS3hE4E3scEyH X-Received: by 10.84.233.72 with SMTP id k8mr9296669plt.420.1513837589096; Wed, 20 Dec 2017 22:26:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837589; cv=none; d=google.com; s=arc-20160816; b=dLFtRzTw3iJIXRD+OD75zb8Gqky4OUJ8zGkcMGlmfATX3xOcmLJjbBKKBUJ7HPRGso bXDtyX+Xsr0Hez3EWsQZy0j9ZHGSTYmOz+ZrywMBSm8tQXvdnqybEYluPvtR1UTk6c53 t7sF0ts0MTCfZ4CzzSk7g332orlX0zEEHPWGWWgyqzutjmBtRWmRLanALl7WCnNvNz2S k33bTQVTJjqfN2SyaYAVedtNQwQb3q78SKJ+5yox3oCM77UloR4/OqUkx72xoY1lSzx7 pzC5zxi+SBatJsRguCDgLcL0PAUGMnLeX9dn0+oPr0lF2+Bt7sBJuoZSqx7pF2aOBRgO Tj3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=lYsYhI3Z/pRWMn6HIFpDfVEtWIA+2IFgvZw8KvlZzeA=; b=Q+I3yv84NilhbEO5mupANyZ4VjeLxZLpJNHR310cS8tWMTOjXvmy1Hd2xi+JdWTK7C 5Hr1BWCZRrhb+xYuv37NjjjVThXquOLYZPR5bj0thyuOv3BJE1JycVD53ELvOHhNvzGp MlIsC3uqzi9lj0xE//So3PJD0BFr5QG1FZmzK+LKE2dgcpwhfRBSM7thbsmr8LdNYAm2 MY0gnuRqKsAxeWZbLtwt+6LkBBSprCss1dw8oa+SBL3k+fVgVBZqIvOk98eMKLDTAM7f WGjnLF3i6lVdGyI0fxx7qK3Qd9JHaJOLMkMvtggEC/Fp0AW2tOavSL5HqQfDDcY0bKJI R9Uw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Z9blwrdO; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o1si14065420plk.131.2017.12.20.22.26.28; Wed, 20 Dec 2017 22:26:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Z9blwrdO; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932569AbdLUG01 (ORCPT + 6 others); Thu, 21 Dec 2017 01:26:27 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:42491 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752146AbdLUGZp (ORCPT ); Thu, 21 Dec 2017 01:25:45 -0500 Received: by mail-pf0-f193.google.com with SMTP id d23so13590558pfe.9 for ; Wed, 20 Dec 2017 22:25:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nHRvBhsC1LnmuY+PtNiblL3WT5zYTHI7fmJowkn1glI=; b=Z9blwrdOeh1aY3DHYz88wg/8ETo/DmW7vOphilPcQz+/uw9Ym2VwhKwJJsLGs0qJDz eixMXz3T7Ye12EuH83FMcgIhTDOmYn95wFHf0t7AN0ZbA/NFjaI3+qWibqzCMNWRtEPX Wm3eVJpKrb2Ozzu+GbA9GQWEH1BvDFVE9SW6k= 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; bh=nHRvBhsC1LnmuY+PtNiblL3WT5zYTHI7fmJowkn1glI=; b=KXsBgFUepqBARMzxu+spZl7MhsZSd4GD+WDWwBDCDrnMPVbh3gSbT0A2D1dT8Xd+PD ZToqla4Y1qnch2by22P2qrZezV1R1/yS1W/0bSytIX+f/4mK/fSzlPFJD8s+K427HURf M9VzMYywUnMWuRdL2yjuTHGQoL7R+GkttDbMYvW/1jjyUqyR51S855GOyEKJS0Ftws7g i6DQqCcgrJhh2DYinDElBT1nbGostXKqWLUo/bnun8nfjd8jCqSPVR49F46xwMwDXGmo ewe03jOU5t5RRq+Mjl7wjiUwUmx6CdtndBm56KEK0FCwVp88OOHl7woVvj3cHu3VmZrZ j/hg== X-Gm-Message-State: AKGB3mJx0CC47Q9775nL0GJo+PFUfWJBae+EM103w+jON8Ik/zULbjqh ttmbhjTsdoalzMPW+Q2qlPa6Fg== X-Received: by 10.98.0.19 with SMTP id 19mr9387422pfa.136.1513837545345; Wed, 20 Dec 2017 22:25:45 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:44 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 4/5] drivers: regulator: empty the old suspend functions Date: Thu, 21 Dec 2017 14:25:05 +0800 Message-Id: <1513837506-26543-5-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Regualtor suspend/resume functions should only be called by PM suspend core via registering dev_pm_ops, and regulator devices should implement the callback functions. Thus, any regulator consumer shouldn't call the regulator suspend/resume functions directly. In order to avoid compile errors, two empty functions with the same name still be left for the time being. Signed-off-by: Chunyan Zhang --- drivers/regulator/core.c | 74 --------------------------------------- include/linux/regulator/machine.h | 5 ++- 2 files changed, 2 insertions(+), 77 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5ea80e9..080c233 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4179,80 +4179,6 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); -static int _regulator_suspend_prepare(struct device *dev, void *data) -{ - struct regulator_dev *rdev = dev_to_rdev(dev); - const suspend_state_t *state = data; - int ret; - - mutex_lock(&rdev->mutex); - ret = suspend_prepare(rdev, *state); - mutex_unlock(&rdev->mutex); - - return ret; -} - -/** - * regulator_suspend_prepare - prepare regulators for system wide suspend - * @state: system suspend state - * - * Configure each regulator with it's suspend operating parameters for state. - * This will usually be called by machine suspend code prior to supending. - */ -int regulator_suspend_prepare(suspend_state_t state) -{ - /* ON is handled by regulator active state */ - if (state == PM_SUSPEND_ON) - return -EINVAL; - - return class_for_each_device(®ulator_class, NULL, &state, - _regulator_suspend_prepare); -} -EXPORT_SYMBOL_GPL(regulator_suspend_prepare); - -static int _regulator_suspend_finish(struct device *dev, void *data) -{ - struct regulator_dev *rdev = dev_to_rdev(dev); - int ret; - - mutex_lock(&rdev->mutex); - if (rdev->use_count > 0 || rdev->constraints->always_on) { - if (!_regulator_is_enabled(rdev)) { - ret = _regulator_do_enable(rdev); - if (ret) - dev_err(dev, - "Failed to resume regulator %d\n", - ret); - } - } else { - if (!have_full_constraints()) - goto unlock; - if (!_regulator_is_enabled(rdev)) - goto unlock; - - ret = _regulator_do_disable(rdev); - if (ret) - dev_err(dev, "Failed to suspend regulator %d\n", ret); - } -unlock: - mutex_unlock(&rdev->mutex); - - /* Keep processing regulators in spite of any errors */ - return 0; -} - -/** - * regulator_suspend_finish - resume regulators from system wide suspend - * - * Turn on regulators that might be turned off by regulator_suspend_prepare - * and that should be turned on according to the regulators properties. - */ -int regulator_suspend_finish(void) -{ - return class_for_each_device(®ulator_class, NULL, NULL, - _regulator_suspend_finish); -} -EXPORT_SYMBOL_GPL(regulator_suspend_finish); /** * regulator_has_full_constraints - the system has fully specified constraints diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index e50519f..b4ddb56 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -231,12 +231,12 @@ struct regulator_init_data { #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); -int regulator_suspend_prepare(suspend_state_t state); -int regulator_suspend_finish(void); #else static inline void regulator_has_full_constraints(void) { } +#endif + static inline int regulator_suspend_prepare(suspend_state_t state) { return 0; @@ -245,6 +245,5 @@ static inline int regulator_suspend_finish(void) { return 0; } -#endif #endif From patchwork Thu Dec 21 06:25:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122510 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485566qgn; Wed, 20 Dec 2017 22:26:09 -0800 (PST) X-Google-Smtp-Source: ACJfBosaayRNn3GbgP/wNa0+zsxtkETj5JZrZTetmCDRaANcL308q6XWhT/KEOw+UA5mdaZeAxDw X-Received: by 10.84.131.98 with SMTP id 89mr9372559pld.170.1513837569626; Wed, 20 Dec 2017 22:26:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837569; cv=none; d=google.com; s=arc-20160816; b=GTTVN4ur6a9SqteCgWmjLAH8NR1k49sfEGOAa/vYkF4gBKD4E/dL9pbYxrEbqbEa6Y GmbH+6RtCtm4LLw6kD0pPFoaL/Zyf5tpSIxRAEJhjw5e412bagrV/4pGZSqJ9etw6T10 Jd1x5PhUn2RzyD3IbfYOcWeh1fQvhIt8q3Q0Od2I2y5UBgshykHx2E5xY8IH9YU9MFRU e+B2UQxCm30pbbSsc05CRgyBodKvKikzQ8Y1nhBYGoCoD01OyIXjCN/q8VHlBV7sYVYl iJflhVxbkVaIHkOAfAl7y5hySeDcmedKzhj8fGxvTzGa8NLvg/7cmwunZmoO/Vlj3i3O ItLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=VsswdKtIhqihH7gPMH6dH/Ej696tKH6gZH1x5sIThf4=; b=gfsBxQLCpXp8TSdG7dP8Yky1OYPwQHJmcrqedH2GeuUB4YRSL9WM7bQUwU0QItaBda PRGUHwHL4GkMnzTxnRFxQSvvcL4/PcSmak1Q0Qv6Erj9Yee1GPeMxwYYK4QF8NXU4E0R kCyp21eXCo3LTvVk38D6CfmNOBR+Za1gHD3rnAMdSLF8fwVbDSgfVhklz8+KTAjqwBQn o/ao0OBhYlLHfyNosANfHY6k2Y2NtO3ltMlSL6iwArinog7e21GyxsfiFP2zsc+DgVj6 IhOmPWKEs/M6N1kQXjeth6zFcoLVHx//1cRZtbQwXBpeHMmS0KpmawzAFKoIjyplloAj tCCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DxVfiRx4; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n11si8502072plg.289.2017.12.20.22.26.09; Wed, 20 Dec 2017 22:26:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DxVfiRx4; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932275AbdLUG0H (ORCPT + 6 others); Thu, 21 Dec 2017 01:26:07 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:40787 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751856AbdLUGZu (ORCPT ); Thu, 21 Dec 2017 01:25:50 -0500 Received: by mail-pg0-f67.google.com with SMTP id k15so12903505pgr.7 for ; Wed, 20 Dec 2017 22:25:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gEAxATlglRsd6dYv8WIYDhqxKHnzDdzURrmd+yldS2I=; b=DxVfiRx4ed3GeKaQrdrtFZMRCFxro1ssV8isLe4CcJrW5vFASl/Z5Xf5YFnY7I3IhK 6hpukL9DHur5cpk4rKfehpqDci6/6Qvxq6H5s+gm0z3YASlcBuOlrXsx9SUXyZi5GYP0 eRaT1bZvbAlzYnRRa1pNpFUnHaU/yYyCHgOAs= 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; bh=gEAxATlglRsd6dYv8WIYDhqxKHnzDdzURrmd+yldS2I=; b=uT4t/dDfK3jdzwX03F4T/XqdfB2VZUuOj9gN2ktTcuPed+u5yF3gm9VGzBMVzl0e+E xnaq+IGG/tsFlh36uYDEA7058YqdU9lwgFiTKmYxJk2sbFfISiegMJz+flO16rWdvtFu ejP7GQzKwy8cms/y2t1RPXRSIrB/UA7FfXunRL0Ds3zmXQP/s8Cksbb4rHBqwXcKcCmM 9+eMcLljvtjMj+SJzMM4Y0xqdeIIsjTnQajiRPbcUdlitDdB8U4zs8UJiLhqSBE7qiPi ECGIqichALHC9C3X5hE5BRiSrbzaRsIqEqwHSQZ4kW4aIjo+gXFXuQpVEkVPNoLNBsb4 HDUg== X-Gm-Message-State: AKGB3mJ2P3WIW6pGvi6pOIxGSGc8z/zTX8k3xn6t4Ql8jRZTOtUxSn6x T+AjfuOoOy9FZ+rAmAG/7ilJXcxBLME= X-Received: by 10.99.107.7 with SMTP id g7mr8374799pgc.387.1513837549428; Wed, 20 Dec 2017 22:25:49 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:48 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 5/5] regulator: add PM suspend and resume hooks Date: Thu, 21 Dec 2017 14:25:06 +0800 Message-Id: <1513837506-26543-6-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In this patch, consumers are allowed to set suspend voltage, and this actually just set the "uV" in constraint::regulator_state, when the regulator_suspend_late() was called by PM core through callback when the system is entering into suspend, the regulator device would act suspend activity then. And it assumes that if any consumer set suspend voltage, the regulator device should be enabled in the suspend state. And if the suspend voltage of a regulator device for all consumers was set zero, the regulator device would be off in the suspend state. This patch also provides a new function hook to regulator devices for resuming from suspend states. Signed-off-by: Chunyan Zhang --- drivers/regulator/core.c | 251 +++++++++++++++++++++++++++++++++----- drivers/regulator/of_regulator.c | 12 ++ include/linux/regulator/driver.h | 2 + include/linux/regulator/machine.h | 16 ++- 4 files changed, 249 insertions(+), 32 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 080c233..3f4d3aa 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -236,6 +236,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev, return 0; } +/* return 0 if the state is valid */ +static int regulator_check_states(suspend_state_t state) +{ + return (state > PM_SUSPEND_MAX || state == PM_SUSPEND_TO_IDLE); +} + /* Make sure we select a voltage that suits the needs of all * regulator consumers */ @@ -327,6 +333,24 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, return -EINVAL; } +static inline struct regulator_state * +regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state) +{ + if (rdev->constraints == NULL) + return NULL; + + switch (state) { + case PM_SUSPEND_STANDBY: + return &rdev->constraints->state_standby; + case PM_SUSPEND_MEM: + return &rdev->constraints->state_mem; + case PM_SUSPEND_MAX: + return &rdev->constraints->state_disk; + default: + return NULL; + } +} + static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -734,9 +758,14 @@ static int drms_uA_update(struct regulator_dev *rdev) } static int suspend_set_state(struct regulator_dev *rdev, - struct regulator_state *rstate) + suspend_state_t state) { int ret = 0; + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; /* If we have no suspend mode configration don't set anything; * only warn if the driver implements set_suspend_voltage or @@ -779,28 +808,8 @@ static int suspend_set_state(struct regulator_dev *rdev, return ret; } } - return ret; -} -/* locks held by caller */ -static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state) -{ - if (!rdev->constraints) - return -EINVAL; - - switch (state) { - case PM_SUSPEND_STANDBY: - return suspend_set_state(rdev, - &rdev->constraints->state_standby); - case PM_SUSPEND_MEM: - return suspend_set_state(rdev, - &rdev->constraints->state_mem); - case PM_SUSPEND_MAX: - return suspend_set_state(rdev, - &rdev->constraints->state_disk); - default: - return -EINVAL; - } + return ret; } static void print_constraints(struct regulator_dev *rdev) @@ -1069,7 +1078,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, /* do we need to setup our suspend state */ if (rdev->constraints->initial_state) { - ret = suspend_prepare(rdev, rdev->constraints->initial_state); + ret = suspend_set_state(rdev, rdev->constraints->initial_state); if (ret < 0) { rdev_err(rdev, "failed to set suspend state\n"); return ret; @@ -2898,6 +2907,35 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, return ret; } +static int _regulator_do_set_suspend_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, suspend_state_t state) +{ + struct regulator_state *rstate; + int uV, sel; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; + + if (!rstate->changeable) + return -EINVAL; + + if (min_uV < rstate->min_uV) + min_uV = rstate->min_uV; + if (max_uV > rstate->max_uV) + max_uV = rstate->max_uV; + + sel = regulator_map_voltage(rdev, min_uV, max_uV); + if (sel < 0) + return sel; + + uV = rdev->desc->ops->list_voltage(rdev, sel); + if (uV >= min_uV && uV <= max_uV) + rstate->uV = uV; + + return 0; +} + static int regulator_set_voltage_unlocked(struct regulator *regulator, int min_uV, int max_uV, suspend_state_t state) @@ -2993,7 +3031,11 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, } } - ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); + if (state == PM_SUSPEND_ON) + ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); + else + ret = _regulator_do_set_suspend_voltage(rdev, min_uV, + max_uV, state); if (ret < 0) goto out2; @@ -3049,6 +3091,92 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) } EXPORT_SYMBOL_GPL(regulator_set_voltage); +static inline int regulator_suspend_toggle(struct regulator_dev *rdev, + suspend_state_t state, bool en) +{ + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; + + if (!rstate->changeable) + return -EINVAL; + + rstate->enabled = en; + + return 0; +} + +static int regulator_suspend_enable(struct regulator_dev *rdev, + suspend_state_t state) +{ + return regulator_suspend_toggle(rdev, state, true); +} + +static int regulator_suspend_disable(struct regulator_dev *rdev, + suspend_state_t state) +{ + struct regulator *regulator; + struct regulator_voltage *voltage; + + /* + * if any consumer wants this regulator device keeping on in + * suspend states, don't set it as disabled. + */ + list_for_each_entry(regulator, &rdev->consumer_list, list) { + voltage = ®ulator->voltage[state]; + if (voltage->min_uV || voltage->max_uV) + return 0; + } + + return regulator_suspend_toggle(rdev, state, false); +} + +static int _regulator_set_suspend_voltage(struct regulator *regulator, + int min_uV, int max_uV, + suspend_state_t state) +{ + int ret; + struct regulator_dev *rdev = regulator->rdev; + + /* + * We assume users want to switch off the regulator device for + * suspend state when setting min_uV and max_uV all with zero. + */ + if (min_uV == 0 && max_uV == 0) { + regulator->voltage[state].min_uV = 0; + regulator->voltage[state].max_uV = 0; + return regulator_suspend_disable(rdev, state); + } + + ret = regulator_suspend_enable(rdev, state); + if (ret < 0) + return ret; + + return regulator_set_voltage_unlocked(regulator, min_uV, max_uV, state); +} + +int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, + int max_uV, suspend_state_t state) +{ + int ret = 0; + + /* PM_SUSPEND_ON is handled by regulator_set_voltage() */ + if (regulator_check_states(state) || state == PM_SUSPEND_ON) + return -EINVAL; + + regulator_lock_supply(regulator->rdev); + + ret = _regulator_set_suspend_voltage(regulator, min_uV, + max_uV, state); + + regulator_unlock_supply(regulator->rdev); + + return ret; +} +EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage); + /** * regulator_set_voltage_time - get raise/fall time * @regulator: regulator source @@ -3923,12 +4051,6 @@ static void regulator_dev_release(struct device *dev) kfree(rdev); } -static struct class regulator_class = { - .name = "regulator", - .dev_release = regulator_dev_release, - .dev_groups = regulator_dev_groups, -}; - static void rdev_init_debugfs(struct regulator_dev *rdev) { struct device *parent = rdev->dev.parent; @@ -4179,7 +4301,76 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); +static int _regulator_suspend_late(struct device *dev, void *data) +{ + struct regulator_dev *rdev = dev_to_rdev(dev); + suspend_state_t *state = data; + int ret; + mutex_lock(&rdev->mutex); + ret = suspend_set_state(rdev, *state); + mutex_unlock(&rdev->mutex); + + return ret; +} + +/** + * regulator_suspend_late - prepare regulators for system wide suspend + * @state: system suspend state + * + * Configure each regulator with it's suspend operating parameters for state. + */ +static int regulator_suspend_late(struct device *dev) +{ + suspend_state_t state = pm_suspend_target_state; + + return class_for_each_device(®ulator_class, NULL, &state, + _regulator_suspend_late); +} +static int _regulator_resume_early(struct device *dev, void *data) +{ + int ret = 0; + struct regulator_dev *rdev = dev_to_rdev(dev); + suspend_state_t *state = data; + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, *state); + if (rstate == NULL) + return -EINVAL; + + mutex_lock(&rdev->mutex); + + if (rdev->desc->ops->resume_early && + (rstate->enabled == ENABLE_IN_SUSPEND || + rstate->enabled == DISABLE_IN_SUSPEND)) + ret = rdev->desc->ops->resume_early(rdev); + + mutex_unlock(&rdev->mutex); + + return ret; +} + +static int regulator_resume_early(struct device *dev) +{ + suspend_state_t state = pm_suspend_target_state; + + return class_for_each_device(®ulator_class, NULL, &state, + _regulator_resume_early); +} + +static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { + .suspend_late = regulator_suspend_late, + .resume_early = regulator_resume_early, +}; + +static struct class regulator_class = { + .name = "regulator", + .dev_release = regulator_dev_release, + .dev_groups = regulator_dev_groups, +#ifdef CONFIG_PM_SLEEP + .pm = ®ulator_pm_ops, +#endif +}; /** * regulator_has_full_constraints - the system has fully specified constraints * diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 41dad42..7dc8fd2 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -188,6 +188,18 @@ static void of_get_regulation_constraints(struct device_node *np, "regulator-suspend-microvolt", &pval)) suspend_state->uV = pval; + if (!of_property_read_u32(np, "regulator-suspend-min-microvolt", + &pval)) + suspend_state->min_uV = pval; + + if (!of_property_read_u32(np, "regulator-suspend-max-microvolt", + &pval)) + suspend_state->max_uV = pval; + + if (of_property_read_bool(suspend_np, + "regulator-changeable-in-suspend")) + suspend_state->changeable = true; + if (i == PM_SUSPEND_MEM) constraints->initial_state = PM_SUSPEND_MEM; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 94417b4..4c00486 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -214,6 +214,8 @@ struct regulator_ops { /* set regulator suspend operating mode (defined in consumer.h) */ int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode); + int (*resume_early)(struct regulator_dev *rdev); + int (*set_pull_down) (struct regulator_dev *); }; diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index b4ddb56..f60ec1f 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -42,7 +42,12 @@ struct regulator; #define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_BYPASS 0x20 -/* operations in suspend mode */ +/* + * operations in suspend mode + * DO_NOTHING_IN_SUSPEND - the default value + * DISABLE_IN_SUSPEND - turn off regulator in suspend states + * ENABLE_IN_SUSPEND - keep regulator on in suspend states + */ #define DO_NOTHING_IN_SUSPEND (-1) #define DISABLE_IN_SUSPEND 0 #define ENABLE_IN_SUSPEND 1 @@ -61,17 +66,24 @@ enum regulator_active_discharge { * state. One of enabled or disabled must be set for the * configuration to be applied. * - * @uV: Operating voltage during suspend. + * @uV: Default operating voltage during suspend, it can be adjusted + * among + * @min_uV: Minimum suspend voltage may be set. + * @max_uV: Maximum suspend voltage may be set. * @mode: Operating mode during suspend. * @enabled: operations during suspend. * - DO_NOTHING_IN_SUSPEND * - DISABLE_IN_SUSPEND * - ENABLE_IN_SUSPEND + * @changeable: Is this state can be changed. */ struct regulator_state { int uV; /* suspend voltage */ + int min_uV; + int max_uV; unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ + bool changeable; }; /**