From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935104AbeAITAq (ORCPT + 1 other); Tue, 9 Jan 2018 14:00:46 -0500 Received: from mga11.intel.com ([192.55.52.93]:42945 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932310AbeAITAp (ORCPT ); Tue, 9 Jan 2018 14:00:45 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,336,1511856000"; d="scan'208";a="18761402" Message-ID: <1515524444.69545.23.camel@linux.intel.com> Subject: Re: [PATCH] powercap: add suspend and resume mechanism for SOC power limit From: Srinivas Pandruvada To: "Rafael J. Wysocki" , xinx.sun@intel.com, Jacob Pan Cc: zhen.han@intel.com, chaox.m.wang@intel.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Date: Tue, 09 Jan 2018 11:00:44 -0800 In-Reply-To: <45933800.B3qMYBKE5m@aspire.rjw.lan> References: <1515486310-20330-1-git-send-email-xinx.sun@intel.com> <45933800.B3qMYBKE5m@aspire.rjw.lan> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.24.6 (3.24.6-1.fc26) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Tue, 2018-01-09 at 12:39 +0100, Rafael J. Wysocki wrote: > On Tuesday, January 9, 2018 9:25:10 AM CET xinx.sun@intel.com wrote: > > From: Zhen Han > > > > PL1 and PL2 could be throlled or de-throttled by > > Thermal management to control SOC temperature. > > However, currently, their value will be reset to default value > > after once system suspend and resume. > > Add pm_notifier to save PL1, PL2 before system suspect and restore > > PL1, PL2 after system resume. > > > > Signed-off-by: Sun Xinx > > Jacob, Srinivas, please have a look at this. I have already looked at this. Looks good to me. Thanks, Srinivas > > > --- > > drivers/powercap/intel_rapl.c | 97 > > +++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 97 insertions(+) > > > > diff --git a/drivers/powercap/intel_rapl.c > > b/drivers/powercap/intel_rapl.c > > index d1694f1..0188cff 100644 > > --- a/drivers/powercap/intel_rapl.c > > +++ b/drivers/powercap/intel_rapl.c > > @@ -29,6 +29,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #include > > @@ -155,6 +156,7 @@ struct rapl_power_limit { > > int prim_id; /* primitive ID used to enable */ > > struct rapl_domain *domain; > > const char *name; > > + u64 last_power_limit; > > }; > > > > static const char pl1_name[] = "long_term"; > > @@ -1533,6 +1535,92 @@ static int rapl_cpu_down_prep(unsigned int > > cpu) > > > > static enum cpuhp_state pcap_rapl_online; > > > > +static void power_limit_state_save(void) > > +{ > > + struct rapl_package *rp; > > + struct rapl_domain *rd; > > + int nr_pl, ret, i; > > + > > + get_online_cpus(); > > + list_for_each_entry(rp, &rapl_packages, plist) { > > + if (!rp->power_zone) > > + continue; > > + rd = power_zone_to_rapl_domain(rp->power_zone); > > + nr_pl = find_nr_power_limit(rd); > > + for (i = 0; i < nr_pl; i++) { > > + switch (rd->rpl[i].prim_id) { > > + case PL1_ENABLE: > > + ret = rapl_read_data_raw(rd, > > + POWER_LIMIT1, > > + true, > > + &rd- > > >rpl[i].last_power_limit); > > + if (ret) > > + rd- > > >rpl[i].last_power_limit = 0; > > + break; > > + case PL2_ENABLE: > > + ret = rapl_read_data_raw(rd, > > + POWER_LIMIT2, > > + true, > > + &rd- > > >rpl[i].last_power_limit); > > + if (ret) > > + rd- > > >rpl[i].last_power_limit = 0; > > + break; > > + } > > + } > > + } > > + put_online_cpus(); > > +} > > + > > +static void power_limit_state_restore(void) > > +{ > > + struct rapl_package *rp; > > + struct rapl_domain *rd; > > + int nr_pl, i; > > + > > + get_online_cpus(); > > + list_for_each_entry(rp, &rapl_packages, plist) { > > + if (!rp->power_zone) > > + continue; > > + rd = power_zone_to_rapl_domain(rp->power_zone); > > + nr_pl = find_nr_power_limit(rd); > > + for (i = 0; i < nr_pl; i++) { > > + switch (rd->rpl[i].prim_id) { > > + case PL1_ENABLE: > > + if (rd->rpl[i].last_power_limit) > > + rapl_write_data_raw(rd, > > + POWER_LIMIT1, > > + rd- > > >rpl[i].last_power_limit); > > + break; > > + case PL2_ENABLE: > > + if (rd->rpl[i].last_power_limit) > > + rapl_write_data_raw(rd, > > + POWER_LIMIT2, > > + rd- > > >rpl[i].last_power_limit); > > + break; > > + } > > + } > > + } > > + put_online_cpus(); > > +} > > + > > +static int rapl_pm_callback(struct notifier_block *nb, > > + unsigned long mode, void *_unused) > > +{ > > + switch (mode) { > > + case PM_SUSPEND_PREPARE: > > + power_limit_state_save(); > > + break; > > + case PM_POST_SUSPEND: > > + power_limit_state_restore(); > > + break; > > + } > > + return NOTIFY_OK; > > +} > > + > > +static struct notifier_block rapl_pm_notifier = { > > + .notifier_call = rapl_pm_callback, > > +}; > > + > > static int __init rapl_init(void) > > { > > const struct x86_cpu_id *id; > > @@ -1560,8 +1648,16 @@ static int __init rapl_init(void) > > > > /* Don't bail out if PSys is not supported */ > > rapl_register_psys(); > > + > > + ret = register_pm_notifier(&rapl_pm_notifier); > > + if (ret) > > + goto err_unreg_all; > > + > > return 0; > > > > +err_unreg_all: > > + cpuhp_remove_state(pcap_rapl_online); > > + > > err_unreg: > > rapl_unregister_powercap(); > > return ret; > > @@ -1569,6 +1665,7 @@ static int __init rapl_init(void) > > > > static void __exit rapl_exit(void) > > { > > + unregister_pm_notifier(&rapl_pm_notifier); > > cpuhp_remove_state(pcap_rapl_online); > > rapl_unregister_powercap(); > > } > > > >