From patchwork Thu Jan 4 07:22: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: 123392 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11108893qgn; Wed, 3 Jan 2018 23:23:46 -0800 (PST) X-Google-Smtp-Source: ACJfBosIP8jfO3xOihxO1Ua3URrjN6E/O4LkbABLpGiH7Yg08B4air3jFcwEQae8gGQ/POTTGO8D X-Received: by 10.99.165.25 with SMTP id n25mr3307617pgf.406.1515050626332; Wed, 03 Jan 2018 23:23:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515050626; cv=none; d=google.com; s=arc-20160816; b=MLmp3Dtc18Kv3rWfl87ia9fFwtXczFKxlgdcKMID4bNp6a3+1xqcNeOh5VfeceIUVB ejHs2qmp+OvlNHn5bVw4BrG+v7YVTcZo33T8kgr0Af/C/9gNeimYDl4pRlkCqj3zBfVP ODrBPdx0wbXmen2Aqm8cNMjsX3RX3h07a4lI2Qt8fCnyVfWp39Rp110CbpwnrbwUyExq QFPwzyAFNMYriipDsvdbnLnGK/d0MALeKJ/yGVo0XUrZCOamQbJdTi3iuI3xeSSIemn2 ioGY6Dih7BcuekUpjMueKRT45I2UHa7vNrx12ZEn0e9MomWNG8w6AKxEJ52CbmLK96uo FfIQ== 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=FrAzK6kKJcDH2tufRv2eoSQNGoRTOWjdJwbNYcSwwWY=; b=F8FCa9KdVwROnMq5Hv6vJD4Jk+slp8/qZfk/aVNGjkv1xZqYM8UF0CQaST7Dq3hvnV aY876YxS7Dp6UQfpIdS/m+j5cT5njDhEUeNtBEq8wOIS0vJlTNgiAtoTWZvuiEw9uiH7 xL84y1KYo1flXiS5m4VGAJ6W9YyVwLlXFqC8jgxyj+hYTA7z6KmhmzNjMvDN0gn5nRjx U97bGehKSjKQ/QBNxV3uZuz9YYcfD6BDmlLtcx+f6fbE3t+I5Vh+gDxaF1/gLCizCp8I OCtYyTs9leu+EoYeFaHuKuvvA9WfQLAAL/Mkny3IKCdt3liQBYAluf5+6Fex9J+h5pYT RKvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cSwed873; 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 q1si1922656plb.29.2018.01.03.23.23.46; Wed, 03 Jan 2018 23:23:46 -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=cSwed873; 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 S1752104AbeADHXn (ORCPT + 28 others); Thu, 4 Jan 2018 02:23:43 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:36722 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751493AbeADHXl (ORCPT ); Thu, 4 Jan 2018 02:23:41 -0500 Received: by mail-pf0-f196.google.com with SMTP id p84so437693pfd.3 for ; Wed, 03 Jan 2018 23:23:41 -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=FrAzK6kKJcDH2tufRv2eoSQNGoRTOWjdJwbNYcSwwWY=; b=cSwed873ri16n9dP2ovE+/YZnZs461ZhAzh4mp9xofwzNEyooUm3aJTtSlmnPm+HUT 39bURJQB8OZhhfhtHd+LBA4+MzBpDzn0kuyLPbpoyp2G121Xd1z883l6qRCoG+S8cxYZ BrYhU6gpcCB267/bdn9N+kMRsVwA+RQVVw5C0= 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=FrAzK6kKJcDH2tufRv2eoSQNGoRTOWjdJwbNYcSwwWY=; b=Na88iawNas+8Lob6VJxW3zYl8UcSFAxWsoW8cGjQtxZklHL6cwI9Mft0Z+Q04cHRws H8/xhilN6aVYrt+zAjlA9t6qm6YOLZ7RFpxr6cFqAQ/YYI1i8oZLhKZQFtgR3bTmGoJ9 71WyvF+RlnV51tfduFLrbR0tq0DbCWcTdcAG0YkzrabvVmGfXysFJ4HpVaPkIcC3F4Tk QrNA3XbZe0hoF68vaqonnJLFtvxjX3NGJjAYGcdjdgNHeFQYFUzvVQDGmUg8M5iLUU6Q IZh5J6ARulFxqv838ppa6A4YgN968KLCdyJzzjNYvoaIkG2RAPm0kFxiMUVktr6uWS/A uNdg== X-Gm-Message-State: AKGB3mK1XcauDnW5B6rFH1Ow6lJtrHLqR3Pe02Lcbn1Vw3e/CcmRvI5K LRM49je8nMErjx/KyTNSJG3tWg== X-Received: by 10.101.81.135 with SMTP id h7mr3401110pgq.422.1515050620987; Wed, 03 Jan 2018 23:23:40 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id s14sm6244456pfa.158.2018.01.03.23.23.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Jan 2018 23:23:40 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson , Chunyan Zhang Subject: [PATCH V2 1/5] bindings: regulator: added support for suspend states Date: Thu, 4 Jan 2018 15:22:44 +0800 Message-Id: <1515050568-23876-2-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515050568-23876-1-git-send-email-zhang.chunyan@linaro.org> References: <1515050568-23876-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 --- Documentation/devicetree/bindings/regulator/regulator.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) -- 2.7.4 diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 378f6dc..532e286 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -42,8 +42,19 @@ 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. The voltage for suspend also can be + adjusted among {regulator-suspend-min-microvolt, + regulator-suspend-max-microvolt} by calling + regulator_set_suspend_voltage(). This property is not deprecated, + setting voltage for suspend mode via API the 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 Thu Jan 4 07:22: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: 123396 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11109419qgn; Wed, 3 Jan 2018 23:24:34 -0800 (PST) X-Google-Smtp-Source: ACJfBoslHyD12Wc/+0tho8HnhiTmHmVjk/ZJiEMg6U/e9EgQ2kVu1Y+CvGuC7Y8KdFgOcvN6rADL X-Received: by 10.98.214.21 with SMTP id r21mr3898625pfg.74.1515050674651; Wed, 03 Jan 2018 23:24:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515050674; cv=none; d=google.com; s=arc-20160816; b=zNzD93WnM9T8FdvwJJBJXuTqNVqQw3eZW/DcddQK2CtN4KDn5XmdLwB0yKV6UM3mhS Tqrp/lz2aMssZk8+cIGEWz4onRnSV7AqQpURWnOGZXjESiOlIg1dv8u7x4rHfLaRsSrO CNnWIql3RkAJr580mE+Gi4Cw00rBN4bS5aZmPN0lbHWzwzRuvbzFyVZ/4c+c3tpL4yjN 7XokoQp0HEgVBdY/NTJNIFnpHZ8YEz25I9ujtJ0vdOzlN3p0AWWmaSbOHmgGpPLDsgm7 B+1bbSaSjFmlJU6jFaYPnG4ZWyHJCwTbjt0bXieCIe2U8GC9FPOQdPLtQKhGhqwK9XLd ieCw== 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=vEQDT+5OPYSkwtGuaJBqQaaBDnbtZHO4oXvKBGvMHLvzJ6k6jdOhqVv8TrZzT5hyoz 9SciQIdX+MqSOO5MQd2ZKhxg+FCBzlVitcZltotCAWp9FEI/ZSH6iikunqwOzHQhICEK 5K0ertzP7paQsEax3oli9nKdX85NCmuArJFIGwuh1rCLu475lT6i8nX6neM2LfY1PkjI j2PdBYumpzLHgEuPEZ0JvXtXkRRWihzb4OgWkEHx7GpzE1uaW/uO2cYFbi2ZvxBey43w Us7niURzB9KtbzEY5E5OE8nEVY0OLAFzuVJGcUz1m007EXqv5MMia4JgG6cYca4VCR3W aRWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FtYf9iND; 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 v10si1897186ply.324.2018.01.03.23.24.34; Wed, 03 Jan 2018 23:24:34 -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=FtYf9iND; 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 S1752139AbeADHXu (ORCPT + 28 others); Thu, 4 Jan 2018 02:23:50 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:38148 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751840AbeADHXq (ORCPT ); Thu, 4 Jan 2018 02:23:46 -0500 Received: by mail-pf0-f196.google.com with SMTP id u25so436315pfg.5 for ; Wed, 03 Jan 2018 23:23:46 -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=FtYf9iNDTDTftlCMDfjoxKTtDo1DdpnAGCNEGKokayk/uozh2Bnrm019e7jFkqJ9qS AvY+mluLrRvrR+r6KhaMGcLZVEyjgyBXiPEws/qkdN/IG33k7ndWy2YEYh8Hk6J+7RNG cUNsn8MUbur9tYRiMqnj9ZZt0rtqRQ3VHMT1A= 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=DOumyanTrZo3QOG5wb5OmvT9sQ+LYDBKT+szNo8dH3JBVfmi7nVl4TwyUFkihAY14B /G5h2jvkzlzI3Ll0U9m3+2lnP42gQcsBPx2PQQx8QTjHnmbaf/8YwVuYjwVS9pYdS30S em9RIfdRd0K0eJWtpTCspA+gK+wHoBou/PxGfZ4Wb0KGOEiiukZvx/wxMuH0HdlVMli5 9tp9U0nypiI8UnelsdQJ/IkMJFRWbN6Wtnki2InbYbTruNxfXzVhGCSIds+MYljSTaKC +Hb4WaFF3wcyYpYMEJYfEBINI81PE9Z9Nr5oVNRD6hQhNeXh7MEiu52ELqFpezMUYFZZ jAsw== X-Gm-Message-State: AKGB3mKN+/TTEm6BnUN1dxnlJVMNlwK7hPBFabxanWcyN+BbVM56rrIW PZWYV4H+Vw9H7On+fDmPoTb+6g== X-Received: by 10.98.15.29 with SMTP id x29mr3791811pfi.232.1515050625773; Wed, 03 Jan 2018 23:23:45 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id s14sm6244456pfa.158.2018.01.03.23.23.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Jan 2018 23:23:44 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson , Chunyan Zhang Subject: [PATCH V2 2/5] regulator: make regulator voltage be an array to support more states Date: Thu, 4 Jan 2018 15:22:45 +0800 Message-Id: <1515050568-23876-3-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515050568-23876-1-git-send-email-zhang.chunyan@linaro.org> References: <1515050568-23876-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 Thu Jan 4 07:22: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: 123393 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11109039qgn; Wed, 3 Jan 2018 23:23:57 -0800 (PST) X-Google-Smtp-Source: ACJfBouQt0yOiZJPgCLCzqZS3IlQISUN6Vwo4Z3Xnh7GscTl40QdXWUzYGipQb1aBnlkmetEcejX X-Received: by 10.98.110.193 with SMTP id j184mr3890682pfc.187.1515050637454; Wed, 03 Jan 2018 23:23:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515050637; cv=none; d=google.com; s=arc-20160816; b=LIjhT5XmChlnRPrQ+pEeevjSEnBl0qKwtX5DeDRetr1+S+eGWN4U0ChCak6xBnUpcO XHwKAJeMBJQ3+V9H80IlcVV/DiNb8iu22VfNYscfivlrVXHXtKhsnUQyEuJ/jan46akC m471osz2L7ym2DkEx5667sndbXv1swQ5IA0jT6BrKbjPv5xwBigPPNaJVJXCfzy2vkLs SpvUWbSsjcKxvFOSnfhOrk2guJ66M91ytpcb6mWC1Nu7CPEBUPc+iTiL7GpRz7Wo8ohB TYAqqak8Ql1LYILfXaFxYPdd7KYMRf6m6KZRTdGWylQ1EPiWaIj/jQLU8XRTx6mWU472 a7DA== 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=9azF0a/CRva7kzQyUrrdYveI6VR5wsw/N+Df49tk6LE=; b=dhQ59lKJIVSs743vyGWr6S87tYNnf4oNPBnAVjYUhZDjrlLlkWHWU8vwcuHjGaO8Q4 o0AXzciOneFWtcqkkVPABKe3ELQ15HUZmEzS9+JlzFf0Gg5bkjfQEPoAut9edA8C38bU 2kH2hbpFW196dbZrJgiR9v1N1aHae9Tz5vSr7+E4KVVVkcQYacXY7p5LfzHdrCVgKjGw 055wpbs+YPugs2mujC2UAk6HPVyJdduD/Z7+9BaU/h7ztCiJz3MxdkToEN3glcM1kTbW 3047LtRuWskl2uOVG214Ci+7zF1rtVpvEDlDnxhcKf/kotQY42Aniv5GWMSIcCLLbKJF IzZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=I0ESj1hc; 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 c32si1913374plj.281.2018.01.03.23.23.57; Wed, 03 Jan 2018 23:23:57 -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=I0ESj1hc; 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 S1752187AbeADHXw (ORCPT + 28 others); Thu, 4 Jan 2018 02:23:52 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:44397 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752132AbeADHXu (ORCPT ); Thu, 4 Jan 2018 02:23:50 -0500 Received: by mail-pl0-f65.google.com with SMTP id n13so590361plp.11 for ; Wed, 03 Jan 2018 23:23: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=9azF0a/CRva7kzQyUrrdYveI6VR5wsw/N+Df49tk6LE=; b=I0ESj1hcbI+yVHOEvKhKnHVmEQtkkLnNNBJ2ZAOkw6MM2HJMIdAoRJ0V7ygh7pQNfe ow7aijZ0dLSFjAfrr8KfQMMQOiHm1wk55JnMf9eSSNUf7RbPyP4+x43Tug0RCisD4tll rBGOnsa2mxJt6/IifnkuazX6Nj/a8s+MYnV50= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9azF0a/CRva7kzQyUrrdYveI6VR5wsw/N+Df49tk6LE=; b=b5rsTx3+sd7QfP3dM8rOWVrU5uf7sFp6hOZ9tdctHFNhogJw1ITPMy3Wvp3uOV32+c +KFdLzLBmbE9o5Kl5hZkUuwm61/hcpO5BCW2Pa4TXKUSjQ2LfMv89jPEzjVpmKdjDOSR fj6ky7X82KFndrrfyZBMJVkBFXor7ACOPrQ7KfRK6zP1PS7rhZaM/gkLAuXFAfzu7KQo LSPAKpG2blW/dzGV2DW8ZJE0RokWMAMNx8YLtTYqe1/Kq735MbVxNTvCXT7u5TP3p+0y LxR2X5oSv10X7xm5j+sahU8CpEKDCLyz9WW4zAZEU+dQWKGL29dTNMoiyVkYtX5JiqOW zhiw== X-Gm-Message-State: AKGB3mLhBt7ZkwBxyP7vMySpxJsWhrr8iW13appwcfebJR1HPg5vx8tq XUqNwq/aSkKoJCpqp7v1oOs4/w== X-Received: by 10.159.205.135 with SMTP id v7mr3740645plo.371.1515050629542; Wed, 03 Jan 2018 23:23:49 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id s14sm6244456pfa.158.2018.01.03.23.23.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Jan 2018 23:23:48 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson , Chunyan Zhang Subject: [PATCH V2 3/5] drivers: regulator: leave one item to record whether regulator is enabled Date: Thu, 4 Jan 2018 15:22:46 +0800 Message-Id: <1515050568-23876-4-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515050568-23876-1-git-send-email-zhang.chunyan@linaro.org> References: <1515050568-23876-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 | 12 +++++++++--- 3 files changed, 19 insertions(+), 13 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..e50519f 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -42,6 +42,11 @@ struct regulator; #define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_BYPASS 0x20 +/* operations in suspend mode */ +#define DO_NOTHING_IN_SUSPEND (-1) +#define DISABLE_IN_SUSPEND 0 +#define ENABLE_IN_SUSPEND 1 + /* Regulator active discharge flags */ enum regulator_active_discharge { REGULATOR_ACTIVE_DISCHARGE_DEFAULT, @@ -58,14 +63,15 @@ enum regulator_active_discharge { * * @uV: Operating voltage during suspend. * @mode: Operating mode during suspend. - * @enabled: Enabled during suspend. - * @disabled: Disabled during suspend. + * @enabled: operations during suspend. + * - DO_NOTHING_IN_SUSPEND + * - DISABLE_IN_SUSPEND + * - ENABLE_IN_SUSPEND */ struct regulator_state { int uV; /* suspend voltage */ unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ - int disabled; /* is the regulator disabled in this suspend state */ }; /** From patchwork Thu Jan 4 07:22: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: 123394 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11109100qgn; Wed, 3 Jan 2018 23:24:04 -0800 (PST) X-Google-Smtp-Source: ACJfBosHsP8pS496ZM3DJbLyPyoQI/KGz9j+67bI+A8vMDJMTANv8odCX4i5TWaIiqmTQfis+y/H X-Received: by 10.98.152.25 with SMTP id q25mr3890736pfd.58.1515050644008; Wed, 03 Jan 2018 23:24:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515050644; cv=none; d=google.com; s=arc-20160816; b=Xm8Bq4HDrZESXVvsox4EE+6HqFCAJ3x5EXdJxivFqVy0b2bKIvcZ7Xn8xjBQ8pPdct p/UzPr/HHT9pQQQHrfobX5hmAfKDIMv3yVOvP6VQpadDdjvZtFp2PCaikEqtE/K6Kcky 7kytyXklqhqoDkEQIkAlZPYexauTKqsPGqVNBTULy/XxFW0L1FShcVwgfSrBUtnRsIsp /CTwEIJaRDB00HBKOaFHoiawKcxibYbgPzOQ8k8IT/dE7uNB+rPw8b2+TDYsCh+ro/uS LWVTnZktk1432538+NgmTu+hRwIgZFlY/au150+k3NyUN15fkzkrSMnuqeYaOvwZJ+WV MkjA== 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=nHRvBhsC1LnmuY+PtNiblL3WT5zYTHI7fmJowkn1glI=; b=CDl6MK+ulRrKNUXOC3tH2FuLsYYty8YkqgG8hc8cKuBX1v/S59N0ZwAQqZkuCrb0ev fMzh4f+GTk7qfDszrwe20NnprCSkMivd2eXZY2kyq4+zd0sfbmU7XhhACPCge4Mhf9XP FFRiESo1ggjlv8oZjkc24mDtp7VHb/BOvOlInueLHVZssy+Q/y7sU04r0wtZXROAaCIn Dt37clfeHRrNs94DLSbCyHvn/+wVhAAV0Cw/gvlSIgPJ5V2j7ilVKWV/vCDIIvIYV1vY j4+fAmIsiksPkSVLf+UKyEDfBttBJPAGMfPwztrXWFwHGGeQF4YkW2QU0B4va3CYg4dF duoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OwMer/Fz; 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 l12si1906800plc.265.2018.01.03.23.24.03; Wed, 03 Jan 2018 23:24:03 -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=OwMer/Fz; 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 S1751995AbeADHX7 (ORCPT + 28 others); Thu, 4 Jan 2018 02:23:59 -0500 Received: from mail-pl0-f68.google.com ([209.85.160.68]:43795 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752195AbeADHXy (ORCPT ); Thu, 4 Jan 2018 02:23:54 -0500 Received: by mail-pl0-f68.google.com with SMTP id z5so594962plo.10 for ; Wed, 03 Jan 2018 23:23:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nHRvBhsC1LnmuY+PtNiblL3WT5zYTHI7fmJowkn1glI=; b=OwMer/FzkogrfRQ2DFmf4RgXRJhtKLmXz06qZ+F6yyUz++vAHrOxwKs5l6drYZp7GL Wuk/ouMYmpsjVlIeC6kHjPxj3wTT/xpCR6WAT3+FEo7fvhFijocstH9SsXBBBUPKbey6 wX6tQyTNCHysZDeLLUa/9vlxOFpvaT+cwBhss= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nHRvBhsC1LnmuY+PtNiblL3WT5zYTHI7fmJowkn1glI=; b=M09NhC5KAw+Xhhu/BBK1cR+lUC4BdJfkW9awQ2/nj8nrahYwg5PREmkZC8+6kCDmlt ZSULdoDdz+E+PJjC1D3V56b1JrcjX9zQ2/MgVfCSNa2deHa37/KzhfH3lDe+s8RHWiKl wjCsx0/AB6/dvmu/GVL/xlUVyO+zeq79fFCa/WbsBklZAdYx00B7Qmv2ylwWTsUncOjz XOTtVpmzX798daQvs+kGhwGerYtWx1C79VtvfRJP+rTOYlw6CD1vT89A1BxZoRaOu38k H0HIDxHPBhSQZdk0n4MQ54biuT3/qM0tpewNb3vqNdVXup/TY+/rcmnrovT/+BX1qqBg BcrA== X-Gm-Message-State: AKGB3mJ3d2Ics6WmXt34s97c14CG0MkMHGDTBYOaqKPOz2FpTklAGHsr ryoBR2386ZvRP8c2DmNpSFI3nw== X-Received: by 10.84.172.1 with SMTP id m1mr3839503plb.345.1515050633659; Wed, 03 Jan 2018 23:23:53 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id s14sm6244456pfa.158.2018.01.03.23.23.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Jan 2018 23:23:52 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson , Chunyan Zhang Subject: [PATCH V2 4/5] drivers: regulator: empty the old suspend functions Date: Thu, 4 Jan 2018 15:22:47 +0800 Message-Id: <1515050568-23876-5-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515050568-23876-1-git-send-email-zhang.chunyan@linaro.org> References: <1515050568-23876-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 e50519f..b4ddb56 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -231,12 +231,12 @@ struct regulator_init_data { #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); -int regulator_suspend_prepare(suspend_state_t state); -int regulator_suspend_finish(void); #else static inline void regulator_has_full_constraints(void) { } +#endif + static inline int regulator_suspend_prepare(suspend_state_t state) { return 0; @@ -245,6 +245,5 @@ static inline int regulator_suspend_finish(void) { return 0; } -#endif #endif From patchwork Thu Jan 4 07:22:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunyan Zhang X-Patchwork-Id: 123395 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11109218qgn; Wed, 3 Jan 2018 23:24:15 -0800 (PST) X-Google-Smtp-Source: ACJfBotBLWBCTIo6PyJTwNE9guB9Ba2MeZNzk5EBGG+PQ1jMdS3jlpvivyZ5vNi+nDD3RMWfHhSP X-Received: by 10.84.242.69 with SMTP id c5mr3747040pll.73.1515050655135; Wed, 03 Jan 2018 23:24:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515050655; cv=none; d=google.com; s=arc-20160816; b=jRs+H3ORqjXIsCrwAS51lbnNCnIudTXcTvamF65u3qH4eUw9yHPyD5VeeGM8t1iKPX Ftwg/IT9paqQeH08OvMMYnTqw40icKDOhAtDk2gHAVd/EQcIxOVBQ+U2wQgoPBPRyOiT 8tpcsU5VAPNe4cmMxC1sEUspMYyqLdB9VTuf4kCwUiacNZOtu/VZ9K4LarcQLhC46ojx QNHPQOtcD9qXwRcczmgW8CohMzJE7++MUfajP7md2Jkd7fDsC83R3Wxukf8gdAIVVLa7 sQlknL19rm9BKrjulu496tHnsPbwxVz7I3D3T6lmyEdUeVvXdHo4/AM+Z5JuR2UFtABt kMeQ== 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=/DdbEiBqcN7QbxpagQVRdsaYb/A5W7VpoaQjEVHGYWA=; b=kDHpYuXvlT/WyQ6H/gGBxdnZTO404Njk+hNICrWgzHhDoqjnn2Q1lYBDw2GirHhadi s751rdJxzsLfpjrE+tAAh9j+bfy8pQRpJeASTX7SYmzV+ZAvM4ldcETUVQf5xEmkNMGi foc8rrfVykrkIYepgtK3ZkkV6PpgnMPa94mKeOs06KZ5E0MIw4+wy/VCWrcanFS0Ggv7 smIX1rTBus/DlUpOdae210wIV/mpPwjnqSDnIlN/msy/wk81p1UkSsvTSNa+xWsslPiG Z56keFiRaJdAKHpsXD/RmusiO+eaaLLhaTTCIgJ1IBMorjpWjdUYuuya+9PYi4PpafAV u9WQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZmeLWXLP; 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 v10si1897186ply.324.2018.01.03.23.24.14; Wed, 03 Jan 2018 23:24:15 -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=ZmeLWXLP; 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 S1752283AbeADHYL (ORCPT + 28 others); Thu, 4 Jan 2018 02:24:11 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:38153 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751788AbeADHX6 (ORCPT ); Thu, 4 Jan 2018 02:23:58 -0500 Received: by mail-pf0-f193.google.com with SMTP id u25so436440pfg.5 for ; Wed, 03 Jan 2018 23:23:58 -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=/DdbEiBqcN7QbxpagQVRdsaYb/A5W7VpoaQjEVHGYWA=; b=ZmeLWXLP0F4pUQB4hgOUHz2GH/PBrYBsNNNQQlJr3v8cc+/0Gqc+gDVJDikiRJTKcr 5CtiXjQvK+7Bh+l6CIVPhgS0maA97pXoE9wDT/J7BMCmWER52qUvYWbiFD9uvf6xR9wN 9+5IisftX+yhOVXALjAE66xkQlXIfwewdp9/M= 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=/DdbEiBqcN7QbxpagQVRdsaYb/A5W7VpoaQjEVHGYWA=; b=er9M13vMJq58fjhrXbne9XO2ZFbZ6djx6QOb7mCUtsNC9a+cnmneekH1C/UsFlYCLT OenJBImKiXdbj8Tiuecr5HBvMZjZutqkSSov6ibGygfrm637E7mdNqR6HuwabyCO0OFN tXSheDW0UUtdFGtb7vPg33gvg3e/AFeT5eUwr+7KGBsPKVDwv+9OFfGH8PpslolzV1fr 9W9Y2nI6TaiLE8TuElr5y/jc7OXkqShjVMmMfVcSsJtFlADrbTb3Ls1DZTLQ6lEMHtCu UrMiZY/0/ry0jkHQbJknPcLrpFXabpbbRppYv9UkuYh9c4cjC48OltuTZyZlOfL3QpQ5 CVtA== X-Gm-Message-State: AKGB3mLMbFrHueftcRf4Qs4bhZzKLpA3titm8wVcIQC/DBkM3w35fjGe kthfwpMKnERpwMRKDWEU4lTnbg== X-Received: by 10.101.66.67 with SMTP id d3mr3277461pgq.244.1515050637587; Wed, 03 Jan 2018 23:23:57 -0800 (PST) Received: from ubt.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id s14sm6244456pfa.158.2018.01.03.23.23.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Jan 2018 23:23:56 -0800 (PST) From: Chunyan Zhang To: Mark Brown , Rob Herring Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson , Chunyan Zhang Subject: [PATCH V2 5/5] regulator: add PM suspend and resume hooks Date: Thu, 4 Jan 2018 15:22:48 +0800 Message-Id: <1515050568-23876-6-git-send-email-zhang.chunyan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515050568-23876-1-git-send-email-zhang.chunyan@linaro.org> References: <1515050568-23876-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 | 251 +++++++++++++++++++++++++++++++++----- drivers/regulator/of_regulator.c | 14 +++ include/linux/regulator/driver.h | 2 + include/linux/regulator/machine.h | 16 ++- 4 files changed, 251 insertions(+), 32 deletions(-) -- 2.7.4 diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 080c233..3f4d3aa 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -236,6 +236,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev, return 0; } +/* return 0 if the state is valid */ +static int regulator_check_states(suspend_state_t state) +{ + return (state > PM_SUSPEND_MAX || state == PM_SUSPEND_TO_IDLE); +} + /* Make sure we select a voltage that suits the needs of all * regulator consumers */ @@ -327,6 +333,24 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, return -EINVAL; } +static inline struct regulator_state * +regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state) +{ + if (rdev->constraints == NULL) + return NULL; + + switch (state) { + case PM_SUSPEND_STANDBY: + return &rdev->constraints->state_standby; + case PM_SUSPEND_MEM: + return &rdev->constraints->state_mem; + case PM_SUSPEND_MAX: + return &rdev->constraints->state_disk; + default: + return NULL; + } +} + static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -734,9 +758,14 @@ static int drms_uA_update(struct regulator_dev *rdev) } static int suspend_set_state(struct regulator_dev *rdev, - struct regulator_state *rstate) + suspend_state_t state) { int ret = 0; + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; /* If we have no suspend mode configration don't set anything; * only warn if the driver implements set_suspend_voltage or @@ -779,28 +808,8 @@ static int suspend_set_state(struct regulator_dev *rdev, return ret; } } - return ret; -} -/* locks held by caller */ -static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state) -{ - if (!rdev->constraints) - return -EINVAL; - - switch (state) { - case PM_SUSPEND_STANDBY: - return suspend_set_state(rdev, - &rdev->constraints->state_standby); - case PM_SUSPEND_MEM: - return suspend_set_state(rdev, - &rdev->constraints->state_mem); - case PM_SUSPEND_MAX: - return suspend_set_state(rdev, - &rdev->constraints->state_disk); - default: - return -EINVAL; - } + return ret; } static void print_constraints(struct regulator_dev *rdev) @@ -1069,7 +1078,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, /* do we need to setup our suspend state */ if (rdev->constraints->initial_state) { - ret = suspend_prepare(rdev, rdev->constraints->initial_state); + ret = suspend_set_state(rdev, rdev->constraints->initial_state); if (ret < 0) { rdev_err(rdev, "failed to set suspend state\n"); return ret; @@ -2898,6 +2907,35 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, return ret; } +static int _regulator_do_set_suspend_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, suspend_state_t state) +{ + struct regulator_state *rstate; + int uV, sel; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; + + if (!rstate->changeable) + return -EINVAL; + + if (min_uV < rstate->min_uV) + min_uV = rstate->min_uV; + if (max_uV > rstate->max_uV) + max_uV = rstate->max_uV; + + sel = regulator_map_voltage(rdev, min_uV, max_uV); + if (sel < 0) + return sel; + + uV = rdev->desc->ops->list_voltage(rdev, sel); + if (uV >= min_uV && uV <= max_uV) + rstate->uV = uV; + + return 0; +} + static int regulator_set_voltage_unlocked(struct regulator *regulator, int min_uV, int max_uV, suspend_state_t state) @@ -2993,7 +3031,11 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, } } - ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); + if (state == PM_SUSPEND_ON) + ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); + else + ret = _regulator_do_set_suspend_voltage(rdev, min_uV, + max_uV, state); if (ret < 0) goto out2; @@ -3049,6 +3091,92 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) } EXPORT_SYMBOL_GPL(regulator_set_voltage); +static inline int regulator_suspend_toggle(struct regulator_dev *rdev, + suspend_state_t state, bool en) +{ + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return -EINVAL; + + if (!rstate->changeable) + return -EINVAL; + + rstate->enabled = en; + + return 0; +} + +static int regulator_suspend_enable(struct regulator_dev *rdev, + suspend_state_t state) +{ + return regulator_suspend_toggle(rdev, state, true); +} + +static int regulator_suspend_disable(struct regulator_dev *rdev, + suspend_state_t state) +{ + struct regulator *regulator; + struct regulator_voltage *voltage; + + /* + * if any consumer wants this regulator device keeping on in + * suspend states, don't set it as disabled. + */ + list_for_each_entry(regulator, &rdev->consumer_list, list) { + voltage = ®ulator->voltage[state]; + if (voltage->min_uV || voltage->max_uV) + return 0; + } + + return regulator_suspend_toggle(rdev, state, false); +} + +static int _regulator_set_suspend_voltage(struct regulator *regulator, + int min_uV, int max_uV, + suspend_state_t state) +{ + int ret; + struct regulator_dev *rdev = regulator->rdev; + + /* + * We assume users want to switch off the regulator device for + * suspend state when setting min_uV and max_uV all with zero. + */ + if (min_uV == 0 && max_uV == 0) { + regulator->voltage[state].min_uV = 0; + regulator->voltage[state].max_uV = 0; + return regulator_suspend_disable(rdev, state); + } + + ret = regulator_suspend_enable(rdev, state); + if (ret < 0) + return ret; + + return regulator_set_voltage_unlocked(regulator, min_uV, max_uV, state); +} + +int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, + int max_uV, suspend_state_t state) +{ + int ret = 0; + + /* PM_SUSPEND_ON is handled by regulator_set_voltage() */ + if (regulator_check_states(state) || state == PM_SUSPEND_ON) + return -EINVAL; + + regulator_lock_supply(regulator->rdev); + + ret = _regulator_set_suspend_voltage(regulator, min_uV, + max_uV, state); + + regulator_unlock_supply(regulator->rdev); + + return ret; +} +EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage); + /** * regulator_set_voltage_time - get raise/fall time * @regulator: regulator source @@ -3923,12 +4051,6 @@ static void regulator_dev_release(struct device *dev) kfree(rdev); } -static struct class regulator_class = { - .name = "regulator", - .dev_release = regulator_dev_release, - .dev_groups = regulator_dev_groups, -}; - static void rdev_init_debugfs(struct regulator_dev *rdev) { struct device *parent = rdev->dev.parent; @@ -4179,7 +4301,76 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); +static int _regulator_suspend_late(struct device *dev, void *data) +{ + struct regulator_dev *rdev = dev_to_rdev(dev); + suspend_state_t *state = data; + int ret; + mutex_lock(&rdev->mutex); + ret = suspend_set_state(rdev, *state); + mutex_unlock(&rdev->mutex); + + return ret; +} + +/** + * regulator_suspend_late - prepare regulators for system wide suspend + * @state: system suspend state + * + * Configure each regulator with it's suspend operating parameters for state. + */ +static int regulator_suspend_late(struct device *dev) +{ + suspend_state_t state = pm_suspend_target_state; + + return class_for_each_device(®ulator_class, NULL, &state, + _regulator_suspend_late); +} +static int _regulator_resume_early(struct device *dev, void *data) +{ + int ret = 0; + struct regulator_dev *rdev = dev_to_rdev(dev); + suspend_state_t *state = data; + struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, *state); + if (rstate == NULL) + return -EINVAL; + + mutex_lock(&rdev->mutex); + + if (rdev->desc->ops->resume_early && + (rstate->enabled == ENABLE_IN_SUSPEND || + rstate->enabled == DISABLE_IN_SUSPEND)) + ret = rdev->desc->ops->resume_early(rdev); + + mutex_unlock(&rdev->mutex); + + return ret; +} + +static int regulator_resume_early(struct device *dev) +{ + suspend_state_t state = pm_suspend_target_state; + + return class_for_each_device(®ulator_class, NULL, &state, + _regulator_resume_early); +} + +static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { + .suspend_late = regulator_suspend_late, + .resume_early = regulator_resume_early, +}; + +static struct class regulator_class = { + .name = "regulator", + .dev_release = regulator_dev_release, + .dev_groups = regulator_dev_groups, +#ifdef CONFIG_PM_SLEEP + .pm = ®ulator_pm_ops, +#endif +}; /** * regulator_has_full_constraints - the system has fully specified constraints * diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 41dad42..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 b4ddb56..f60ec1f 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -42,7 +42,12 @@ struct regulator; #define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_BYPASS 0x20 -/* operations in suspend mode */ +/* + * operations in suspend mode + * DO_NOTHING_IN_SUSPEND - the default value + * DISABLE_IN_SUSPEND - turn off regulator in suspend states + * ENABLE_IN_SUSPEND - keep regulator on in suspend states + */ #define DO_NOTHING_IN_SUSPEND (-1) #define DISABLE_IN_SUSPEND 0 #define ENABLE_IN_SUSPEND 1 @@ -61,17 +66,24 @@ enum regulator_active_discharge { * state. One of enabled or disabled must be set for the * configuration to be applied. * - * @uV: Operating voltage during suspend. + * @uV: Default operating voltage during suspend, it can be adjusted + * among + * @min_uV: Minimum suspend voltage may be set. + * @max_uV: Maximum suspend voltage may be set. * @mode: Operating mode during suspend. * @enabled: operations during suspend. * - DO_NOTHING_IN_SUSPEND * - DISABLE_IN_SUSPEND * - ENABLE_IN_SUSPEND + * @changeable: Is this state can be changed. */ struct regulator_state { int uV; /* suspend voltage */ + int min_uV; + int max_uV; unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ + bool changeable; }; /**