Commit 4f9a7a1d authored by Lukasz Luba's avatar Lukasz Luba Committed by Viresh Kumar
Browse files

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: default avatarLukasz Luba <lukasz.luba@arm.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent 0409ab77
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -113,6 +113,31 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage);

/**
 * dev_pm_opp_get_power() - Gets the power corresponding to an opp
 * @opp:	opp for which power has to be returned for
 *
 * Return: power in micro watt corresponding to the opp, else
 * return 0
 *
 * This is useful only for devices with single power supply.
 */
unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
{
	unsigned long opp_power = 0;
	int i;

	if (IS_ERR_OR_NULL(opp)) {
		pr_err("%s: Invalid parameters\n", __func__);
		return 0;
	}
	for (i = 0; i < opp->opp_table->regulator_count; i++)
		opp_power += opp->supplies[i].u_watt;

	return opp_power;
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_power);

/**
 * dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp
 * @opp:	opp for which frequency has to be returned for
+3 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ static void opp_debug_create_supplies(struct dev_pm_opp *opp,

		debugfs_create_ulong("u_amp", S_IRUGO, d,
				     &opp->supplies[i].u_amp);

		debugfs_create_ulong("u_watt", S_IRUGO, d,
				     &opp->supplies[i].u_watt);
	}
}

+45 −2
Original line number Diff line number Diff line
@@ -575,8 +575,9 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
			      struct opp_table *opp_table)
{
	u32 *microvolt, *microamp = NULL;
	int supplies = opp_table->regulator_count, vcount, icount, ret, i, j;
	u32 *microvolt, *microamp = NULL, *microwatt = NULL;
	int supplies = opp_table->regulator_count;
	int vcount, icount, pcount, ret, i, j;
	struct property *prop = NULL;
	char name[NAME_MAX];

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

	/* Search for "opp-microwatt" */
	sprintf(name, "opp-microwatt");
	prop = of_find_property(opp->np, name, NULL);

	if (prop) {
		pcount = of_property_count_u32_elems(opp->np, name);
		if (pcount < 0) {
			dev_err(dev, "%s: Invalid %s property (%d)\n", __func__,
				name, pcount);
			ret = pcount;
			goto free_microamp;
		}

		if (pcount != supplies) {
			dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
				__func__, name, pcount, supplies);
			ret = -EINVAL;
			goto free_microamp;
		}

		microwatt = kmalloc_array(pcount, sizeof(*microwatt),
					  GFP_KERNEL);
		if (!microwatt) {
			ret = -EINVAL;
			goto free_microamp;
		}

		ret = of_property_read_u32_array(opp->np, name, microwatt,
						 pcount);
		if (ret) {
			dev_err(dev, "%s: error parsing %s: %d\n", __func__,
				name, ret);
			ret = -EINVAL;
			goto free_microwatt;
		}
	}

	for (i = 0, j = 0; i < supplies; i++) {
		opp->supplies[i].u_volt = microvolt[j++];

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

		if (microamp)
			opp->supplies[i].u_amp = microamp[i];

		if (microwatt)
			opp->supplies[i].u_watt = microwatt[i];
	}

free_microwatt:
	kfree(microwatt);
free_microamp:
	kfree(microamp);
free_microvolt:
+11 −1
Original line number Diff line number Diff line
@@ -32,14 +32,17 @@ enum dev_pm_opp_event {
 * @u_volt_min:	Minimum voltage in microvolts corresponding to this OPP
 * @u_volt_max:	Maximum voltage in microvolts corresponding to this OPP
 * @u_amp:	Maximum current drawn by the device in microamperes
 * @u_watt:	Power used by the device in microwatts
 *
 * This structure stores the voltage/current values for a single power supply.
 * This structure stores the voltage/current/power values for a single power
 * supply.
 */
struct dev_pm_opp_supply {
	unsigned long u_volt;
	unsigned long u_volt_min;
	unsigned long u_volt_max;
	unsigned long u_amp;
	unsigned long u_watt;
};

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

unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);

unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp);

unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);

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)
	return 0;
}

static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
{
	return 0;
}

static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
{
	return 0;