Skip to content

Commit c95d9c1

Browse files
committed
Merge branches 'pm-core', 'powercap', 'pm-opp', 'pm-avs' and 'pm-misc'
* pm-core: PM-runtime: add tracepoints for usage_count changes * powercap: powercap/intel_rapl: add support for JasperLake x86/cpu: Add Jasper Lake to Intel family powercap/intel_rapl: add support for TigerLake Mobile * pm-opp: opp: Replace list_kref with a local counter opp: Free static OPPs on errors while adding them * pm-avs: power: avs: qcom-cpr: remove duplicated include from qcom-cpr.c power: avs: fix uninitialized error return on failed cpr_read_fuse_uV() call power: avs: qcom-cpr: make cpr_get_opp_hz_for_req() static power: avs: qcom-cpr: remove set but unused variable power: avs: qcom-cpr: make sure that regmap is available power: avs: qcom-cpr: fix unsigned expression compared with zero power: avs: qcom-cpr: fix invalid printk specifier in debug print power: avs: Add support for CPR (Core Power Reduction) dt-bindings: power: avs: Add support for CPR (Core Power Reduction) * pm-misc: mailmap: Add entry for <[email protected]>
6 parents 245224d + d229290 + ead067b + c267930 + f9900c1 + 0b7c99d commit c95d9c1

File tree

13 files changed

+2008
-48
lines changed

13 files changed

+2008
-48
lines changed

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ Praveen BP <[email protected]>
217217
218218
219219
220+
220221
Rajesh Shah <[email protected]>
221222
Ralf Baechle <[email protected]>
222223
Ralf Wildenhues <[email protected]>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
QCOM CPR (Core Power Reduction)
2+
3+
CPR (Core Power Reduction) is a technology to reduce core power on a CPU
4+
or other device. Each OPP of a device corresponds to a "corner" that has
5+
a range of valid voltages for a particular frequency. While the device is
6+
running at a particular frequency, CPR monitors dynamic factors such as
7+
temperature, etc. and suggests adjustments to the voltage to save power
8+
and meet silicon characteristic requirements.
9+
10+
- compatible:
11+
Usage: required
12+
Value type: <string>
13+
Definition: should be "qcom,qcs404-cpr", "qcom,cpr" for qcs404
14+
15+
- reg:
16+
Usage: required
17+
Value type: <prop-encoded-array>
18+
Definition: base address and size of the rbcpr register region
19+
20+
- interrupts:
21+
Usage: required
22+
Value type: <prop-encoded-array>
23+
Definition: should specify the CPR interrupt
24+
25+
- clocks:
26+
Usage: required
27+
Value type: <prop-encoded-array>
28+
Definition: phandle to the reference clock
29+
30+
- clock-names:
31+
Usage: required
32+
Value type: <stringlist>
33+
Definition: must be "ref"
34+
35+
- vdd-apc-supply:
36+
Usage: required
37+
Value type: <phandle>
38+
Definition: phandle to the vdd-apc-supply regulator
39+
40+
- #power-domain-cells:
41+
Usage: required
42+
Value type: <u32>
43+
Definition: should be 0
44+
45+
- operating-points-v2:
46+
Usage: required
47+
Value type: <phandle>
48+
Definition: A phandle to the OPP table containing the
49+
performance states supported by the CPR
50+
power domain
51+
52+
- acc-syscon:
53+
Usage: optional
54+
Value type: <phandle>
55+
Definition: phandle to syscon for writing ACC settings
56+
57+
- nvmem-cells:
58+
Usage: required
59+
Value type: <phandle>
60+
Definition: phandle to nvmem cells containing the data
61+
that makes up a fuse corner, for each fuse corner.
62+
As well as the CPR fuse revision.
63+
64+
- nvmem-cell-names:
65+
Usage: required
66+
Value type: <stringlist>
67+
Definition: should be "cpr_quotient_offset1", "cpr_quotient_offset2",
68+
"cpr_quotient_offset3", "cpr_init_voltage1",
69+
"cpr_init_voltage2", "cpr_init_voltage3", "cpr_quotient1",
70+
"cpr_quotient2", "cpr_quotient3", "cpr_ring_osc1",
71+
"cpr_ring_osc2", "cpr_ring_osc3", "cpr_fuse_revision"
72+
for qcs404.
73+
74+
Example:
75+
76+
cpr_opp_table: cpr-opp-table {
77+
compatible = "operating-points-v2-qcom-level";
78+
79+
cpr_opp1: opp1 {
80+
opp-level = <1>;
81+
qcom,opp-fuse-level = <1>;
82+
};
83+
cpr_opp2: opp2 {
84+
opp-level = <2>;
85+
qcom,opp-fuse-level = <2>;
86+
};
87+
cpr_opp3: opp3 {
88+
opp-level = <3>;
89+
qcom,opp-fuse-level = <3>;
90+
};
91+
};
92+
93+
power-controller@b018000 {
94+
compatible = "qcom,qcs404-cpr", "qcom,cpr";
95+
reg = <0x0b018000 0x1000>;
96+
interrupts = <0 15 IRQ_TYPE_EDGE_RISING>;
97+
clocks = <&xo_board>;
98+
clock-names = "ref";
99+
vdd-apc-supply = <&pms405_s3>;
100+
#power-domain-cells = <0>;
101+
operating-points-v2 = <&cpr_opp_table>;
102+
acc-syscon = <&tcsr>;
103+
104+
nvmem-cells = <&cpr_efuse_quot_offset1>,
105+
<&cpr_efuse_quot_offset2>,
106+
<&cpr_efuse_quot_offset3>,
107+
<&cpr_efuse_init_voltage1>,
108+
<&cpr_efuse_init_voltage2>,
109+
<&cpr_efuse_init_voltage3>,
110+
<&cpr_efuse_quot1>,
111+
<&cpr_efuse_quot2>,
112+
<&cpr_efuse_quot3>,
113+
<&cpr_efuse_ring1>,
114+
<&cpr_efuse_ring2>,
115+
<&cpr_efuse_ring3>,
116+
<&cpr_efuse_revision>;
117+
nvmem-cell-names = "cpr_quotient_offset1",
118+
"cpr_quotient_offset2",
119+
"cpr_quotient_offset3",
120+
"cpr_init_voltage1",
121+
"cpr_init_voltage2",
122+
"cpr_init_voltage3",
123+
"cpr_quotient1",
124+
"cpr_quotient2",
125+
"cpr_quotient3",
126+
"cpr_ring_osc1",
127+
"cpr_ring_osc2",
128+
"cpr_ring_osc3",
129+
"cpr_fuse_revision";
130+
};

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13671,6 +13671,14 @@ S: Maintained
1367113671
F: Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
1367213672
F: drivers/cpufreq/qcom-cpufreq-nvmem.c
1367313673

13674+
QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
13675+
M: Niklas Cassel <[email protected]>
13676+
13677+
13678+
S: Maintained
13679+
F: Documentation/devicetree/bindings/power/avs/qcom,cpr.txt
13680+
F: drivers/power/avs/qcom-cpr.c
13681+
1367413682
QUALCOMM EMAC GIGABIT ETHERNET DRIVER
1367513683
M: Timur Tabi <[email protected]>
1367613684

arch/x86/include/asm/intel-family.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111

112112
#define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */
113113
#define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */
114+
#define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */
114115

115116
/* Xeon Phi */
116117

drivers/base/power/runtime.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,10 @@ int __pm_runtime_idle(struct device *dev, int rpmflags)
10061006
int retval;
10071007

10081008
if (rpmflags & RPM_GET_PUT) {
1009-
if (!atomic_dec_and_test(&dev->power.usage_count))
1009+
if (!atomic_dec_and_test(&dev->power.usage_count)) {
1010+
trace_rpm_usage_rcuidle(dev, rpmflags);
10101011
return 0;
1012+
}
10111013
}
10121014

10131015
might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
@@ -1038,8 +1040,10 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags)
10381040
int retval;
10391041

10401042
if (rpmflags & RPM_GET_PUT) {
1041-
if (!atomic_dec_and_test(&dev->power.usage_count))
1043+
if (!atomic_dec_and_test(&dev->power.usage_count)) {
1044+
trace_rpm_usage_rcuidle(dev, rpmflags);
10421045
return 0;
1046+
}
10431047
}
10441048

10451049
might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
@@ -1101,6 +1105,7 @@ int pm_runtime_get_if_in_use(struct device *dev)
11011105
retval = dev->power.disable_depth > 0 ? -EINVAL :
11021106
dev->power.runtime_status == RPM_ACTIVE
11031107
&& atomic_inc_not_zero(&dev->power.usage_count);
1108+
trace_rpm_usage_rcuidle(dev, 0);
11041109
spin_unlock_irqrestore(&dev->power.lock, flags);
11051110
return retval;
11061111
}
@@ -1434,6 +1439,8 @@ void pm_runtime_allow(struct device *dev)
14341439
dev->power.runtime_auto = true;
14351440
if (atomic_dec_and_test(&dev->power.usage_count))
14361441
rpm_idle(dev, RPM_AUTO | RPM_ASYNC);
1442+
else
1443+
trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC);
14371444

14381445
out:
14391446
spin_unlock_irq(&dev->power.lock);
@@ -1501,6 +1508,8 @@ static void update_autosuspend(struct device *dev, int old_delay, int old_use)
15011508
if (!old_use || old_delay >= 0) {
15021509
atomic_inc(&dev->power.usage_count);
15031510
rpm_resume(dev, 0);
1511+
} else {
1512+
trace_rpm_usage_rcuidle(dev, 0);
15041513
}
15051514
}
15061515

drivers/opp/core.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,6 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
988988
BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head);
989989
INIT_LIST_HEAD(&opp_table->opp_list);
990990
kref_init(&opp_table->kref);
991-
kref_init(&opp_table->list_kref);
992991

993992
/* Secure the device table modification */
994993
list_add(&opp_table->node, &opp_tables);
@@ -1072,33 +1071,6 @@ static void _opp_table_kref_release(struct kref *kref)
10721071
mutex_unlock(&opp_table_lock);
10731072
}
10741073

1075-
void _opp_remove_all_static(struct opp_table *opp_table)
1076-
{
1077-
struct dev_pm_opp *opp, *tmp;
1078-
1079-
list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) {
1080-
if (!opp->dynamic)
1081-
dev_pm_opp_put(opp);
1082-
}
1083-
1084-
opp_table->parsed_static_opps = false;
1085-
}
1086-
1087-
static void _opp_table_list_kref_release(struct kref *kref)
1088-
{
1089-
struct opp_table *opp_table = container_of(kref, struct opp_table,
1090-
list_kref);
1091-
1092-
_opp_remove_all_static(opp_table);
1093-
mutex_unlock(&opp_table_lock);
1094-
}
1095-
1096-
void _put_opp_list_kref(struct opp_table *opp_table)
1097-
{
1098-
kref_put_mutex(&opp_table->list_kref, _opp_table_list_kref_release,
1099-
&opp_table_lock);
1100-
}
1101-
11021074
void dev_pm_opp_put_opp_table(struct opp_table *opp_table)
11031075
{
11041076
kref_put_mutex(&opp_table->kref, _opp_table_kref_release,
@@ -1202,6 +1174,24 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq)
12021174
}
12031175
EXPORT_SYMBOL_GPL(dev_pm_opp_remove);
12041176

1177+
void _opp_remove_all_static(struct opp_table *opp_table)
1178+
{
1179+
struct dev_pm_opp *opp, *tmp;
1180+
1181+
mutex_lock(&opp_table->lock);
1182+
1183+
if (!opp_table->parsed_static_opps || --opp_table->parsed_static_opps)
1184+
goto unlock;
1185+
1186+
list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) {
1187+
if (!opp->dynamic)
1188+
dev_pm_opp_put_unlocked(opp);
1189+
}
1190+
1191+
unlock:
1192+
mutex_unlock(&opp_table->lock);
1193+
}
1194+
12051195
/**
12061196
* dev_pm_opp_remove_all_dynamic() - Remove all dynamically created OPPs
12071197
* @dev: device for which we do this operation
@@ -2276,7 +2266,7 @@ void _dev_pm_opp_find_and_remove_table(struct device *dev)
22762266
return;
22772267
}
22782268

2279-
_put_opp_list_kref(opp_table);
2269+
_opp_remove_all_static(opp_table);
22802270

22812271
/* Drop reference taken by _find_opp_table() */
22822272
dev_pm_opp_put_opp_table(opp_table);

drivers/opp/of.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -658,17 +658,15 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
658658
struct dev_pm_opp *opp;
659659

660660
/* OPP table is already initialized for the device */
661+
mutex_lock(&opp_table->lock);
661662
if (opp_table->parsed_static_opps) {
662-
kref_get(&opp_table->list_kref);
663+
opp_table->parsed_static_opps++;
664+
mutex_unlock(&opp_table->lock);
663665
return 0;
664666
}
665667

666-
/*
667-
* Re-initialize list_kref every time we add static OPPs to the OPP
668-
* table as the reference count may be 0 after the last tie static OPPs
669-
* were removed.
670-
*/
671-
kref_init(&opp_table->list_kref);
668+
opp_table->parsed_static_opps = 1;
669+
mutex_unlock(&opp_table->lock);
672670

673671
/* We have opp-table node now, iterate over it and add OPPs */
674672
for_each_available_child_of_node(opp_table->np, np) {
@@ -678,15 +676,17 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
678676
dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
679677
ret);
680678
of_node_put(np);
681-
return ret;
679+
goto remove_static_opp;
682680
} else if (opp) {
683681
count++;
684682
}
685683
}
686684

687685
/* There should be one of more OPP defined */
688-
if (WARN_ON(!count))
689-
return -ENOENT;
686+
if (WARN_ON(!count)) {
687+
ret = -ENOENT;
688+
goto remove_static_opp;
689+
}
690690

691691
list_for_each_entry(opp, &opp_table->opp_list, node)
692692
pstate_count += !!opp->pstate;
@@ -695,15 +695,19 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
695695
if (pstate_count && pstate_count != count) {
696696
dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
697697
count, pstate_count);
698-
return -ENOENT;
698+
ret = -ENOENT;
699+
goto remove_static_opp;
699700
}
700701

701702
if (pstate_count)
702703
opp_table->genpd_performance_state = true;
703704

704-
opp_table->parsed_static_opps = true;
705-
706705
return 0;
706+
707+
remove_static_opp:
708+
_opp_remove_all_static(opp_table);
709+
710+
return ret;
707711
}
708712

709713
/* Initializes OPP tables based on old-deprecated bindings */
@@ -738,6 +742,7 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
738742
if (ret) {
739743
dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
740744
__func__, freq, ret);
745+
_opp_remove_all_static(opp_table);
741746
return ret;
742747
}
743748
nr -= 2;

drivers/opp/opp.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,10 @@ enum opp_table_access {
127127
* @dev_list: list of devices that share these OPPs
128128
* @opp_list: table of opps
129129
* @kref: for reference count of the table.
130-
* @list_kref: for reference count of the OPP list.
131130
* @lock: mutex protecting the opp_list and dev_list.
132131
* @np: struct device_node pointer for opp's DT node.
133132
* @clock_latency_ns_max: Max clock latency in nanoseconds.
134-
* @parsed_static_opps: True if OPPs are initialized from DT.
133+
* @parsed_static_opps: Count of devices for which OPPs are initialized from DT.
135134
* @shared_opp: OPP is shared between multiple devices.
136135
* @suspend_opp: Pointer to OPP to be used during device suspend.
137136
* @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers.
@@ -167,7 +166,6 @@ struct opp_table {
167166
struct list_head dev_list;
168167
struct list_head opp_list;
169168
struct kref kref;
170-
struct kref list_kref;
171169
struct mutex lock;
172170

173171
struct device_node *np;
@@ -176,7 +174,7 @@ struct opp_table {
176174
/* For backward compatibility with v1 bindings */
177175
unsigned int voltage_tolerance_v1;
178176

179-
bool parsed_static_opps;
177+
unsigned int parsed_static_opps;
180178
enum opp_table_access shared_opp;
181179
struct dev_pm_opp *suspend_opp;
182180

0 commit comments

Comments
 (0)