From patchwork Thu Dec 21 06:25:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 122508 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp485377qgn; Wed, 20 Dec 2017 22:25:53 -0800 (PST) X-Google-Smtp-Source: ACJfBotsqVz4m5mEHBFC9l4OT5ToSzS12wq4SYEk6wap9DQ5qHPZzOlryxSJvhjl4QJSD7YlLx9e X-Received: by 10.98.152.25 with SMTP id q25mr9522993pfd.58.1513837553799; Wed, 20 Dec 2017 22:25:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513837553; cv=none; d=google.com; s=arc-20160816; b=tQe+iNVmEre9RqOwgjCQ2P+d0gJc5Q4IN61bChh0Epmr9DVSlKdrr9zs08COgTzquF Noi/P3t2+SQCK6vAQD0MJyTZCRuSOaFN2xne2GTyBs+PuBqoXmTCMGZ+8kuAvc6H5MUB j2Ugm31RTjkEvJPAxLm7N1l9VHI9itW6qkfg9PHlas/7EWaPSKuWWrFPR/8HN0yCw8dI S0kW3Zl1ZKBVDHN3u7AmBgRroq34Hde3HpWTJ5hVhNQ47xvT/x4ebGAjeolSWfTvePFV eCpYfOttCe4iwv8bM03SG7mZ96UMz0qTTFCjW1MROAAf6Y713tRfXzU3LjAKXuA0JGmT 6GJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=3fGcyQm5MzO+IikfJbd6xonOoxnRNHYtVLII8nMPgX0=; b=D45o04ZpeMAHIJ9LqJtTrPeaaGI3XFx7ki+xnqvdG280L/O6hCp1pDkNPLyF8ymUil 10w04aynEv6DJt0pQw0/hpsrRxjZvDeqzB1v/SoDODzc+mbm8mQC7yVVIAltgewDCWo2 8HDv8Nv+gDR8jE1KYfJWyPD6pbmSXGGUaHY8nAtoluRJJVHN0CWT0B0uSM58nLFuJlB8 U35uV4lGVLRzjLnRt4pKxwYhoeAc5SeNnGkq73ZLmPD+ZSc+IVOY/6vzK5rJ53s6jOwY 1e6RGpZv5rDJfWnTCRUDk6kstyuZbTpNcxNRzUpqFWx9VXRLXqc4y6W1NJeOQSFtKw8Y D0cA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eX6Vge1q; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si1638719pgf.122.2017.12.20.22.25.53; Wed, 20 Dec 2017 22:25:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eX6Vge1q; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751845AbdLUGZj (ORCPT + 6 others); Thu, 21 Dec 2017 01:25:39 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:37217 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751716AbdLUGZe (ORCPT ); Thu, 21 Dec 2017 01:25:34 -0500 Received: by mail-pg0-f66.google.com with SMTP id o13so2162052pgp.4 for ; Wed, 20 Dec 2017 22:25:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=eX6Vge1qKc8YJXP+/p2ZXlXm9/VKCs70YVs1h35EWr43H9RgTCQyvSI6umkV0cfPKB J3C4gBvphZH9ZWNZ2JTirgwV4/emwTAIPEd9pG69n7RtB/nBC6r4kq9Lgr/Y2GB+kZ/T ML04qIFj+9rVKvH96oZztMPM3bIRy4bSkZZNo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7bkU8d6OAw4dJNJomrati/RpvribAE2V8BOdwc88N+k=; b=GX3c4M5G+D+OqVdSTcCgayICQLGeurtz3uKoexxMzuuqi83IYp9OUM1YnjsTh9JnWC UQEvOhy4xqiXHCKvM5qyDuX4waFJpRTIO4Ut/J6moQ1o8DskCpmrDmzce67LpWwaiM+4 oN1x5/rHPdKeVgPrKyafhd8lFEyHLvVfps28U1kgrObXiRA7wclqGcs6RrSkFV76SHQ6 ttnQSBC4U2BSI1i8/ghdDrpRqdkbLYXch1aHkiuOnLwsVfVrAZyMeYTYR0HbSVsAxwYb hk2dM131+Ek61VxFqPGfDB8fEiIg/GL+095HnOD4yd28zG8rtPxT7YnGM5xPC/5b5vtu 3Qeg== X-Gm-Message-State: AKGB3mIlHyqMf57acKnRl1cC75MXTGK8jRlwLkse/n4nKMEGgahffN5Y +sTZA/TGVkcrJbnFyM8i0Q1ijw== X-Received: by 10.98.109.65 with SMTP id i62mr9359319pfc.139.1513837534213; Wed, 20 Dec 2017 22:25:34 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id o88sm36970683pfj.175.2017.12.20.22.25.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 22:25:33 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chunyan Zhang Subject: [PATCH 2/5] regulator: make regulator voltage be an array to support more states Date: Thu, 21 Dec 2017 14:25:03 +0800 Message-Id: <1513837506-26543-3-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> References: <1513837506-26543-1-git-send-email-zhang.chunyan@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Some regulator consumers would like to make the regulator device keeping a voltage range output when the system entering into suspend states. Making regulator voltage be an array can allow consumers to set voltage for normal state as well as for suspend states through the same code. Signed-off-by: Chunyan Zhang --- drivers/regulator/core.c | 63 ++++++++++++++++++++++++-------------------- drivers/regulator/internal.h | 18 +++++++++++-- 2 files changed, 51 insertions(+), 30 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b64b791..97bc9f7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -240,22 +240,25 @@ static int regulator_check_voltage(struct regulator_dev *rdev, * regulator consumers */ static int regulator_check_consumers(struct regulator_dev *rdev, - int *min_uV, int *max_uV) + int *min_uV, int *max_uV, + suspend_state_t state) { struct regulator *regulator; + struct regulator_voltage *voltage; list_for_each_entry(regulator, &rdev->consumer_list, list) { + voltage = ®ulator->voltage[state]; /* * Assume consumers that didn't say anything are OK * with anything in the constraint range. */ - if (!regulator->min_uV && !regulator->max_uV) + if (!voltage->min_uV && !voltage->max_uV) continue; - if (*max_uV > regulator->max_uV) - *max_uV = regulator->max_uV; - if (*min_uV < regulator->min_uV) - *min_uV = regulator->min_uV; + if (*max_uV > voltage->max_uV) + *max_uV = voltage->max_uV; + if (*min_uV < voltage->min_uV) + *min_uV = voltage->min_uV; } if (*min_uV > *max_uV) { @@ -1356,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, debugfs_create_u32("uA_load", 0444, regulator->debugfs, ®ulator->uA_load); debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->min_uV); + ®ulator->voltage[PM_SUSPEND_ON].min_uV); debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->max_uV); + ®ulator->voltage[PM_SUSPEND_ON].max_uV); debugfs_create_file("constraint_flags", 0444, regulator->debugfs, regulator, &constraint_flags_fops); @@ -2898,9 +2901,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, } static int regulator_set_voltage_unlocked(struct regulator *regulator, - int min_uV, int max_uV) + int min_uV, int max_uV, + suspend_state_t state) { struct regulator_dev *rdev = regulator->rdev; + struct regulator_voltage *voltage = ®ulator->voltage[state]; int ret = 0; int old_min_uV, old_max_uV; int current_uV; @@ -2911,7 +2916,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, * should be a noop (some cpufreq implementations use the same * voltage for multiple frequencies, for example). */ - if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) + if (voltage->min_uV == min_uV && voltage->max_uV == max_uV) goto out; /* If we're trying to set a range that overlaps the current voltage, @@ -2921,8 +2926,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) { current_uV = _regulator_get_voltage(rdev); if (min_uV <= current_uV && current_uV <= max_uV) { - regulator->min_uV = min_uV; - regulator->max_uV = max_uV; + voltage->min_uV = min_uV; + voltage->max_uV = max_uV; goto out; } } @@ -2940,12 +2945,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, goto out; /* restore original values in case of error */ - old_min_uV = regulator->min_uV; - old_max_uV = regulator->max_uV; - regulator->min_uV = min_uV; - regulator->max_uV = max_uV; + old_min_uV = voltage->min_uV; + old_max_uV = voltage->max_uV; + voltage->min_uV = min_uV; + voltage->max_uV = max_uV; - ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state); if (ret < 0) goto out2; @@ -2982,7 +2987,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (supply_change_uV > 0) { ret = regulator_set_voltage_unlocked(rdev->supply, - best_supply_uV, INT_MAX); + best_supply_uV, INT_MAX, state); if (ret) { dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", ret); @@ -2996,7 +3001,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, if (supply_change_uV < 0) { ret = regulator_set_voltage_unlocked(rdev->supply, - best_supply_uV, INT_MAX); + best_supply_uV, INT_MAX, state); if (ret) dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", ret); @@ -3007,8 +3012,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, out: return ret; out2: - regulator->min_uV = old_min_uV; - regulator->max_uV = old_max_uV; + voltage->min_uV = old_min_uV; + voltage->max_uV = old_max_uV; return ret; } @@ -3037,7 +3042,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) regulator_lock_supply(regulator->rdev); - ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV); + ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, + PM_SUSPEND_ON); regulator_unlock_supply(regulator->rdev); @@ -3138,6 +3144,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); int regulator_sync_voltage(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; + struct regulator_voltage *voltage = ®ulator->voltage[PM_SUSPEND_ON]; int ret, min_uV, max_uV; mutex_lock(&rdev->mutex); @@ -3149,20 +3156,20 @@ int regulator_sync_voltage(struct regulator *regulator) } /* This is only going to work if we've had a voltage configured. */ - if (!regulator->min_uV && !regulator->max_uV) { + if (!voltage->min_uV && !voltage->max_uV) { ret = -EINVAL; goto out; } - min_uV = regulator->min_uV; - max_uV = regulator->max_uV; + min_uV = voltage->min_uV; + max_uV = voltage->max_uV; /* This should be a paranoia check... */ ret = regulator_check_voltage(rdev, &min_uV, &max_uV); if (ret < 0) goto out; - ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0); if (ret < 0) goto out; @@ -4424,8 +4431,8 @@ static void regulator_summary_show_subtree(struct seq_file *s, switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%37dmV %5dmV", - consumer->min_uV / 1000, - consumer->max_uV / 1000); + consumer->voltage[PM_SUSPEND_ON].min_uV / 1000, + consumer->voltage[PM_SUSPEND_ON].max_uV / 1000); break; case REGULATOR_CURRENT: break; diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 66a8ea0..aba8e414 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -16,10 +16,25 @@ #ifndef __REGULATOR_INTERNAL_H #define __REGULATOR_INTERNAL_H +#include + +#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1) + +struct regulator_voltage { + int min_uV; + int max_uV; +}; + /* * struct regulator * * One for each consumer device. + * @voltage - a voltage array for each state of runtime, i.e.: + * PM_SUSPEND_ON + * PM_SUSPEND_TO_IDLE + * PM_SUSPEND_STANDBY + * PM_SUSPEND_MEM + * PM_SUSPEND_MAX */ struct regulator { struct device *dev; @@ -27,8 +42,7 @@ struct regulator { unsigned int always_on:1; unsigned int bypass:1; int uA_load; - int min_uV; - int max_uV; + struct regulator_voltage voltage[REGULATOR_STATES_NUM]; const char *supply_name; struct device_attribute dev_attr; struct regulator_dev *rdev;