Skip to content

Commit 4f9a7a1

Browse files
lukaszluba-armvireshk
authored andcommitted
OPP: Add "opp-microwatt" supporting code
Add new property to the OPP: power value. The OPP entry in the DT can have "opp-microwatt". Add the needed code to handle this new property in the existing infrastructure. Signed-off-by: Lukasz Luba <lukasz.luba@arm.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
1 parent 0409ab7 commit 4f9a7a1

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

drivers/opp/core.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,31 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
113113
}
114114
EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage);
115115

116+
/**
117+
* dev_pm_opp_get_power() - Gets the power corresponding to an opp
118+
* @opp: opp for which power has to be returned for
119+
*
120+
* Return: power in micro watt corresponding to the opp, else
121+
* return 0
122+
*
123+
* This is useful only for devices with single power supply.
124+
*/
125+
unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
126+
{
127+
unsigned long opp_power = 0;
128+
int i;
129+
130+
if (IS_ERR_OR_NULL(opp)) {
131+
pr_err("%s: Invalid parameters\n", __func__);
132+
return 0;
133+
}
134+
for (i = 0; i < opp->opp_table->regulator_count; i++)
135+
opp_power += opp->supplies[i].u_watt;
136+
137+
return opp_power;
138+
}
139+
EXPORT_SYMBOL_GPL(dev_pm_opp_get_power);
140+
116141
/**
117142
* dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp
118143
* @opp: opp for which frequency has to be returned for

drivers/opp/debugfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ static void opp_debug_create_supplies(struct dev_pm_opp *opp,
100100

101101
debugfs_create_ulong("u_amp", S_IRUGO, d,
102102
&opp->supplies[i].u_amp);
103+
104+
debugfs_create_ulong("u_watt", S_IRUGO, d,
105+
&opp->supplies[i].u_watt);
103106
}
104107
}
105108

drivers/opp/of.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,9 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
575575
static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
576576
struct opp_table *opp_table)
577577
{
578-
u32 *microvolt, *microamp = NULL;
579-
int supplies = opp_table->regulator_count, vcount, icount, ret, i, j;
578+
u32 *microvolt, *microamp = NULL, *microwatt = NULL;
579+
int supplies = opp_table->regulator_count;
580+
int vcount, icount, pcount, ret, i, j;
580581
struct property *prop = NULL;
581582
char name[NAME_MAX];
582583

@@ -688,6 +689,43 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
688689
}
689690
}
690691

692+
/* Search for "opp-microwatt" */
693+
sprintf(name, "opp-microwatt");
694+
prop = of_find_property(opp->np, name, NULL);
695+
696+
if (prop) {
697+
pcount = of_property_count_u32_elems(opp->np, name);
698+
if (pcount < 0) {
699+
dev_err(dev, "%s: Invalid %s property (%d)\n", __func__,
700+
name, pcount);
701+
ret = pcount;
702+
goto free_microamp;
703+
}
704+
705+
if (pcount != supplies) {
706+
dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
707+
__func__, name, pcount, supplies);
708+
ret = -EINVAL;
709+
goto free_microamp;
710+
}
711+
712+
microwatt = kmalloc_array(pcount, sizeof(*microwatt),
713+
GFP_KERNEL);
714+
if (!microwatt) {
715+
ret = -EINVAL;
716+
goto free_microamp;
717+
}
718+
719+
ret = of_property_read_u32_array(opp->np, name, microwatt,
720+
pcount);
721+
if (ret) {
722+
dev_err(dev, "%s: error parsing %s: %d\n", __func__,
723+
name, ret);
724+
ret = -EINVAL;
725+
goto free_microwatt;
726+
}
727+
}
728+
691729
for (i = 0, j = 0; i < supplies; i++) {
692730
opp->supplies[i].u_volt = microvolt[j++];
693731

@@ -701,8 +739,13 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
701739

702740
if (microamp)
703741
opp->supplies[i].u_amp = microamp[i];
742+
743+
if (microwatt)
744+
opp->supplies[i].u_watt = microwatt[i];
704745
}
705746

747+
free_microwatt:
748+
kfree(microwatt);
706749
free_microamp:
707750
kfree(microamp);
708751
free_microvolt:

include/linux/pm_opp.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ enum dev_pm_opp_event {
3232
* @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
3333
* @u_volt_max: Maximum voltage in microvolts corresponding to this OPP
3434
* @u_amp: Maximum current drawn by the device in microamperes
35+
* @u_watt: Power used by the device in microwatts
3536
*
36-
* This structure stores the voltage/current values for a single power supply.
37+
* This structure stores the voltage/current/power values for a single power
38+
* supply.
3739
*/
3840
struct dev_pm_opp_supply {
3941
unsigned long u_volt;
4042
unsigned long u_volt_min;
4143
unsigned long u_volt_max;
4244
unsigned long u_amp;
45+
unsigned long u_watt;
4346
};
4447

4548
/**
@@ -94,6 +97,8 @@ void dev_pm_opp_put_opp_table(struct opp_table *opp_table);
9497

9598
unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);
9699

100+
unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp);
101+
97102
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);
98103

99104
unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp);
@@ -186,6 +191,11 @@ static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
186191
return 0;
187192
}
188193

194+
static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
195+
{
196+
return 0;
197+
}
198+
189199
static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
190200
{
191201
return 0;

0 commit comments

Comments
 (0)