Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 336780
b: refs/heads/master
c: 1b5c1be
h: refs/heads/master
v: v3
  • Loading branch information
Nishanth Menon authored and MyungJoo Ham committed Nov 20, 2012
1 parent b26e2f5 commit 3b3447d
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 83116e66a232184f733ecf09a41817cf893ede98
refs/heads/master: 1b5c1be2c88e8445a20fa1929e26c37e7ca8c926
95 changes: 87 additions & 8 deletions trunk/drivers/devfreq/devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ int update_devfreq(struct devfreq *devfreq)
return -EINVAL;
}

if (!devfreq->governor)
return -EINVAL;

/* Reevaluate the proper frequency */
err = devfreq->governor->get_target_freq(devfreq, &freq);
if (err)
Expand Down Expand Up @@ -379,7 +382,9 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip)
list_del(&devfreq->node);
mutex_unlock(&devfreq_list_lock);

devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL);
if (devfreq->governor)
devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_STOP, NULL);

if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent);
Expand Down Expand Up @@ -412,19 +417,20 @@ static void devfreq_dev_release(struct device *dev)
* devfreq_add_device() - Add devfreq feature to the device
* @dev: the device to add devfreq feature.
* @profile: device-specific profile to run devfreq.
* @governor: the policy to choose frequency.
* @governor_name: name of the policy to choose frequency.
* @data: private data for the governor. The devfreq framework does not
* touch this value.
*/
struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
const struct devfreq_governor *governor,
const char *governor_name,
void *data)
{
struct devfreq *devfreq;
struct devfreq_governor *governor;
int err = 0;

if (!dev || !profile || !governor) {
if (!dev || !profile || !governor_name) {
dev_err(dev, "%s: Invalid parameters.\n", __func__);
return ERR_PTR(-EINVAL);
}
Expand Down Expand Up @@ -452,7 +458,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
devfreq->dev.class = devfreq_class;
devfreq->dev.release = devfreq_dev_release;
devfreq->profile = profile;
devfreq->governor = governor;
strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
devfreq->previous_freq = profile->initial_freq;
devfreq->data = data;
devfreq->nb.notifier_call = devfreq_notifier_call;
Expand All @@ -478,10 +484,14 @@ struct devfreq *devfreq_add_device(struct device *dev,

mutex_lock(&devfreq_list_lock);
list_add(&devfreq->node, &devfreq_list);
mutex_unlock(&devfreq_list_lock);

err = devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_START, NULL);
governor = find_devfreq_governor(devfreq->governor_name);
if (!IS_ERR(governor))
devfreq->governor = governor;
if (devfreq->governor)
err = devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_START, NULL);
mutex_unlock(&devfreq_list_lock);
if (err) {
dev_err(dev, "%s: Unable to start governor for the device\n",
__func__);
Expand Down Expand Up @@ -524,6 +534,9 @@ int devfreq_suspend_device(struct devfreq *devfreq)
if (!devfreq)
return -EINVAL;

if (!devfreq->governor)
return 0;

return devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_SUSPEND, NULL);
}
Expand All @@ -538,6 +551,9 @@ int devfreq_resume_device(struct devfreq *devfreq)
if (!devfreq)
return -EINVAL;

if (!devfreq->governor)
return 0;

return devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_RESUME, NULL);
}
Expand All @@ -550,6 +566,7 @@ EXPORT_SYMBOL(devfreq_resume_device);
int devfreq_add_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
struct devfreq *devfreq;
int err = 0;

if (!governor) {
Expand All @@ -568,6 +585,38 @@ int devfreq_add_governor(struct devfreq_governor *governor)

list_add(&governor->node, &devfreq_governor_list);

list_for_each_entry(devfreq, &devfreq_list, node) {
int ret = 0;
struct device *dev = devfreq->dev.parent;

if (!strncmp(devfreq->governor_name, governor->name,
DEVFREQ_NAME_LEN)) {
/* The following should never occur */
if (devfreq->governor) {
dev_warn(dev,
"%s: Governor %s already present\n",
__func__, devfreq->governor->name);
ret = devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_STOP, NULL);
if (ret) {
dev_warn(dev,
"%s: Governor %s stop = %d\n",
__func__,
devfreq->governor->name, ret);
}
/* Fall through */
}
devfreq->governor = governor;
ret = devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_START, NULL);
if (ret) {
dev_warn(dev, "%s: Governor %s start=%d\n",
__func__, devfreq->governor->name,
ret);
}
}
}

err_out:
mutex_unlock(&devfreq_list_lock);

Expand All @@ -582,6 +631,7 @@ EXPORT_SYMBOL(devfreq_add_governor);
int devfreq_remove_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
struct devfreq *devfreq;
int err = 0;

if (!governor) {
Expand All @@ -597,6 +647,29 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
err = -EINVAL;
goto err_out;
}
list_for_each_entry(devfreq, &devfreq_list, node) {
int ret;
struct device *dev = devfreq->dev.parent;

if (!strncmp(devfreq->governor_name, governor->name,
DEVFREQ_NAME_LEN)) {
/* we should have a devfreq governor! */
if (!devfreq->governor) {
dev_warn(dev, "%s: Governor %s NOT present\n",
__func__, governor->name);
continue;
/* Fall through */
}
ret = devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_STOP, NULL);
if (ret) {
dev_warn(dev, "%s: Governor %s stop=%d\n",
__func__, devfreq->governor->name,
ret);
}
devfreq->governor = NULL;
}
}

list_del(&governor->node);
err_out:
Expand All @@ -609,6 +682,9 @@ EXPORT_SYMBOL(devfreq_remove_governor);
static ssize_t show_governor(struct device *dev,
struct device_attribute *attr, char *buf)
{
if (!to_devfreq(dev)->governor)
return -EINVAL;

return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}

Expand Down Expand Up @@ -645,6 +721,9 @@ static ssize_t store_polling_interval(struct device *dev,
unsigned int value;
int ret;

if (!df->governor)
return -EINVAL;

ret = sscanf(buf, "%u", &value);
if (ret != 1)
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/devfreq/exynos4_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
busfreq_mon_reset(data);

data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
&devfreq_simple_ondemand, NULL);
"simple_ondemand", NULL);
if (IS_ERR(data->devfreq))
return PTR_ERR(data->devfreq);

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/devfreq/governor_performance.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq,
return ret;
}

const struct devfreq_governor devfreq_performance = {
static struct devfreq_governor devfreq_performance = {
.name = "performance",
.get_target_freq = devfreq_performance_func,
.event_handler = devfreq_performance_handler,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/devfreq/governor_powersave.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq,
return ret;
}

const struct devfreq_governor devfreq_powersave = {
static struct devfreq_governor devfreq_powersave = {
.name = "powersave",
.get_target_freq = devfreq_powersave_func,
.event_handler = devfreq_powersave_handler,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/devfreq/governor_simpleondemand.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
return 0;
}

const struct devfreq_governor devfreq_simple_ondemand = {
static struct devfreq_governor devfreq_simple_ondemand = {
.name = "simple_ondemand",
.get_target_freq = devfreq_simple_ondemand_func,
.event_handler = devfreq_simple_ondemand_handler,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/devfreq/governor_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int devfreq_userspace_handler(struct devfreq *devfreq,
return ret;
}

const struct devfreq_governor devfreq_userspace = {
static struct devfreq_governor devfreq_userspace = {
.name = "userspace",
.get_target_freq = devfreq_userspace_func,
.event_handler = devfreq_userspace_handler,
Expand Down
21 changes: 4 additions & 17 deletions trunk/include/linux/devfreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct devfreq_governor {
* using devfreq.
* @profile: device-specific devfreq profile
* @governor: method how to choose frequency based on the usage.
* @governor_name: devfreq governor name for use with this devfreq
* @nb: notifier block used to notify devfreq object that it should
* reevaluate operable frequencies. Devfreq users may use
* devfreq.nb to the corresponding register notifier call chain.
Expand Down Expand Up @@ -155,6 +156,7 @@ struct devfreq {
struct device dev;
struct devfreq_dev_profile *profile;
const struct devfreq_governor *governor;
char governor_name[DEVFREQ_NAME_LEN];
struct notifier_block nb;
struct delayed_work work;

Expand All @@ -176,7 +178,7 @@ struct devfreq {
#if defined(CONFIG_PM_DEVFREQ)
extern struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
const struct devfreq_governor *governor,
const char *governor_name,
void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
extern int devfreq_suspend_device(struct devfreq *devfreq);
Expand All @@ -190,17 +192,7 @@ extern int devfreq_register_opp_notifier(struct device *dev,
extern int devfreq_unregister_opp_notifier(struct device *dev,
struct devfreq *devfreq);

#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE
extern const struct devfreq_governor devfreq_powersave;
#endif
#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE
extern const struct devfreq_governor devfreq_performance;
#endif
#ifdef CONFIG_DEVFREQ_GOV_USERSPACE
extern const struct devfreq_governor devfreq_userspace;
#endif
#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND
extern const struct devfreq_governor devfreq_simple_ondemand;
/**
* struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
* and devfreq_add_device
Expand All @@ -223,7 +215,7 @@ struct devfreq_simple_ondemand_data {
#else /* !CONFIG_PM_DEVFREQ */
static struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
struct devfreq_governor *governor,
const char *governor_name,
void *data)
{
return NULL;
Expand Down Expand Up @@ -262,11 +254,6 @@ static int devfreq_unregister_opp_notifier(struct device *dev,
return -EINVAL;
}

#define devfreq_powersave NULL
#define devfreq_performance NULL
#define devfreq_userspace NULL
#define devfreq_simple_ondemand NULL

#endif /* CONFIG_PM_DEVFREQ */

#endif /* __LINUX_DEVFREQ_H__ */

0 comments on commit 3b3447d

Please sign in to comment.