Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e5b3352 authored by Jeremy Gebben's avatar Jeremy Gebben Committed by Stephen Boyd
Browse files

PM / devfreq: improve devfreq->data support



This field is treated as governer specific data for
a devfreq instance. But there's currently no way to
set the correct data when switching governors through
sysfs. Add support for optionally passing a set of
name / data pairs in struct devfreq_dev_profile,
representing the data for each governor.

Change-Id: I5523ce94f8b0045974f0635fb734cb1282512f91
Signed-off-by: default avatarJeremy Gebben <jgebben@codeaurora.org>
Signed-off-by: default avatarVladimir Razgulin <vrazguli@codeaurora.org>
parent 8bb62853
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -418,6 +418,32 @@ static void devfreq_dev_release(struct device *dev)
	_remove_devfreq(devfreq, true);
}

/**
 * find_governor_data - Find device specific private data for a governor.
 * @profile: The profile to search.
 * @governor_name: The governor to search for.
 *
 * Look up the device specific data for a governor.
 */
static void *find_governor_data(struct devfreq_dev_profile *profile,
				const char *governor_name)
{
	void *data = NULL;
	int i;

	if (profile->governor_data == NULL)
		return NULL;

	for (i = 0; i < profile->num_governor_data; i++) {
		if (!strncmp(governor_name, profile->governor_data[i].name,
			     DEVFREQ_NAME_LEN) == 0) {
			data = profile->governor_data[i].data;
			break;
		}
	}
	return data;
}

/**
 * devfreq_add_device() - Add devfreq feature to the device
 * @dev:	the device to add devfreq feature.
@@ -465,7 +491,10 @@ struct devfreq *devfreq_add_device(struct device *dev,
	devfreq->profile = profile;
	strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
	devfreq->previous_freq = profile->initial_freq;
	devfreq->data = data;

	devfreq->data = data ? data : find_governor_data(devfreq->profile,
							 governor_name);

	devfreq->nb.notifier_call = devfreq_notifier_call;

	devfreq->trans_table =	devm_kzalloc(dev, sizeof(unsigned int) *
@@ -722,6 +751,7 @@ static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
			goto out;
		}
	}
	df->data = find_governor_data(df->profile, str_governor);
	df->governor = governor;
	strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
	ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+21 −0
Original line number Diff line number Diff line
@@ -52,6 +52,20 @@ struct devfreq_dev_status {
 */
#define DEVFREQ_FLAG_LEAST_UPPER_BOUND		0x1

/**
 * struct devfreq_governor_data - mapping to per device governor data
 * @name:		The name of the governor.
 * @data:		Private data for the governor.
 *
 * Devices may pass in an array of this structure to allow governors
 * to get the correct data pointer when they are enabled after
 * the devfreq_add_device() call.
 */
struct devfreq_governor_data {
	const char *name;
	void *data;
};

/**
 * struct devfreq_dev_profile - Devfreq's user device profile
 * @initial_freq:	The operating frequency when devfreq_add_device() is
@@ -75,6 +89,11 @@ struct devfreq_dev_status {
 *			this is the time to unregister it.
 * @freq_table:	Optional list of frequencies to support statistics.
 * @max_state:	The size of freq_table.
 * @governor_data:	Optional array of private data for governors.
 *			This is used to set devfreq->data correctly
 *			when a governor is enabled via sysfs or other
 *			mechanisms after the devfreq_add_device() call.
 * @num_governor_data:  Number of elements in governor_data.
 */
struct devfreq_dev_profile {
	unsigned long initial_freq;
@@ -88,6 +107,8 @@ struct devfreq_dev_profile {

	unsigned int *freq_table;
	unsigned int max_state;
	const struct devfreq_governor_data *governor_data;
	unsigned int num_governor_data;
};

/**