From patchwork Tue Jan 23 11:59:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125501 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1711137ljf; Tue, 23 Jan 2018 04:00:56 -0800 (PST) X-Google-Smtp-Source: AH8x226SYL3+2Kcw1AqIi9MPUvKcH6amFTuTLiFEvuBDAzsZHFFANJS6Uf5XD9AdngWylB/SBIKo X-Received: by 2002:a17:902:fa2:: with SMTP id 31-v6mr3826446plz.346.1516708856265; Tue, 23 Jan 2018 04:00:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516708856; cv=none; d=google.com; s=arc-20160816; b=fueFBhhPrcnka5cadVrwpEl+YIAG1z4Ydde81xV3Ico0WviGiXLAsF1SHWh1ZHS9Ve MfLr7XrmIPyB5hh3Pdmiatr2Ve2QnG8skGgfRpEHn3GyaGZygtbBbjszvhNatXzFxSup PfB+Tl2tWym2FF8JTUokUFqPfyW+4RnRLFmu2/ua24Q+OHK6K5fsPuxal4I9Or8G0Jlq bvYEMxqHBPrOnJjM/Z5ylbYdhO20uevXecqLEsR/qw4SQqqfnhkv4GiNMUDTtffRAtSJ xkvP9rFniWyahqmWzpBvPBlifKJGlljIqUz3XUzp7bVI2USIIsUjOPWOJTqPXNsk/Pji b6hA== 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=RxXoOcQcJRJUWriZbVoSutl7S86276QDooCuqM/n/geLnd3guKPzUOeOWgOlRKyfzg H/W6HaRPWf2LBNdXhZUFtRjNxf7MJOQV9jpie3t0xAQhIOH5KiP7z/tH4+V+vehSvgL2 e2GFyXJnloAwBHrn8KCT+vYQPmDoUBLfsZfCv5l4g/ASbE6CruB/8lSfGqLVIebWvYQL pWCDNor4+/Enm9UDvTFVdlULXh0b2dqYtQ56wt4dSaqHMk1yBhl8RVsh5nrKl2hMbVsz gYN0FrTB5Eg8d0uozSswjHG4AFnjxM5Gg5oRRs5RCvyLNweOFXoMD+r6lOMCveUaFYWq E59g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kXS/zXQX; 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 f9-v6si4726928plm.183.2018.01.23.04.00.55; Tue, 23 Jan 2018 04:00:56 -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=kXS/zXQX; 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 S1751259AbeAWMAw (ORCPT + 28 others); Tue, 23 Jan 2018 07:00:52 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:43555 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751169AbeAWMAt (ORCPT ); Tue, 23 Jan 2018 07:00:49 -0500 Received: by mail-pf0-f193.google.com with SMTP id y26so140229pfi.10 for ; Tue, 23 Jan 2018 04:00: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=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=kXS/zXQXwxIx177onzFWDIpE5HdEssWNpbO1uUpBdeXGInlSfDY/X9O2dEUefrjzLx +mHsXVAVA4/QycczvbXtmGFAOUcP9wy+YlohetHhbPYJtN+WvEI/avxUpOIe1i2tvAug OA17wNqR+Pz6cgNt5zNuozJc6Qj2XP4OvnE7U= 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=eC20yCKNSliIaA/PNVUAZGjvfPg1YZm/zB7KktsRWHrf2tMtNEoYzGtpnDbZdq3Sp7 UdtZ6mmOX3DwcSQ909z/6YcrHKHbXL+LXS6/LzwOKlJZyGRUfS93RGb2dJ9Va0Q4eSyI an9vaLdvEGBRlPfVju5ZdZUH2ubSwe8vGP0Bp27VBnp6g9JNyGLQZUYyTPvk2cpAv3Nf NYmfp3FtSjmXst7vDGi3Q3MwP3wsVLALB+ebKf6OanoTtox6tIhabu8gm/yKBcj3+MCY QAjj7dKJ5CLW2P4QDR4j6eCatmBXIRwl3CRSIATWDI62bprGQXx0wl7tGl1JdsS3qy28 Ohug== X-Gm-Message-State: AKwxyte4ZVIgMUD91eBKEXuynMR4AZfnEkwZPKVmQ2xMzHbPDig2Z9Jk z4BtyzTXBIS4QP6ECJPSjmj9+w== X-Received: by 2002:a17:902:7e86:: with SMTP id c6-v6mr1288998plm.166.1516708849083; Tue, 23 Jan 2018 04:00:49 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id p75sm5853049pfi.148.2018.01.23.04.00.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 23 Jan 2018 04:00: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 V4 2/5] regulator: make regulator voltage be an array to support more states Date: Tue, 23 Jan 2018 19:59:40 +0800 Message-Id: <1516708783-6288-2-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516708783-6288-1-git-send-email-zhang.chunyan@linaro.org> References: <1516708783-6288-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 Tue Jan 23 11:59:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 125502 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1711177ljf; Tue, 23 Jan 2018 04:01:00 -0800 (PST) X-Google-Smtp-Source: AH8x2248MFePtzjdT6bBf+zVdEYCKdx2wMlFStT+DCpsa9CA6OnwooJebljc9TRTcx4TYPWasJSj X-Received: by 2002:a17:902:bc47:: with SMTP id t7-v6mr5350425plz.344.1516708859937; Tue, 23 Jan 2018 04:00:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516708859; cv=none; d=google.com; s=arc-20160816; b=RniswFbPuI63McUljewxRP84DVfT1psd4ueHDwkmLqQa46BbyTNLvnzBpm5vglSRG7 +agbVsEejgFMw59AhnStSTCcPmLtUSHwiXxHjfyVrt7FaaX5OdyeasdOktwInHfIS3AN 9JkMhJQ9maKLxsaifpWHoNdCCdNBspR6hkczdbxLt3XMved1WvLNNg3lRUKIUEVrV4ja AsOmXcBnL2TFSjdIC3m5+/cnFN1x/ezE3+mEQVlUVTt5GPgushiEdN0mJO3dpX/9wTQK a2Je0hoEX/CvhnAnibkAAqiV2b2hKaB/eH1my6UJyH0BLstXs+TxWtvYhYwgM70x7LDV trKw== 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=FKO4AxaTrKbnGuQ8iA4pe8harToDfi8wb0PAzTAZMu3HZPRZ64eN4S4FAKZpDO+YDG a3JocrLeIIUNvCCR/j1vIMn6bMYw4VJAxvEG4sfzgtPyJGypeEMp6LOg2af6R3iJ+i5r EaJainXdNgGCljUIdj7k4ikkhp+0SU6VNfHySeG1ozoAzTR74v7MPMAcu1xs0kEdxCBR E5Z9vlb6CKIC8+6r89uksyfYuGlE126DEh6XXTSxm48ioMzBWuVu6QnB63+4LFK00jXC JWeJbWHQ9lGy1XisZr0VrepNuB2rbRX+vynO4+o1mc4WeDlO2AHo8rwt6RlgZtEHG56b lfhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=M8JrD0S4; 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 l59-v6si4624140plb.743.2018.01.23.04.00.59; Tue, 23 Jan 2018 04:00:59 -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=M8JrD0S4; 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 S1751375AbeAWMA4 (ORCPT + 28 others); Tue, 23 Jan 2018 07:00:56 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:46875 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751169AbeAWMAx (ORCPT ); Tue, 23 Jan 2018 07:00:53 -0500 Received: by mail-pf0-f195.google.com with SMTP id y5so136737pff.13 for ; Tue, 23 Jan 2018 04:00:52 -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=M8JrD0S4Zl8PUP15QmxBF7RxRDwpWw4E5k1GSTlM8ykECeXxHcZ60U5sFg0HojiyTO qYAlyEoA7hd+ddIg5m073uYKq6XN51icVbclM1OTZ5iiQdU8J8LTrtfnBgTrpsPTFnvC 7HD9CmKnExqe/MGh2dS/XPl9cuW7vuztPHsQU= 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=S8WovtVflhy7Bv4A/FoZ5/73PxjgD68Jd6naRoOtAWFVXR3salYkgXBTmJwnU57qlb tEjkF0UE/BAevqBFpUeiN8zYvJtPvOtNwfA1DEu6laXpHz5ov0PTzRizXwy2WIXpApBy lBdTdP1GbzzNXvg2OEqw+uk0EzQxaYwHDiCpaQfU/U9OGDOSSN34huGhh0CloDoK1zKX gE+kQRzm7iG9QOiXZaKBY0qraWVQBvfdoK+ZjCmXbIRUuYzEOe7n5xOOY4jYfH/l4Emu gWaa+z7/ASDoFJelIXPKDtGoSXtcWiKiVSfKnY1c9doiv8ijyLCbu9Q4/mhwRcO5Lj9t UhuA== X-Gm-Message-State: AKwxyte0TkpeB5FnZRRGjpPKKiUKfqivccsRFcbcPDVgIL51Y4a2uYOs Auw5b23z22G2wwCaf2fLDzNRtw== X-Received: by 10.101.101.144 with SMTP id u16mr8552042pgv.73.1516708852473; Tue, 23 Jan 2018 04:00:52 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id p75sm5853049pfi.148.2018.01.23.04.00.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 23 Jan 2018 04:00:51 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V4 3/5] drivers: regulator: leave one item to record whether regulator is enabled Date: Tue, 23 Jan 2018 19:59:41 +0800 Message-Id: <1516708783-6288-3-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516708783-6288-1-git-send-email-zhang.chunyan@linaro.org> References: <1516708783-6288-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 Tue Jan 23 11:59: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: 125504 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1711256ljf; Tue, 23 Jan 2018 04:01:07 -0800 (PST) X-Google-Smtp-Source: AH8x226zwH1JOIJmC/kLemWFQx2JE7JvS2pBDJRy7yiz2fKJMmIvwd3wbYxOq1ABwI674t3bP6n/ X-Received: by 2002:a17:902:e85:: with SMTP id 5-v6mr5393225plx.136.1516708867558; Tue, 23 Jan 2018 04:01:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516708867; cv=none; d=google.com; s=arc-20160816; b=CDMF4V1A7s5pbpHwfggRB7pwnF/EtX0rrRXQerAhZdKAmyESCJih8Oaru2Fv/NyVDo R5auEWOU8CX+QAj1+L5bw8VwaEzg/gjNYKei7ENIGRMclOkKq/8IoIFIbuc3C/5IDAWh GrjbH6/mwQ726Gu5vFHP4kMrY3dGjZiZHlAmPUlqhHBrDekHcGO24z2yZ55pObeC+ALX Whl+Qoh/7k0WqSOVzxViwrqUyW1U9i/5f+/d4R7Ckj2N2HAqdtBujZKKuunHK2MBUXnr o/XLniwsL0IbmJsPu1suJzEUZqH/yVr9lEjIwyrj1QXBrkn3aIanFS8bCw6IwIpjR5Du pKtg== 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=IWJ3mszr09oNqlYiPcCcomDRoYXzAaNJhfoCNZJ3bsQ=; b=hxxqz6FajKClynSP9Zi3r+IYuV5wiTcqvfjNeD8irebTmToPFt898xvSG7JglqUSLL VGJ7aA1mZ3VRq1uCx2vnPab5f52NxWsJVXD7n9rjviAh2dNx3XbiNqs1GFjunZRJ+FGk r0qNyBF5bS5pc48ItO02/cVPTBKNHE/p175hi2QamnG7SFTh51bIrmt6wEOIrQPspldw FIj4HDUtkXve3UKwtBHOr5BzxcNc39RXVRpoiSnRTMWfx5JFqsf0H1+bgnWBTHHINfc+ 30lheNEIUjUP7WLQvSJXtuEyBkKjw+g6oB5BdT7Q/metgbCNxR4cQkugNkFkDBkY05K+ 1fjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZzZqRv6M; 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 k14-v6si2320108pls.587.2018.01.23.04.01.07; Tue, 23 Jan 2018 04:01:07 -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=ZzZqRv6M; 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 S1751480AbeAWMBE (ORCPT + 28 others); Tue, 23 Jan 2018 07:01:04 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:46894 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751419AbeAWMBB (ORCPT ); Tue, 23 Jan 2018 07:01:01 -0500 Received: by mail-pf0-f194.google.com with SMTP id y5so137013pff.13 for ; Tue, 23 Jan 2018 04:01:01 -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=IWJ3mszr09oNqlYiPcCcomDRoYXzAaNJhfoCNZJ3bsQ=; b=ZzZqRv6MAkh6rKpiPv6sdyLVgHyGU2X8qVU4sxlPFk2Rk4mIz1brMpYxsj5kBPIeva 2gbWCTgn7i7ahaGbtpYGLjVSUC3ialATvMp58CCwxy+SZnkdJW+ypU74MXAaxzuct9CE I9fLjX/Lnu7FgitpBMwmfm+/L1gT2sE3UDnYY= 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=IWJ3mszr09oNqlYiPcCcomDRoYXzAaNJhfoCNZJ3bsQ=; b=tmpDBDvZM3coxEiDjBMTvAlHSmzOtt/L+69VvEQOgED15St0YB83YDc6ExEnNaFg7Z X9Q4S0W0cO6yJOfXDIJm3bgziYv9WgzrlA4UrXi/tyJidp2l9woyOeF/wnkweLr4uiOJ f7GV5RHEx4KfmVUz7POD6AzxMv1NLl69TNbPZXe8o8tvwFidPFZQLWNtLdoCFrynq3tb DiKLu8aBrjIx0YKuNBMjexxBEHe5gpZWVLZMC0took0Q0gryEBhO7L5f6W4kA3QZwEiM 5V5CNZWESxwuRCzJmiM0DQsByVvuqXiiH5tzT8ebU6faPCKdgI5V9gupKZyEFe+Xl6NT ga8g== X-Gm-Message-State: AKwxyteXidvmXbgz8OIg6Gxxh9lhlMuo+F1hr7fKU/F8UEi4PWMAS0pE LpLjbI8j3xpACD9M5APRM4GxLA== X-Received: by 10.101.97.12 with SMTP id z12mr8355497pgu.92.1516708860626; Tue, 23 Jan 2018 04:01:00 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id p75sm5853049pfi.148.2018.01.23.04.00.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 23 Jan 2018 04:00:59 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH V4 5/5] regulator: add PM suspend and resume hooks Date: Tue, 23 Jan 2018 19:59:43 +0800 Message-Id: <1516708783-6288-5-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516708783-6288-1-git-send-email-zhang.chunyan@linaro.org> References: <1516708783-6288-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 | 245 +++++++++++++++++++++++++++++++++----- drivers/regulator/of_regulator.c | 14 +++ include/linux/regulator/driver.h | 2 + include/linux/regulator/machine.h | 13 +- 4 files changed, 241 insertions(+), 33 deletions(-) -- 2.7.4 diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 080c233..0dfa758 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,7 +4295,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..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; }; /**