From patchwork Fri Jan 26 13:08:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125960 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp323860ljd; Fri, 26 Jan 2018 05:09:17 -0800 (PST) X-Google-Smtp-Source: AH8x2263REow5W3gTdcxw6BBFUg6XOnIEVGQQd5yYT0/vkYCc6nsYYd8/TKs7vP80RvwHOZCPuCn X-Received: by 2002:a17:902:622:: with SMTP id 31-v6mr14228972plg.448.1516972156862; Fri, 26 Jan 2018 05:09:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516972156; cv=none; d=google.com; s=arc-20160816; b=ITqIakXoTQer0uVf2h42YI2G0xYyNxAyTFw22r/UhrgmNzp64gXQM6/dsbEpVzdA3s 2rvLgvrYdhUQz020mGPadJpaXeCFvfc1tMG7oX6+aA48PrfVFoHb2jbBg/mhQld3Sfhv w9syau8H4mbLoCfVHHcK20HUCHi2HHr5F5r3PNQ2vYwYT3zSfrnR3SdXZmmaz5qQ5+Mb hf8FPHIHErPr88ASdOA8HQ3P8mEvDE+MtGg4t2qZZPxG8IX7gQ2nB7fTZnTIihqPKxf5 sukuXB2daj7y6TLjY4pDm1qNHALK0xIW/rfvysL2crgKRGITLAM0n7N8tSsAzHMSKVeQ 1u0A== 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=JvNSlIMTyVFAQEYAKhkukqbzC538/hhFEd2DI7mvImM=; b=c1Q4UgJT2+/kj7pqZoJHLtmKMXoBrXx09frxU6/8HTgUDBmJAS0E1VYEqx5qG42eru 3hGKjyxD+XUVnS4puR0CaQI5dhRyzoFqW3EiG8h9tdiA6YO1ByyTejxapYgYFepBNIR2 CgPJKYRfGgG0UdyDj2HYbmF69g2LaR58fNYwgFgXXRl1FWDCU0u4JF7wJvWvJg88kqeV H5vBRgAa6ZC7XbrzxpbJSD1RiG8HAzjnwsup4dn4V6EjaRDALyg8eXI4wQWt65ND1zwP eyen70MzSoOfaa3bf9tC84OoZWUAD1/X2v90Sc4q5VPMgypn4axW1fyg/ppeHmsvDAXp x3gQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GX7imlsh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (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 a72si6359247pfk.398.2018.01.26.05.09.16; Fri, 26 Jan 2018 05:09:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GX7imlsh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751637AbeAZNJN (ORCPT + 28 others); Fri, 26 Jan 2018 08:09:13 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:46832 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751531AbeAZNJJ (ORCPT ); Fri, 26 Jan 2018 08:09:09 -0500 Received: by mail-pg0-f68.google.com with SMTP id s9so235144pgq.13 for ; Fri, 26 Jan 2018 05:09:09 -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=JvNSlIMTyVFAQEYAKhkukqbzC538/hhFEd2DI7mvImM=; b=GX7imlshpDEJmErHJovp35i6klOjYgjG1Nza33wwkHQE6zD1jhrI60vlrVnjePrS0/ RhBbgSJAEDvSoNmg667+IADK9g/M3HfcTOeEN4HbGwY5GPZG9cNd9cWRmHJ1cYpJnPN2 ylJ/EzpsfyVvSquUDX0nLukPQqebRsBBJGQ1s= 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=JvNSlIMTyVFAQEYAKhkukqbzC538/hhFEd2DI7mvImM=; b=ic0U7MnZulBCzk0PJYQg/M2Uzynzx8Qd0ZYdErefydvQZcH5qGbHkGCMDrOjyHuF+l o+96zyTyDai7MP0CFjTxGdtVguXEpC5b4adu7omoWB8qEaxFkjDiVfn7YB2S2v66bYKp w+ru4t80He5OHF+seC65JwnU3ZPWq1vTtqSq2R/4zDGrUbERA7mdjwN/17XAFLiTWJrv 9zgF7D2VcZrd5O9pk1FX38LK71fsbN0BR2TgxxfdOJq46rjRYRpedE8z+TmH2myb0ccU GiLLp9vJwlvk+sqtR49ltiqGVVkZ5J0WNno2FW3VVtIrMaa24qnf+YzegeXj9hgqb/ob EhTw== X-Gm-Message-State: AKwxytd32g/JSi6xnWxLueI8gTg7BRh8wW4xmsHzQZASWj3ft54li3/X HlHHEJVFyuTn1lKPMIYrMP4omw== X-Received: by 10.98.80.20 with SMTP id e20mr19017594pfb.148.1516972149058; Fri, 26 Jan 2018 05:09:09 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id b6sm18663238pfe.85.2018.01.26.05.09.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jan 2018 05:09:08 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V5 1/5] bindings: regulator: added support for suspend states Date: Fri, 26 Jan 2018 21:08:43 +0800 Message-Id: <1516972127-972-2-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> References: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some systems need to set regulators to specific states when they enter low power modes, especially around CPUs. There are many of these modes depending on the particular runtime state. Currently the regulator consumers are not granted permission to change suspend state of regulator devices, the constraints are configured at startup. In order to allow changes in a vlotage range, we need to add new properties for voltage range and a flag to give permission to change the suspend voltage and suspend on/off in suspend mode. Signed-off-by: Chunyan Zhang Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/regulator/regulator.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) -- 2.7.4 diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 378f6dc..e459226 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -42,8 +42,16 @@ 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 + would be set in suspend. This property is now deprecated, instead + setting voltage for suspend mode via the API which regulator + driver provides is recommended. + - 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 Fri Jan 26 13:08:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125961 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp323903ljd; Fri, 26 Jan 2018 05:09:19 -0800 (PST) X-Google-Smtp-Source: AH8x224wz2rXsnlJ5/fdrcS+LeIwQaXbVXewls/2NaFwBv7JPmMw5YffNIh1BcV6zduo5HvJ3/Uj X-Received: by 10.101.101.11 with SMTP id x11mr16038466pgv.130.1516972159781; Fri, 26 Jan 2018 05:09:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516972159; cv=none; d=google.com; s=arc-20160816; b=XArq3ssLeS7ei+QC3+c4E6SwYtIPDKCi+feP1FJ6nKNNovzBJXvftEik4XEUfXfLi4 b9DkrwP2mBFypdoX4woPONvmEs6YtP+UqvlLM8bRntHLzIdGL0qm0Rx9CQYfRhHOxL/j /W+/MvZdTzVAI1VXpSxzepuI8S+f2liHx2k2rtCPN5HiVUY5myrHWcnsxeH7VwsmdihF KiuB0xyCmSgu6lSTYGgFZqGGSbA+63nZHCoHrNOethpndWdBhkGy2sPtMEOal9caqQRf hhRthMA0EFKzj83MfqvT+0ca1Zg7s6uJ6+ji1ghhKTMk2eswXxgvWVuxtCJeZjgnOi3k Z05w== 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=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=mSyHz3KghwzPhqHiVBwJGiNmpQ2LzFxdy1XIxB0T6yjbOXogWJyibcl7kMxIfIx+2B UdTDE5P/d8OQ7GjzOBNMZjsv3/sGBNuMY9n/n1sSY0+eMKlMX95FS1fOFsP3cZeLn+dk k7FEgvKe2Bl0JgxJkKbgTWmL/aH1UYiDWqEFRDiP7JQG2FNNMLjT2CZr3s/d6RAuhyil l0XGQr16eG7RwA3KM04PDTcF+oF+B+Ps106SW9PMYGa05m1hWJ4YvyuJyTHQWX5Vd1w3 CNaGn6wJtLXg2wlb9g1DTxbmF5c6iZPHn9hA7CBpPsYLuN4oszbYuGDn4fOzUaKbXuUk wiSg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bcxBqSGW; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (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 a72si6359247pfk.398.2018.01.26.05.09.19; Fri, 26 Jan 2018 05:09:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bcxBqSGW; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751725AbeAZNJS (ORCPT + 28 others); Fri, 26 Jan 2018 08:09:18 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:43810 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751575AbeAZNJN (ORCPT ); Fri, 26 Jan 2018 08:09:13 -0500 Received: by mail-pf0-f193.google.com with SMTP id y26so219156pfi.10 for ; Fri, 26 Jan 2018 05:09:13 -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=bcxBqSGWC+Dbbrm8Oi9n9XP7t+6bHdw5fMu+nLIFokz5tzPfeZqGsMxdkBr/W7noLw cLoLrqj+CkGGVgsl3rOVVxAPt9qaf54uY7WXkJzwAuEZ7c8nLgt5+IFEQ1cy+YXEV/lu 235JSIN6EezjQRow+U3BxfsI4uWeZjW584TPQ= 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=nxH90bEG4MRj5cGVkvBfXh06vPksaUypniStz5r6/YAWIZ0tUG+Z64UtkfigNiM+YM dwPFeUn9NmOOWjZ/RqMcG3T0q2uXKGYaEHxx1uRVS8jPFe3IpOnCYN+eje4TkbDSTo9N 45nzC2GwYJMuPcAFdkI8NPUCzHQ+W+nHcuPiqpc9Jg4Eo018y0OHzZfAKdJcqaGLU2B7 MHWBfXSxvSBhw2g+SiLwzoUuLo+hr3lYFWYjYpMgqFTnvJsJVBFgi2KRhlDM7Psl6STJ kv2cxcOvv2UjAwnYxNK8rGnx4wUU/MiSFy8xNiNMdH+Iu7jOLhp3EHQDuUwFdYU1CAfk 6k0Q== X-Gm-Message-State: AKwxytd+4NJO1GxdTCqLtFLgDu7LC1nj7q+pX8W+DYnPu4p6wuvOB+v2 q52qt/x7QDpZSof1EZvi3htL8Q== X-Received: by 10.98.202.214 with SMTP id y83mr18802624pfk.49.1516972152790; Fri, 26 Jan 2018 05:09:12 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id b6sm18663238pfe.85.2018.01.26.05.09.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jan 2018 05:09:11 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V5 2/5] regulator: make regulator voltage be an array to support more states Date: Fri, 26 Jan 2018 21:08:44 +0800 Message-Id: <1516972127-972-3-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> References: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 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 Fri Jan 26 13:08:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125964 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp324289ljd; Fri, 26 Jan 2018 05:10:04 -0800 (PST) X-Google-Smtp-Source: AH8x226ZkWj3keJXFqnVE9i4ZZv4KL/nA3L857nL1b6R4rO7kNebz7WzvVuUxOvXb57+l/p1Jm1z X-Received: by 10.99.56.85 with SMTP id h21mr15366686pgn.402.1516972204296; Fri, 26 Jan 2018 05:10:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516972204; cv=none; d=google.com; s=arc-20160816; b=K7V3Wnypd/dQywoPwPREj6vji22wUa37ljDz4RdTt0LAAqNcvP6RCDM1GpWCi2hQjc cLj/xAmAUCzdT0wIwPHfuYEo2FE+Z9F+9d1hInNoImT1MMcYXtHocoTmCc/BeMnBtUYn CqbRTgLM9Ts81+dk37/54yGQO+C49AQoyG+9BHg1ACLLR00hdklbKHQ0U9atptZqFCI/ iUNI93kIiesflALWABK7lsrVf/b0PXeDdbGfrtmLLbeSh5PSGYBmymM1HFAFgM5yCKaf 0S1szdwjnTS9OMXUKmxfYlrpZCbVszDFQywzWCk1nhzsuATvAxmNv/Hy9pp/48ExVjrt H8fg== 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=EcLpvBMIMakiKa8EPdDMFEkOKTKDf++0HWt3W/KiWU4=; b=KUBaOBSfIL4sW41u6iZ65B0H6QTR2YnbBaf40kDRas8BDKHMH0R8SYTvka4YHukS8D qhSpXaGIzDw67Jjmjvoml1ZMgoT5eUGcYVXm/j6hs5rIWdR8EqQlfUMFvWoBHCsGclRo KAhuuUqPcQUXsswx8+W7DNDSLzQ0YBQdhYGGopyQxPKRYJi6qd/WUGFRvxex+dqi7h25 tqRu0FXAc5w/XC8BZ+5B690r1oafUcIyHpQio57FVrPBFUpqLglPHxvWRwN+SzcZZ6WA 2ymDnx2u3AWzFgCiO9/syy7tfcXsR5/zhu30KFdx8EiMsXcgfmGqGFGxipYxVJN8f7WD fimw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B7nA6Beh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (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 a89si6383161pfj.107.2018.01.26.05.10.04; Fri, 26 Jan 2018 05:10:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B7nA6Beh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752200AbeAZNKB (ORCPT + 28 others); Fri, 26 Jan 2018 08:10:01 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:45743 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbeAZNJQ (ORCPT ); Fri, 26 Jan 2018 08:09:16 -0500 Received: by mail-pf0-f195.google.com with SMTP id a88so216451pfe.12 for ; Fri, 26 Jan 2018 05:09:16 -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=EcLpvBMIMakiKa8EPdDMFEkOKTKDf++0HWt3W/KiWU4=; b=B7nA6BehZHF7TFm4eFiVU1nACabbE662RlrHGgXWRSYpDKayvZZumx2IYl3FwEDcEX wxiyeLMWLJmBVudqZQw7z3ypwto1mpo64qtfz/TGjqgSX5qqhsRpV4ILm9vsSBeKG3Qn 8TjiBtRFjXx8q6FWY5qO0DteLrU63hXHJHmSg= 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=EcLpvBMIMakiKa8EPdDMFEkOKTKDf++0HWt3W/KiWU4=; b=gANSMiXIK2XVS4mVO/ZyPg5YnzPzfhdeoQblfXnHWcfRLeVGQFrEbA0sVK8EiqXbOK 51EuMGoTstPIV4tDNw5mWkiqxm5/sXvaERe6b7k5hkx8oIiydT2uHwuAZP2d5TWI6TpA +675ev/8N55s1I3RqZ2veKUkmZQ1gWxTPfg7LO6+zQyNOv8isZy+SZn81x3U/yN38zP8 nrRk38yiSO5a55Oe2jkXMDPgUNFDoP6FocTj1IccZhgN+edyUEZpOfpoRezbgqwn6eJ0 1nmUvBnlkl/XUtnoeaBkxa82eam06MpvoN3sRFndPvScMTTxL9eb5u3MpFWvDuW+ximz dVlw== X-Gm-Message-State: AKwxytdOSWEfZUOej97wOHCEv5ywA4SOsrPsIlJHKf/WRa0JRZeQaRof QtYN+pecFM6HCwPCjUtQmNvfVQ== X-Received: by 10.101.64.139 with SMTP id t11mr15207712pgp.162.1516972155955; Fri, 26 Jan 2018 05:09:15 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id b6sm18663238pfe.85.2018.01.26.05.09.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jan 2018 05:09:15 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V5 3/5] drivers: regulator: leave one item to record whether regulator is enabled Date: Fri, 26 Jan 2018 21:08:45 +0800 Message-Id: <1516972127-972-4-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> References: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 | 19 +++++++++++++++---- 3 files changed, 25 insertions(+), 14 deletions(-) -- 2.7.4 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..ce89c55 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -42,6 +42,16 @@ struct regulator; #define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_BYPASS 0x20 +/* + * 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 + /* Regulator active discharge flags */ enum regulator_active_discharge { REGULATOR_ACTIVE_DISCHARGE_DEFAULT, @@ -58,14 +68,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 */ + int enabled; }; /** From patchwork Fri Jan 26 13:08:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125962 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp323974ljd; Fri, 26 Jan 2018 05:09:28 -0800 (PST) X-Google-Smtp-Source: AH8x226EXiiFxjA7Q8G7jTq7OafFCjK2NLIx4J3h+H+v6Aylg3kkEnX0ySPt5MLQlGEXVopkMcB2 X-Received: by 2002:a17:902:901:: with SMTP id 1-v6mr8326457plm.165.1516972168090; Fri, 26 Jan 2018 05:09:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516972168; cv=none; d=google.com; s=arc-20160816; b=H6ExNOofAM4F+jHTyC2eUrVEKLhgUb7kerhjbaBSFDgcijK+3QxY0MkaszD6tGD60X KEiPcjlynli7JFEHicogAn18LlzIG0UGDXuLzufC02d2qGQLHjqURtTyU0NPsS7ZwJ6u sZoOhH/8QRBkB9g6aaDA3mqQA+pwdnNVtwjXqsFBINdNyYwPB/FjWBM3LwZGznhjI5tO LFL6EWHKoG0+/R10T146oosgOTFdR9MHgQySVoPO1NNsc+BFtIChLlnLr79OOpYBFSao 0ZFDyOEkIakFruRREGyRmzxSr+TKMhOPJvkNRQ6+JBHVi/rVo5NHE1wQG210Yn/PJNIH OcIA== 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=PgJpBAWoL6UfAEBRKx+NUQscAn0hvzT2js/EGzJp15w=; b=cTh3bUYwIqpYwOxlDEVMhJ5u0EGdn/ktA+i0QZr9GYhXgVSJPvHMm9EN/P92bOoNUQ l5ilYejgEe3D6VmwutFZMuYPM3wpmsQHOi6KaLg5PEu36APNLDeMtrnHQ28qbt6DjJo9 hOot5EB4heccYMqt7hUqCDbwHiv6+xMyqtAyq/ou0WyCKtZzTN221YprJ9R4MrfwR3ul n5O+So2YZBjMCplOWWSzOc0C9DnB1nhWDzKSR3XpLpmsAwPDXmTsouQRa9a+skavc3U6 SX4qAYHzWOqGEYOU+cM4A+9bVq6nF/ag38cHUt2ilC1TUSLE+a09pYn/ksQFIhVU/IF7 /Hzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=a8XhowLn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (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 q16-v6si2974572pls.74.2018.01.26.05.09.27; Fri, 26 Jan 2018 05:09:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=a8XhowLn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751789AbeAZNJZ (ORCPT + 28 others); Fri, 26 Jan 2018 08:09:25 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:33987 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751733AbeAZNJT (ORCPT ); Fri, 26 Jan 2018 08:09:19 -0500 Received: by mail-pf0-f194.google.com with SMTP id e76so235819pfk.1 for ; Fri, 26 Jan 2018 05:09:19 -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=PgJpBAWoL6UfAEBRKx+NUQscAn0hvzT2js/EGzJp15w=; b=a8XhowLnmhmePXQRvnJ1gF7cT/1zfPiYFFV1dPBzRlR/YqERNKKHNQA+VALHfZ21cC SIOe05EiGRnRNC128TcHoIs2r6mgPr3l5QXCeqd7dG4eYF3zOx07Fofd0GA+SpyjOHE4 DvTROzvVX0qCQkjbzLaK7L2s0Dccaq25YRymo= 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=PgJpBAWoL6UfAEBRKx+NUQscAn0hvzT2js/EGzJp15w=; b=BbJGFrZYVQHFFN4ZDTZrlIWf828rrDzv+Te1mBzJjR+7sVaEi3pxrkvGyMQruuJX7g CG1Cg4kgNkvOow6cCpnPW0r6Zp9yNmH4wMFwLV+irOsVQVly/f/c6IMM9Nc0Wbpkptxp vdglLrg9AYs/gA8QUyCRNFkCMvUHHoUXzi2+bKxQSstxu8CbNdeX5rClyZo0hZ0aJ3Rq UPNBYihKOuwVkGxqf3GUoc/Y3mo26L+mRwd4SKkEK3zOEkm3ZxHsTUncKQ+7eLM20o4f kZNyvxxcuaRvQ32pSxW+BtuphhKPzvfexpgAdbHLUP3qAgVnX3BWT+wA8kdojYROJ8ZE NObQ== X-Gm-Message-State: AKwxytdnUaSmmNXuWG8A+/UTcKjnCUpIzsBIoiamsNR+Jfg2TeWzqGSh R4Uy6WcR0xCMrwfx6fHQRpk70w== X-Received: by 10.98.228.5 with SMTP id r5mr19617920pfh.193.1516972159008; Fri, 26 Jan 2018 05:09:19 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id b6sm18663238pfe.85.2018.01.26.05.09.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jan 2018 05:09:18 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V5 4/5] drivers: regulator: empty the old suspend functions Date: Fri, 26 Jan 2018 21:08:46 +0800 Message-Id: <1516972127-972-5-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> References: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 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 ce89c55..c4a56df 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -236,12 +236,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; @@ -250,6 +250,5 @@ static inline int regulator_suspend_finish(void) { return 0; } -#endif #endif From patchwork Fri Jan 26 13:08:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125963 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp324008ljd; Fri, 26 Jan 2018 05:09:31 -0800 (PST) X-Google-Smtp-Source: AH8x226Pnlxd+bIfm3ad5W7sQBV5zBJ6QEAX6N4XW9OUpc7Cy3GiLjStMHE2cC6TqMTjCoUJtuwR X-Received: by 10.99.148.17 with SMTP id m17mr14930666pge.367.1516972171438; Fri, 26 Jan 2018 05:09:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516972171; cv=none; d=google.com; s=arc-20160816; b=C9FBkSfj85HqeXDSZ5LcDx6XB4pSVrtxDovUNQXg+5prTuUcrdJlTTLCw/H1RXdkdU BQEJEbfwUruwADYMhhvKOi7G3JTpbHgoPzrF3vTFSIdj35Xk7y9sNs1QAQpOymjrRm/d hXXIyecVUwXE4Bt5Dz0yALeo6L8d+5c+kn3qoNDLrutfvMwihLtXkrFugbAdzbTWtDDs 1W1/SaS3ff4M7cbHIj4AmFWrJ1EqcNUJl7KVBP9jv/qm4r9l6I+Z3Xf0W0AZSDr8Go/5 y+og5pbtHdc0aivMzx8RQOfCEOx6QmzLS45RY7K2Rr4jcug1e8e+O44JJPAmlVvEgMTA r6xg== 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=qRFNS9apZ3VNNTXLXYn17OM9LzeZi3ZkCB07dS9SN4w=; b=wrr1RY4ezREShn5Jouq+48ncMuWwiMeFQWzTz2L5bpt1pj5gkunQO7te27dSH0gJVb dKRUcgujm56rIuK5/Z58hKdzKB11Y7Fgx/qL62fvl9VU0QGmZs7/GlSjEPBRjsmIJBng Zl52S+Q+9SRr+keNX3PrLDd3hqehmzORcpAzZtm09oYgXNzzupkminqa+viDr/Cbaz/q SigFlhRZHDGcN/t6cim2FK69mc2aVflHIXvZ9E9GVlfKIdxBSTen3wUFC1A51+Vum7FN Y6V4mXF/BkkR+lGpTH15AkGplHYtg5L2zrulGrajG3GLMaNDA+y+UWnNKyWFr9TVDSXi bLxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Xq62c8fa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (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 q16-v6si2974572pls.74.2018.01.26.05.09.31; Fri, 26 Jan 2018 05:09:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Xq62c8fa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751906AbeAZNJa (ORCPT + 28 others); Fri, 26 Jan 2018 08:09:30 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:44622 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751745AbeAZNJY (ORCPT ); Fri, 26 Jan 2018 08:09:24 -0500 Received: by mail-pg0-f66.google.com with SMTP id m20so238601pgc.11 for ; Fri, 26 Jan 2018 05:09:24 -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=qRFNS9apZ3VNNTXLXYn17OM9LzeZi3ZkCB07dS9SN4w=; b=Xq62c8faCkpTucjFigA5KFQCZvw8o7+h00HsIRgIRRhxN1oRB+x65wmqeHSm8lf+p8 pQJ8CeVLuqmz11Bo6oXRMMn0Jy22jfzf4Ds+5k5+lUiohYfQ3frPtVXuSQ7UutV4DauM C1CFdqXGkX+2xF/emSP3XbEVgb8i30Vfuzj9w= 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=qRFNS9apZ3VNNTXLXYn17OM9LzeZi3ZkCB07dS9SN4w=; b=CuNfd9pOQoa25x4yLT+FrTGtDAfikzaBI334LjSUoxaI3Vyt87ReP7Z3FP18ZaR987 i54imMRzpeenCxumOKsTXrpuw7IC61hy1tG13ecW8ocf+e0hsCe19lStuoK058+R+2Ul QxEY3RfidNagqTcrQyylvdotvATqxvDT+jHX4p8D6g02g/VPhl5SaQJ3QqJT8zkvRZPJ Hmhzg2aL/Mmj8mb9y1ccqxtzYSwMnMnmpUgkPPvlSBLVW9s8iyIIGQCLmclfv5+UiXFJ rAaQ5x0S1t2ksVu+hfib6XtkSTF9snLJmmwP/3zs0Clx4TWMCdoh9XpSFIVln+oo6s+5 Fj8g== X-Gm-Message-State: AKwxytf6ueqAaRARJkBVmtyRnX0eJSkpCdWyuw9yNZgg5iNJSNuiRdfV dVLLyoSYajyJvZpau2yv+mQTfA== X-Received: by 10.98.201.199 with SMTP id l68mr19333938pfk.199.1516972163583; Fri, 26 Jan 2018 05:09:23 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id b6sm18663238pfe.85.2018.01.26.05.09.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jan 2018 05:09:22 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V5 5/5] regulator: add PM suspend and resume hooks Date: Fri, 26 Jan 2018 21:08:47 +0800 Message-Id: <1516972127-972-6-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> References: <1516972127-972-1-git-send-email-zhang.chunyan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 | 255 +++++++++++++++++++++++++++++++++----- drivers/regulator/of_regulator.c | 14 +++ include/linux/regulator/driver.h | 2 + include/linux/regulator/machine.h | 13 +- 4 files changed, 251 insertions(+), 33 deletions(-) -- 2.7.4 diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 080c233..949e317 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,32 @@ 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 (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 +3028,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 +3088,89 @@ 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 -EPERM; + + rstate->enabled = en; + + return 0; +} + +int regulator_suspend_enable(struct regulator_dev *rdev, + suspend_state_t state) +{ + return regulator_suspend_toggle(rdev, state, true); +} +EXPORT_SYMBOL_GPL(regulator_suspend_enable); + +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); +} +EXPORT_SYMBOL_GPL(regulator_suspend_disable); + +static int _regulator_set_suspend_voltage(struct regulator *regulator, + int min_uV, int max_uV, + suspend_state_t state) +{ + struct regulator_dev *rdev = regulator->rdev; + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; + + if (rstate->min_uV == rstate->max_uV) { + rdev_err(rdev, "The suspend voltage can't be changed!\n"); + return -EPERM; + } + + 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 +4045,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,8 +4295,87 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); +#ifdef CONFIG_SUSPEND +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); +} + +#else /* !CONFIG_SUSPEND */ + +#define regulator_suspend_late NULL +#define regulator_resume_early NULL + +#endif /* !CONFIG_SUSPEND */ + +#ifdef CONFIG_PM +static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { + .suspend_late = regulator_suspend_late, + .resume_early = regulator_resume_early, +}; +#endif + +static struct class regulator_class = { + .name = "regulator", + .dev_release = regulator_dev_release, + .dev_groups = regulator_dev_groups, +#ifdef CONFIG_PM + .pm = ®ulator_pm_ops, +#endif +}; +/** * regulator_has_full_constraints - the system has fully specified constraints * * Calling this function will cause the regulator API to disable all diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 41dad42..a09ef6c 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -184,9 +184,23 @@ static void of_get_regulation_constraints(struct device_node *np, else suspend_state->enabled = DO_NOTHING_IN_SUSPEND; + 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_u32(suspend_np, "regulator-suspend-microvolt", &pval)) suspend_state->uV = pval; + else /* otherwise use min_uV as default suspend voltage */ + suspend_state->uV = suspend_state->min_uV; + + 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 c4a56df..93a0489 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -66,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 switched between enabled/disabled, */ struct regulator_state { - int uV; /* suspend voltage */ - unsigned int mode; /* suspend regulator operating mode */ + int uV; + int min_uV; + int max_uV; + unsigned int mode; int enabled; + bool changeable; }; /**