Skip to content

Commit f6235eb

Browse files
committed
Merge tag 'pm-5.9-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki: "These are mostly ARM cpufreq driver updates plus a cpufreq core cleanup, an ARM-wide change to make schedutil the default scaling governor, an intel_pstate driver fix and some runtime PM changes regarding kerneldoc comments. Specifics: - Add adaptive voltage scaling (AVS) support to the brcmstb cpufreq driver and clean it up (Florian Fainelli, Markus Mayer). - Add a new Tegra cpufreq driver and clean up the existing one (Jon Hunter, Sumit Gupta). - Add bandwidth level support to the Qcom cpufreq driver along with OPP changes (Sibi Sankar). - Clean up the sti, cpufreq-dt, ap806, CPPC cpufreq drivers (Viresh Kumar, Lee Jones, Ivan Kokshaysky, Sven Auhagen, Xin Hao). - Make schedutil the default governor for ARM (Valentin Schneider). - Fix dependency issues for the imx cpufreq driver (Walter Lozano). - Clean up cached_resolved_idx handlihng in the cpufreq core (Viresh Kumar). - Fix the intel_pstate driver to use the correct maximum frequency value when MSR_TURBO_RATIO_LIMIT is 0 (Srinivas Pandruvada). - Provide kenrneldoc comments for multiple runtime PM helpers and improve the pm_runtime_get_if_active() kerneldoc (Rafael Wysocki)" * tag 'pm-5.9-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (22 commits) cpufreq: intel_pstate: Fix cpuinfo_max_freq when MSR_TURBO_RATIO_LIMIT is 0 PM: runtime: Improve kerneldoc of pm_runtime_get_if_active() PM: runtime: Add kerneldoc comments to multiple helpers cpufreq: make schedutil the default for arm and arm64 cpufreq: cached_resolved_idx can not be negative cpufreq: Add Tegra194 cpufreq driver dt-bindings: arm: Add NVIDIA Tegra194 CPU Complex binding cpufreq: imx: Select NVMEM_IMX_OCOTP cpufreq: sti-cpufreq: Fix some formatting and misspelling issues cpufreq: tegra186: Simplify probe return path cpufreq: CPPC: Reuse caps variable in few routines cpufreq: ap806: fix cpufreq driver needs ap cpu clk cpufreq: cppc: Reorder code and remove apply_hisi_workaround variable cpufreq: dt: fix oops on armada37xx cpufreq: brcmstb-avs-cpufreq: send S2_ENTER / S2_EXIT commands to AVS cpufreq: brcmstb-avs-cpufreq: Support polling AVS firmware cpufreq: brcmstb-avs-cpufreq: more flexible interface for __issue_avs_command() cpufreq: qcom: Disable fast switch when scaling DDR/L3 cpufreq: qcom: Update the bandwidth levels on frequency change OPP: Add and export helper to set bandwidth ...
2 parents 2f12d44 + 0873ad9 commit f6235eb

19 files changed

+963
-114
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: "http://devicetree.org/schemas/arm/nvidia,tegra194-ccplex.yaml#"
5+
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
6+
7+
title: NVIDIA Tegra194 CPU Complex device tree bindings
8+
9+
maintainers:
10+
- Thierry Reding <[email protected]>
11+
- Jonathan Hunter <[email protected]>
12+
- Sumit Gupta <[email protected]>
13+
14+
description: |+
15+
Tegra194 SOC has homogeneous architecture where each cluster has two
16+
symmetric cores. Compatible string in "cpus" node represents the CPU
17+
Complex having all clusters.
18+
19+
properties:
20+
$nodename:
21+
const: cpus
22+
23+
compatible:
24+
enum:
25+
- nvidia,tegra194-ccplex
26+
27+
nvidia,bpmp:
28+
$ref: '/schemas/types.yaml#/definitions/phandle'
29+
description: |
30+
Specifies the bpmp node that needs to be queried to get
31+
operating point data for all CPUs.
32+
33+
examples:
34+
- |
35+
cpus {
36+
compatible = "nvidia,tegra194-ccplex";
37+
nvidia,bpmp = <&bpmp>;
38+
#address-cells = <1>;
39+
#size-cells = <0>;
40+
41+
cpu0_0: cpu@0 {
42+
compatible = "nvidia,tegra194-carmel";
43+
device_type = "cpu";
44+
reg = <0x0>;
45+
enable-method = "psci";
46+
};
47+
48+
cpu0_1: cpu@1 {
49+
compatible = "nvidia,tegra194-carmel";
50+
device_type = "cpu";
51+
reg = <0x001>;
52+
enable-method = "psci";
53+
};
54+
55+
cpu1_0: cpu@100 {
56+
compatible = "nvidia,tegra194-carmel";
57+
device_type = "cpu";
58+
reg = <0x100>;
59+
enable-method = "psci";
60+
};
61+
62+
cpu1_1: cpu@101 {
63+
compatible = "nvidia,tegra194-carmel";
64+
device_type = "cpu";
65+
reg = <0x101>;
66+
enable-method = "psci";
67+
};
68+
};
69+
...

drivers/base/power/runtime.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,24 +1085,26 @@ int __pm_runtime_resume(struct device *dev, int rpmflags)
10851085
EXPORT_SYMBOL_GPL(__pm_runtime_resume);
10861086

10871087
/**
1088-
* pm_runtime_get_if_active - Conditionally bump up the device's usage counter.
1088+
* pm_runtime_get_if_active - Conditionally bump up device usage counter.
10891089
* @dev: Device to handle.
1090+
* @ign_usage_count: Whether or not to look at the current usage counter value.
10901091
*
1091-
* Return -EINVAL if runtime PM is disabled for the device.
1092+
* Return -EINVAL if runtime PM is disabled for @dev.
10921093
*
1093-
* Otherwise, if the device's runtime PM status is RPM_ACTIVE and either
1094-
* ign_usage_count is true or the device's usage_count is non-zero, increment
1095-
* the counter and return 1. Otherwise return 0 without changing the counter.
1094+
* Otherwise, if the runtime PM status of @dev is %RPM_ACTIVE and either
1095+
* @ign_usage_count is %true or the runtime PM usage counter of @dev is not
1096+
* zero, increment the usage counter of @dev and return 1. Otherwise, return 0
1097+
* without changing the usage counter.
10961098
*
1097-
* If ign_usage_count is true, the function can be used to prevent suspending
1098-
* the device when its runtime PM status is RPM_ACTIVE.
1099+
* If @ign_usage_count is %true, this function can be used to prevent suspending
1100+
* the device when its runtime PM status is %RPM_ACTIVE.
10991101
*
1100-
* If ign_usage_count is false, the function can be used to prevent suspending
1101-
* the device when both its runtime PM status is RPM_ACTIVE and its usage_count
1102-
* is non-zero.
1102+
* If @ign_usage_count is %false, this function can be used to prevent
1103+
* suspending the device when both its runtime PM status is %RPM_ACTIVE and its
1104+
* runtime PM usage counter is not zero.
11031105
*
1104-
* The caller is resposible for putting the device's usage count when ther
1105-
* return value is greater than zero.
1106+
* The caller is resposible for decrementing the runtime PM usage counter of
1107+
* @dev after this function has returned a positive value for it.
11061108
*/
11071109
int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count)
11081110
{

drivers/cpufreq/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ config CPU_FREQ_STAT
3737
choice
3838
prompt "Default CPUFreq governor"
3939
default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ
40-
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if BIG_LITTLE
40+
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if ARM64 || ARM
4141
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if X86_INTEL_PSTATE && SMP
4242
default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
4343
help

drivers/cpufreq/Kconfig.arm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ config ARM_ARMADA_37XX_CPUFREQ
4141
config ARM_ARMADA_8K_CPUFREQ
4242
tristate "Armada 8K CPUFreq driver"
4343
depends on ARCH_MVEBU && CPUFREQ_DT
44+
select ARMADA_AP_CPU_CLK
4445
help
4546
This enables the CPUFreq driver support for Marvell
4647
Armada8k SOCs.
@@ -93,6 +94,7 @@ config ARM_IMX6Q_CPUFREQ
9394
tristate "Freescale i.MX6 cpufreq support"
9495
depends on ARCH_MXC
9596
depends on REGULATOR_ANATOP
97+
select NVMEM_IMX_OCOTP
9698
select PM_OPP
9799
help
98100
This adds cpufreq driver support for Freescale i.MX6 series SoCs.
@@ -314,6 +316,13 @@ config ARM_TEGRA186_CPUFREQ
314316
help
315317
This adds the CPUFreq driver support for Tegra186 SOCs.
316318

319+
config ARM_TEGRA194_CPUFREQ
320+
tristate "Tegra194 CPUFreq support"
321+
depends on ARCH_TEGRA_194_SOC && TEGRA_BPMP
322+
default y
323+
help
324+
This adds CPU frequency driver support for Tegra194 SOCs.
325+
317326
config ARM_TI_CPUFREQ
318327
bool "Texas Instruments CPUFreq support"
319328
depends on ARCH_OMAP2PLUS

drivers/cpufreq/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ obj-$(CONFIG_ARM_TANGO_CPUFREQ) += tango-cpufreq.o
8383
obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o
8484
obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
8585
obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o
86+
obj-$(CONFIG_ARM_TEGRA194_CPUFREQ) += tegra194-cpufreq.o
8687
obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o
8788
obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
8889

drivers/cpufreq/armada-37xx-cpufreq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
456456
/* Now that everything is setup, enable the DVFS at hardware level */
457457
armada37xx_cpufreq_enable_dvfs(nb_pm_base);
458458

459+
memset(&pdata, 0, sizeof(pdata));
459460
pdata.suspend = armada37xx_cpufreq_suspend;
460461
pdata.resume = armada37xx_cpufreq_resume;
461462

drivers/cpufreq/brcmstb-avs-cpufreq.c

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
*/
4343

4444
#include <linux/cpufreq.h>
45+
#include <linux/delay.h>
4546
#include <linux/interrupt.h>
4647
#include <linux/io.h>
4748
#include <linux/module.h>
@@ -178,6 +179,7 @@ struct private_data {
178179
struct completion done;
179180
struct semaphore sem;
180181
struct pmap pmap;
182+
int host_irq;
181183
};
182184

183185
static void __iomem *__map_region(const char *name)
@@ -195,11 +197,36 @@ static void __iomem *__map_region(const char *name)
195197
return ptr;
196198
}
197199

198-
static int __issue_avs_command(struct private_data *priv, int cmd, bool is_send,
200+
static unsigned long wait_for_avs_command(struct private_data *priv,
201+
unsigned long timeout)
202+
{
203+
unsigned long time_left = 0;
204+
u32 val;
205+
206+
/* Event driven, wait for the command interrupt */
207+
if (priv->host_irq >= 0)
208+
return wait_for_completion_timeout(&priv->done,
209+
msecs_to_jiffies(timeout));
210+
211+
/* Polling for command completion */
212+
do {
213+
time_left = timeout;
214+
val = readl(priv->base + AVS_MBOX_STATUS);
215+
if (val)
216+
break;
217+
218+
usleep_range(1000, 2000);
219+
} while (--timeout);
220+
221+
return time_left;
222+
}
223+
224+
static int __issue_avs_command(struct private_data *priv, unsigned int cmd,
225+
unsigned int num_in, unsigned int num_out,
199226
u32 args[])
200227
{
201-
unsigned long time_left = msecs_to_jiffies(AVS_TIMEOUT);
202228
void __iomem *base = priv->base;
229+
unsigned long time_left;
203230
unsigned int i;
204231
int ret;
205232
u32 val;
@@ -225,11 +252,9 @@ static int __issue_avs_command(struct private_data *priv, int cmd, bool is_send,
225252
/* Clear status before we begin. */
226253
writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
227254

228-
/* We need to send arguments for this command. */
229-
if (args && is_send) {
230-
for (i = 0; i < AVS_MAX_CMD_ARGS; i++)
231-
writel(args[i], base + AVS_MBOX_PARAM(i));
232-
}
255+
/* Provide input parameters */
256+
for (i = 0; i < num_in; i++)
257+
writel(args[i], base + AVS_MBOX_PARAM(i));
233258

234259
/* Protect from spurious interrupts. */
235260
reinit_completion(&priv->done);
@@ -239,7 +264,7 @@ static int __issue_avs_command(struct private_data *priv, int cmd, bool is_send,
239264
writel(AVS_CPU_L2_INT_MASK, priv->avs_intr_base + AVS_CPU_L2_SET0);
240265

241266
/* Wait for AVS co-processor to finish processing the command. */
242-
time_left = wait_for_completion_timeout(&priv->done, time_left);
267+
time_left = wait_for_avs_command(priv, AVS_TIMEOUT);
243268

244269
/*
245270
* If the AVS status is not in the expected range, it means AVS didn't
@@ -256,11 +281,9 @@ static int __issue_avs_command(struct private_data *priv, int cmd, bool is_send,
256281
goto out;
257282
}
258283

259-
/* This command returned arguments, so we read them back. */
260-
if (args && !is_send) {
261-
for (i = 0; i < AVS_MAX_CMD_ARGS; i++)
262-
args[i] = readl(base + AVS_MBOX_PARAM(i));
263-
}
284+
/* Process returned values */
285+
for (i = 0; i < num_out; i++)
286+
args[i] = readl(base + AVS_MBOX_PARAM(i));
264287

265288
/* Clear status to tell AVS co-processor we are done. */
266289
writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
@@ -338,7 +361,7 @@ static int brcm_avs_get_pmap(struct private_data *priv, struct pmap *pmap)
338361
u32 args[AVS_MAX_CMD_ARGS];
339362
int ret;
340363

341-
ret = __issue_avs_command(priv, AVS_CMD_GET_PMAP, false, args);
364+
ret = __issue_avs_command(priv, AVS_CMD_GET_PMAP, 0, 4, args);
342365
if (ret || !pmap)
343366
return ret;
344367

@@ -359,15 +382,15 @@ static int brcm_avs_set_pmap(struct private_data *priv, struct pmap *pmap)
359382
args[2] = pmap->p2;
360383
args[3] = pmap->state;
361384

362-
return __issue_avs_command(priv, AVS_CMD_SET_PMAP, true, args);
385+
return __issue_avs_command(priv, AVS_CMD_SET_PMAP, 4, 0, args);
363386
}
364387

365388
static int brcm_avs_get_pstate(struct private_data *priv, unsigned int *pstate)
366389
{
367390
u32 args[AVS_MAX_CMD_ARGS];
368391
int ret;
369392

370-
ret = __issue_avs_command(priv, AVS_CMD_GET_PSTATE, false, args);
393+
ret = __issue_avs_command(priv, AVS_CMD_GET_PSTATE, 0, 1, args);
371394
if (ret)
372395
return ret;
373396
*pstate = args[0];
@@ -381,7 +404,8 @@ static int brcm_avs_set_pstate(struct private_data *priv, unsigned int pstate)
381404

382405
args[0] = pstate;
383406

384-
return __issue_avs_command(priv, AVS_CMD_SET_PSTATE, true, args);
407+
return __issue_avs_command(priv, AVS_CMD_SET_PSTATE, 1, 0, args);
408+
385409
}
386410

387411
static u32 brcm_avs_get_voltage(void __iomem *base)
@@ -482,14 +506,24 @@ static int brcm_avs_suspend(struct cpufreq_policy *policy)
482506
* AVS co-processor, not necessarily the P-state we are running at now.
483507
* So, we get the current P-state explicitly.
484508
*/
485-
return brcm_avs_get_pstate(priv, &priv->pmap.state);
509+
ret = brcm_avs_get_pstate(priv, &priv->pmap.state);
510+
if (ret)
511+
return ret;
512+
513+
/* This is best effort. Nothing to do if it fails. */
514+
(void)__issue_avs_command(priv, AVS_CMD_S2_ENTER, 0, 0, NULL);
515+
516+
return 0;
486517
}
487518

488519
static int brcm_avs_resume(struct cpufreq_policy *policy)
489520
{
490521
struct private_data *priv = policy->driver_data;
491522
int ret;
492523

524+
/* This is best effort. Nothing to do if it fails. */
525+
(void)__issue_avs_command(priv, AVS_CMD_S2_EXIT, 0, 0, NULL);
526+
493527
ret = brcm_avs_set_pmap(priv, &priv->pmap);
494528
if (ret == -EEXIST) {
495529
struct platform_device *pdev = cpufreq_get_driver_data();
@@ -511,7 +545,7 @@ static int brcm_avs_prepare_init(struct platform_device *pdev)
511545
{
512546
struct private_data *priv;
513547
struct device *dev;
514-
int host_irq, ret;
548+
int ret;
515549

516550
dev = &pdev->dev;
517551
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -538,19 +572,14 @@ static int brcm_avs_prepare_init(struct platform_device *pdev)
538572
goto unmap_base;
539573
}
540574

541-
host_irq = platform_get_irq_byname(pdev, BRCM_AVS_HOST_INTR);
542-
if (host_irq < 0) {
543-
dev_err(dev, "Couldn't find interrupt %s -- %d\n",
544-
BRCM_AVS_HOST_INTR, host_irq);
545-
ret = host_irq;
546-
goto unmap_intr_base;
547-
}
575+
priv->host_irq = platform_get_irq_byname(pdev, BRCM_AVS_HOST_INTR);
548576

549-
ret = devm_request_irq(dev, host_irq, irq_handler, IRQF_TRIGGER_RISING,
577+
ret = devm_request_irq(dev, priv->host_irq, irq_handler,
578+
IRQF_TRIGGER_RISING,
550579
BRCM_AVS_HOST_INTR, priv);
551-
if (ret) {
580+
if (ret && priv->host_irq >= 0) {
552581
dev_err(dev, "IRQ request failed: %s (%d) -- %d\n",
553-
BRCM_AVS_HOST_INTR, host_irq, ret);
582+
BRCM_AVS_HOST_INTR, priv->host_irq, ret);
554583
goto unmap_intr_base;
555584
}
556585

@@ -593,7 +622,7 @@ static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy)
593622
/* All cores share the same clock and thus the same policy. */
594623
cpumask_setall(policy->cpus);
595624

596-
ret = __issue_avs_command(priv, AVS_CMD_ENABLE, false, NULL);
625+
ret = __issue_avs_command(priv, AVS_CMD_ENABLE, 0, 0, NULL);
597626
if (!ret) {
598627
unsigned int pstate;
599628

0 commit comments

Comments
 (0)