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;