From 51b63409b75980753f52edb45da7d1b3e2b9405d Mon Sep 17 00:00:00 2001 From: Ajay Thomas Date: Thu, 30 Apr 2015 01:43:23 +0530 Subject: [PATCH 01/10] powercap / RAPL: Floor frequency setting in Atom SoC CPU Floor frequency is set in BIOS for newer Atom SoCs. This patch handles configuration of floor frequency for different variants of Atom SoCs appropriately and ensures configuration of floor frequency is not done from driver for these newer Atom SoCs. Since address of the register for configuring floor frequency might change for different Atom SoCs, this patch also prevents potential overwriting of wrong registers. Reviewed-by: Jacob Pan Signed-off-by: Ajay Thomas Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 50 ++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index fd243231620a..f33262843453 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -187,6 +187,7 @@ struct rapl_package { }; struct rapl_defaults { + u8 floor_freq_reg_addr; int (*check_unit)(struct rapl_package *rp, int cpu); void (*set_floor_freq)(struct rapl_domain *rd, bool mode); u64 (*compute_time_window)(struct rapl_package *rp, u64 val, @@ -196,7 +197,8 @@ struct rapl_defaults { static struct rapl_defaults *rapl_defaults; /* Sideband MBI registers */ -#define IOSF_CPU_POWER_BUDGET_CTL (0x2) +#define IOSF_CPU_POWER_BUDGET_CTL_BYT (0x2) +#define IOSF_CPU_POWER_BUDGET_CTL_TNG (0xdf) #define PACKAGE_PLN_INT_SAVED BIT(0) #define MAX_PRIM_NAME (32) @@ -358,7 +360,8 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode) get_online_cpus(); rapl_write_data_raw(rd, PL1_ENABLE, mode); - rapl_defaults->set_floor_freq(rd, mode); + if (rapl_defaults->set_floor_freq) + rapl_defaults->set_floor_freq(rd, mode); put_online_cpus(); return 0; @@ -979,16 +982,22 @@ static void set_floor_freq_atom(struct rapl_domain *rd, bool enable) static u32 power_ctrl_orig_val; u32 mdata; + if (!rapl_defaults->floor_freq_reg_addr) { + pr_err("Invalid floor frequency config register\n"); + return; + } + if (!power_ctrl_orig_val) iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_PMC_READ, - IOSF_CPU_POWER_BUDGET_CTL, &power_ctrl_orig_val); + rapl_defaults->floor_freq_reg_addr, + &power_ctrl_orig_val); mdata = power_ctrl_orig_val; if (enable) { mdata &= ~(0x7f << 8); mdata |= 1 << 8; } iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_PMC_WRITE, - IOSF_CPU_POWER_BUDGET_CTL, mdata); + rapl_defaults->floor_freq_reg_addr, mdata); } static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, @@ -1029,6 +1038,7 @@ static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value, } static const struct rapl_defaults rapl_defaults_core = { + .floor_freq_reg_addr = 0, .check_unit = rapl_check_unit_core, .set_floor_freq = set_floor_freq_default, .compute_time_window = rapl_compute_time_window_core, @@ -1041,12 +1051,34 @@ static const struct rapl_defaults rapl_defaults_hsw_server = { .dram_domain_energy_unit = 15300, }; -static const struct rapl_defaults rapl_defaults_atom = { +static const struct rapl_defaults rapl_defaults_byt = { + .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_BYT, .check_unit = rapl_check_unit_atom, .set_floor_freq = set_floor_freq_atom, .compute_time_window = rapl_compute_time_window_atom, }; +static const struct rapl_defaults rapl_defaults_tng = { + .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_TNG, + .check_unit = rapl_check_unit_atom, + .set_floor_freq = set_floor_freq_atom, + .compute_time_window = rapl_compute_time_window_atom, +}; + +static const struct rapl_defaults rapl_defaults_ann = { + .floor_freq_reg_addr = 0, + .check_unit = rapl_check_unit_atom, + .set_floor_freq = NULL, + .compute_time_window = rapl_compute_time_window_atom, +}; + +static const struct rapl_defaults rapl_defaults_cht = { + .floor_freq_reg_addr = 0, + .check_unit = rapl_check_unit_atom, + .set_floor_freq = NULL, + .compute_time_window = rapl_compute_time_window_atom, +}; + #define RAPL_CPU(_model, _ops) { \ .vendor = X86_VENDOR_INTEL, \ .family = 6, \ @@ -1057,7 +1089,7 @@ static const struct rapl_defaults rapl_defaults_atom = { static const struct x86_cpu_id rapl_ids[] __initconst = { RAPL_CPU(0x2a, rapl_defaults_core),/* Sandy Bridge */ RAPL_CPU(0x2d, rapl_defaults_core),/* Sandy Bridge EP */ - RAPL_CPU(0x37, rapl_defaults_atom),/* Valleyview */ + RAPL_CPU(0x37, rapl_defaults_byt),/* Valleyview */ RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ @@ -1065,10 +1097,10 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { RAPL_CPU(0x4f, rapl_defaults_hsw_server),/* Broadwell servers */ RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ RAPL_CPU(0x4E, rapl_defaults_core),/* Skylake */ - RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ - RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ + RAPL_CPU(0x4C, rapl_defaults_cht),/* Braswell/Cherryview */ + RAPL_CPU(0x4A, rapl_defaults_tng),/* Tangier */ RAPL_CPU(0x56, rapl_defaults_core),/* Future Xeon */ - RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */ + RAPL_CPU(0x5A, rapl_defaults_ann),/* Annidale */ {} }; MODULE_DEVICE_TABLE(x86cpu, rapl_ids); From 75f504004ab866c8f84749303b0f70953724e259 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Apr 2015 14:03:09 +0530 Subject: [PATCH 02/10] PM / clock_ops: Provide default runtime ops to users Most users of PM clocks do the extact same things in the runtime suspend/resume callbacks. Provide them USE_PM_CLK_RUNTIME_OPS so as to avoid/remove boilerplate code. Signed-off-by: Rajendra Nayak Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Acked-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 38 ++++++++++++++++++++++++++++++++++ include/linux/pm_clock.h | 10 +++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 7fdd0172605a..8abea669c82c 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef CONFIG_PM @@ -367,6 +368,43 @@ static int pm_clk_notify(struct notifier_block *nb, return 0; } +int pm_clk_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) { + dev_err(dev, "failed to suspend device\n"); + return ret; + } + + ret = pm_clk_suspend(dev); + if (ret) { + dev_err(dev, "failed to suspend clock\n"); + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +int pm_clk_runtime_resume(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_clk_resume(dev); + if (ret) { + dev_err(dev, "failed to resume clock\n"); + return ret; + } + + return pm_generic_runtime_resume(dev); +} + #else /* !CONFIG_PM */ /** diff --git a/include/linux/pm_clock.h b/include/linux/pm_clock.h index 0b0039634410..25266c600021 100644 --- a/include/linux/pm_clock.h +++ b/include/linux/pm_clock.h @@ -20,6 +20,16 @@ struct pm_clk_notifier_block { struct clk; +#ifdef CONFIG_PM +extern int pm_clk_runtime_suspend(struct device *dev); +extern int pm_clk_runtime_resume(struct device *dev); +#define USE_PM_CLK_RUNTIME_OPS \ + .runtime_suspend = pm_clk_runtime_suspend, \ + .runtime_resume = pm_clk_runtime_resume, +#else +#define USE_PM_CLK_RUNTIME_OPS +#endif + #ifdef CONFIG_PM_CLK static inline bool pm_clk_no_clocks(struct device *dev) { From 1f51b0c6461eb72595c2b69b79ca69a322ed1d0e Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Apr 2015 14:03:10 +0530 Subject: [PATCH 03/10] arm: keystone: remove boilerplate code and use USE_PM_CLK_RUNTIME_OPS USE_PM_CLK_RUNTIME_OPS is introduced so we don't repeat the same code to do runtime_suspend and runtime_resume across users of PM clocks. Use it to remove the boilerplate code. Signed-off-by: Rajendra Nayak Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Acked-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-keystone/pm_domain.c | 33 +----------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c index 41bebfd296dc..edea697e8253 100644 --- a/arch/arm/mach-keystone/pm_domain.c +++ b/arch/arm/mach-keystone/pm_domain.c @@ -19,40 +19,9 @@ #include #include -#ifdef CONFIG_PM -static int keystone_pm_runtime_suspend(struct device *dev) -{ - int ret; - - dev_dbg(dev, "%s\n", __func__); - - ret = pm_generic_runtime_suspend(dev); - if (ret) - return ret; - - ret = pm_clk_suspend(dev); - if (ret) { - pm_generic_runtime_resume(dev); - return ret; - } - - return 0; -} - -static int keystone_pm_runtime_resume(struct device *dev) -{ - dev_dbg(dev, "%s\n", __func__); - - pm_clk_resume(dev); - - return pm_generic_runtime_resume(dev); -} -#endif - static struct dev_pm_domain keystone_pm_domain = { .ops = { - SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend, - keystone_pm_runtime_resume, NULL) + USE_PM_CLK_RUNTIME_OPS USE_PLATFORM_PM_SLEEP_OPS }, }; From 2d3dc933e0575f1e5e07d222ffd95d8517562b38 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Apr 2015 14:03:11 +0530 Subject: [PATCH 04/10] arm: omap1: remove boilerplate code and use USE_PM_CLK_RUNTIME_OPS USE_PM_CLK_RUNTIME_OPS is introduced so we don't repeat the same code to do runtime_suspend and runtime_resume across users of PM clocks. Use it to remove the boilerplate code. Signed-off-by: Rajendra Nayak Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Acked-by: Geert Uytterhoeven Acked-by: Tony Lindgren Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-omap1/pm_bus.c | 37 ++---------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c index c40e209de65c..667c1637ff91 100644 --- a/arch/arm/mach-omap1/pm_bus.c +++ b/arch/arm/mach-omap1/pm_bus.c @@ -21,48 +21,15 @@ #include "soc.h" -#ifdef CONFIG_PM -static int omap1_pm_runtime_suspend(struct device *dev) -{ - int ret; - - dev_dbg(dev, "%s\n", __func__); - - ret = pm_generic_runtime_suspend(dev); - if (ret) - return ret; - - ret = pm_clk_suspend(dev); - if (ret) { - pm_generic_runtime_resume(dev); - return ret; - } - - return 0; -} - -static int omap1_pm_runtime_resume(struct device *dev) -{ - dev_dbg(dev, "%s\n", __func__); - - pm_clk_resume(dev); - return pm_generic_runtime_resume(dev); -} - static struct dev_pm_domain default_pm_domain = { .ops = { - .runtime_suspend = omap1_pm_runtime_suspend, - .runtime_resume = omap1_pm_runtime_resume, + USE_PM_CLK_RUNTIME_OPS USE_PLATFORM_PM_SLEEP_OPS }, }; -#define OMAP1_PM_DOMAIN (&default_pm_domain) -#else -#define OMAP1_PM_DOMAIN NULL -#endif /* CONFIG_PM */ static struct pm_clk_notifier_block platform_bus_notifier = { - .pm_domain = OMAP1_PM_DOMAIN, + .pm_domain = &default_pm_domain, .con_ids = { "ick", "fck", NULL, }, }; From ea6f83346ecbe65e061a8c66c5486d3f2c9964e9 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Apr 2015 14:03:12 +0530 Subject: [PATCH 05/10] arm: davinci: remove boilerplate code and use USE_PM_CLK_RUNTIME_OPS USE_PM_CLK_RUNTIME_OPS is introduced so we don't repeat the same code to do runtime_suspend and runtime_resume across users of PM clocks. Use it to remove the boilerplate code. Signed-off-by: Rajendra Nayak Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Acked-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-davinci/pm_domain.c | 32 +------------------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c index 641edc313938..78eac2c0c146 100644 --- a/arch/arm/mach-davinci/pm_domain.c +++ b/arch/arm/mach-davinci/pm_domain.c @@ -14,39 +14,9 @@ #include #include -#ifdef CONFIG_PM -static int davinci_pm_runtime_suspend(struct device *dev) -{ - int ret; - - dev_dbg(dev, "%s\n", __func__); - - ret = pm_generic_runtime_suspend(dev); - if (ret) - return ret; - - ret = pm_clk_suspend(dev); - if (ret) { - pm_generic_runtime_resume(dev); - return ret; - } - - return 0; -} - -static int davinci_pm_runtime_resume(struct device *dev) -{ - dev_dbg(dev, "%s\n", __func__); - - pm_clk_resume(dev); - return pm_generic_runtime_resume(dev); -} -#endif - static struct dev_pm_domain davinci_pm_domain = { .ops = { - SET_RUNTIME_PM_OPS(davinci_pm_runtime_suspend, - davinci_pm_runtime_resume, NULL) + USE_PM_CLK_RUNTIME_OPS USE_PLATFORM_PM_SLEEP_OPS }, }; From d2c4b43d8848afaf968ed1f3cea0c99296ff5ff3 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Apr 2015 14:03:13 +0530 Subject: [PATCH 06/10] drivers: sh: remove boilerplate code and use USE_PM_CLK_RUNTIME_OPS USE_PM_CLK_RUNTIME_OPS is introduced so we don't repeat the same code to do runtime_suspend and runtime_resume across users of PM clocks. Use it to remove the boilerplate code. Signed-off-by: Rajendra Nayak Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Acked-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- drivers/sh/pm_runtime.c | 47 ++--------------------------------------- 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c index fe8875f0d7be..d3d1891cda3c 100644 --- a/drivers/sh/pm_runtime.c +++ b/drivers/sh/pm_runtime.c @@ -20,58 +20,15 @@ #include #include -#ifdef CONFIG_PM -static int sh_pm_runtime_suspend(struct device *dev) -{ - int ret; - - ret = pm_generic_runtime_suspend(dev); - if (ret) { - dev_err(dev, "failed to suspend device\n"); - return ret; - } - - ret = pm_clk_suspend(dev); - if (ret) { - dev_err(dev, "failed to suspend clock\n"); - pm_generic_runtime_resume(dev); - return ret; - } - - return 0; -} - -static int sh_pm_runtime_resume(struct device *dev) -{ - int ret; - - ret = pm_clk_resume(dev); - if (ret) { - dev_err(dev, "failed to resume clock\n"); - return ret; - } - - return pm_generic_runtime_resume(dev); -} - static struct dev_pm_domain default_pm_domain = { .ops = { - .runtime_suspend = sh_pm_runtime_suspend, - .runtime_resume = sh_pm_runtime_resume, + USE_PM_CLK_RUNTIME_OPS USE_PLATFORM_PM_SLEEP_OPS }, }; -#define DEFAULT_PM_DOMAIN_PTR (&default_pm_domain) - -#else - -#define DEFAULT_PM_DOMAIN_PTR NULL - -#endif /* CONFIG_PM */ - static struct pm_clk_notifier_block platform_bus_notifier = { - .pm_domain = DEFAULT_PM_DOMAIN_PTR, + .pm_domain = &default_pm_domain, .con_ids = { NULL, }, }; From 3fc3a0be0dab352e065d1dad7d3f81953ed0d4bc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 May 2015 10:47:43 +0200 Subject: [PATCH 07/10] PM / clk: Fix clock error check in __pm_clk_add() In the final iteration of commit 245bd6f6af8a62a2 ("PM / clock_ops: Add pm_clk_add_clk()"), a refcount increment was added by Grygorii Strashko. However, the accompanying IS_ERR() check operates on the wrong clock pointer, which is always zero at this point, i.e. not an error. This may lead to a NULL pointer dereference later, when __clk_get() tries to dereference an error pointer. Check the passed clock pointer instead to fix this. Signed-off-by: Geert Uytterhoeven Fixes: 245bd6f6af8a62a2 ("PM / clock_ops: Add pm_clk_add_clk()") Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 8abea669c82c..442ce010559b 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -94,7 +94,7 @@ static int __pm_clk_add(struct device *dev, const char *con_id, return -ENOMEM; } } else { - if (IS_ERR(ce->clk) || !__clk_get(clk)) { + if (IS_ERR(clk) || !__clk_get(clk)) { kfree(ce); return -ENOENT; } From 6f066d4d2621affdbc510b5b0bd624af7ae74e1b Mon Sep 17 00:00:00 2001 From: Dasaratharaman Chandramouli Date: Tue, 19 May 2015 15:37:49 -0700 Subject: [PATCH 08/10] powercap / RAPL: Support Knights Landing This patch enables intel_rapl driver to run on the next-generation Intel(R) Xeon Phi Microarchitecture code named "Knights Landing" Signed-off-by: Dasaratharaman Chandramouli Acked-by: Jacob Pan Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index f33262843453..482b22ddc7b2 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -1101,6 +1101,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { RAPL_CPU(0x4A, rapl_defaults_tng),/* Tangier */ RAPL_CPU(0x56, rapl_defaults_core),/* Future Xeon */ RAPL_CPU(0x5A, rapl_defaults_ann),/* Annidale */ + RAPL_CPU(0x57, rapl_defaults_hsw_server),/* Knights Landing */ {} }; MODULE_DEVICE_TABLE(x86cpu, rapl_ids); From a4630c61274322eda7c4a4d17051f7c72a9e03b1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 May 2015 17:24:23 +0200 Subject: [PATCH 09/10] PM / Domains: Skip timings during syscore suspend/resume The PM Domain code uses ktime_get() to perform various latency measurements. However, if ktime_get() is called while timekeeping is suspended, the following warning is printed: WARNING: CPU: 0 PID: 1340 at kernel/time/timekeeping.c:576 ktime_get+0x3 This happens when resuming the PM Domain that contains the clock events source, which calls pm_genpd_syscore_poweron(). Chain of operations is: timekeeping_resume() { clockevents_resume() sh_cmt_clock_event_resume() pm_genpd_syscore_poweron() pm_genpd_sync_poweron() genpd_syscore_switch() genpd_power_on() ktime_get(), but timekeeping_suspended == 1 ... timekeeping_suspended = 0; } Fix this by adding a "timed" parameter to genpd_power_{on,off}() and pm_genpd_sync_power{off,on}(), to indicate whether latency measurements are allowed. This parameter is passed as false in genpd_syscore_switch() (i.e. during syscore suspend/resume), and true in all other cases. Signed-off-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 42 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2327613d4539..cdd547bd67df 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -181,7 +181,7 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) genpd->cpuidle_data->idle_state->exit_latency = usecs64; } -static int genpd_power_on(struct generic_pm_domain *genpd) +static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) { ktime_t time_start; s64 elapsed_ns; @@ -190,6 +190,9 @@ static int genpd_power_on(struct generic_pm_domain *genpd) if (!genpd->power_on) return 0; + if (!timed) + return genpd->power_on(genpd); + time_start = ktime_get(); ret = genpd->power_on(genpd); if (ret) @@ -208,7 +211,7 @@ static int genpd_power_on(struct generic_pm_domain *genpd) return ret; } -static int genpd_power_off(struct generic_pm_domain *genpd) +static int genpd_power_off(struct generic_pm_domain *genpd, bool timed) { ktime_t time_start; s64 elapsed_ns; @@ -217,6 +220,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd) if (!genpd->power_off) return 0; + if (!timed) + return genpd->power_off(genpd); + time_start = ktime_get(); ret = genpd->power_off(genpd); if (ret == -EBUSY) @@ -305,7 +311,7 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) } } - ret = genpd_power_on(genpd); + ret = genpd_power_on(genpd, true); if (ret) goto err; @@ -615,7 +621,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) * the pm_genpd_poweron() restore power for us (this shouldn't * happen very often). */ - ret = genpd_power_off(genpd); + ret = genpd_power_off(genpd, true); if (ret == -EBUSY) { genpd_set_active(genpd); goto out; @@ -827,6 +833,7 @@ static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd, /** * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its masters. * @genpd: PM domain to power off, if possible. + * @timed: True if latency measurements are allowed. * * Check if the given PM domain can be powered off (during system suspend or * hibernation) and do that if so. Also, in that case propagate to its masters. @@ -836,7 +843,8 @@ static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd, * executed sequentially, so it is guaranteed that it will never run twice in * parallel). */ -static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd) +static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd, + bool timed) { struct gpd_link *link; @@ -847,26 +855,28 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd) || atomic_read(&genpd->sd_count) > 0) return; - genpd_power_off(genpd); + genpd_power_off(genpd, timed); genpd->status = GPD_STATE_POWER_OFF; list_for_each_entry(link, &genpd->slave_links, slave_node) { genpd_sd_counter_dec(link->master); - pm_genpd_sync_poweroff(link->master); + pm_genpd_sync_poweroff(link->master, timed); } } /** * pm_genpd_sync_poweron - Synchronously power on a PM domain and its masters. * @genpd: PM domain to power on. + * @timed: True if latency measurements are allowed. * * This function is only called in "noirq" and "syscore" stages of system power * transitions, so it need not acquire locks (all of the "noirq" callbacks are * executed sequentially, so it is guaranteed that it will never run twice in * parallel). */ -static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd) +static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd, + bool timed) { struct gpd_link *link; @@ -874,11 +884,11 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd) return; list_for_each_entry(link, &genpd->slave_links, slave_node) { - pm_genpd_sync_poweron(link->master); + pm_genpd_sync_poweron(link->master, timed); genpd_sd_counter_inc(link->master); } - genpd_power_on(genpd); + genpd_power_on(genpd, timed); genpd->status = GPD_STATE_ACTIVE; } @@ -1056,7 +1066,7 @@ static int pm_genpd_suspend_noirq(struct device *dev) * the same PM domain, so it is not necessary to use locking here. */ genpd->suspended_count++; - pm_genpd_sync_poweroff(genpd); + pm_genpd_sync_poweroff(genpd, true); return 0; } @@ -1086,7 +1096,7 @@ static int pm_genpd_resume_noirq(struct device *dev) * guaranteed that this function will never run twice in parallel for * the same PM domain, so it is not necessary to use locking here. */ - pm_genpd_sync_poweron(genpd); + pm_genpd_sync_poweron(genpd, true); genpd->suspended_count--; return genpd_start_dev(genpd, dev); @@ -1300,7 +1310,7 @@ static int pm_genpd_restore_noirq(struct device *dev) * If the domain was off before the hibernation, make * sure it will be off going forward. */ - genpd_power_off(genpd); + genpd_power_off(genpd, true); return 0; } @@ -1309,7 +1319,7 @@ static int pm_genpd_restore_noirq(struct device *dev) if (genpd->suspend_power_off) return 0; - pm_genpd_sync_poweron(genpd); + pm_genpd_sync_poweron(genpd, true); return genpd_start_dev(genpd, dev); } @@ -1367,9 +1377,9 @@ static void genpd_syscore_switch(struct device *dev, bool suspend) if (suspend) { genpd->suspended_count++; - pm_genpd_sync_poweroff(genpd); + pm_genpd_sync_poweroff(genpd, false); } else { - pm_genpd_sync_poweron(genpd); + pm_genpd_sync_poweron(genpd, false); genpd->suspended_count--; } } From f17f4adfe48b64b23247b792c0e5ab998b7ab34e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 May 2015 18:35:31 +0200 Subject: [PATCH 10/10] PM / clk: Print acquired clock name in addition to con_id Currently the con_id of the acquired clock is printed for debugging purposes. But in several cases, the con_id is NULL, which doesn't provide much debugging information when printed. These cases are: - When explicitly passing a NULL con_id (which means the first clock tied to the device, if available), - When not using pm_clk_add(), but pm_clk_add_clk() (which takes a "struct clk *" directly). Hence print the actual clock name in addition to (and not instead of; thanks Grygorii Strashko!) the con_id. Note that the clock name is not available with legacy clock frameworks, and the hex pointer address will be printed instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Grygorii Strashko Reviewed-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 442ce010559b..acef9f9f759a 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -68,7 +68,8 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) } else { clk_prepare(ce->clk); ce->status = PCE_STATUS_ACQUIRED; - dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); + dev_dbg(dev, "Clock %pC con_id %s managed by runtime PM.\n", + ce->clk, ce->con_id); } }