Merge branch 'pm-devfreq'

* pm-devfreq: (23 commits)
  PM / devfreq: remove compiler error with module governors (2)
  PM / devfreq: Fix return value in devfreq_remove_governor()
  PM / devfreq: Fix incorrect argument in error message
  PM / devfreq: missing rcu_read_lock() added for find_device_opp()
  PM / devfreq: remove compiler error when a governor is module
  PM / devfreq: exynos4_bus.c: Fixed an alignment of the func call args.
  PM / devfreq: Add sysfs node to expose available governors
  PM / devfreq: allow sysfs governor node to switch governor
  PM / devfreq: governors: add GPL module license and allow module build
  PM / devfreq: map devfreq drivers to governor using name
  PM / devfreq: register governors with devfreq framework
  PM / devfreq: provide hooks for governors to be registered
  PM / devfreq: export update_devfreq
  PM / devfreq: Add sysfs node for representing frequency transition information.
  PM / devfreq: Add sysfs node to expose available frequencies
  PM / devfreq: documentation cleanups for devfreq header
  PM / devfreq: Use devm_* functions in exynos4_bus.c
  PM / devfreq: make devfreq_class static
  PM / devfreq: fix sscanf handling for writable sysfs entries
  PM / devfreq: kernel-doc typo corrections
  ...
This commit is contained in:
Rafael J. Wysocki
2012-12-07 23:13:36 +01:00
10 zmienionych plików z 947 dodań i 406 usunięć

Wyświetl plik

@@ -30,7 +30,7 @@ if PM_DEVFREQ
comment "DEVFREQ Governors"
config DEVFREQ_GOV_SIMPLE_ONDEMAND
bool "Simple Ondemand"
tristate "Simple Ondemand"
help
Chooses frequency based on the recent load on the device. Works
similar as ONDEMAND governor of CPUFREQ does. A device with
@@ -39,7 +39,7 @@ config DEVFREQ_GOV_SIMPLE_ONDEMAND
values to the governor with data field at devfreq_add_device().
config DEVFREQ_GOV_PERFORMANCE
bool "Performance"
tristate "Performance"
help
Sets the frequency at the maximum available frequency.
This governor always returns UINT_MAX as frequency so that
@@ -47,7 +47,7 @@ config DEVFREQ_GOV_PERFORMANCE
at any time.
config DEVFREQ_GOV_POWERSAVE
bool "Powersave"
tristate "Powersave"
help
Sets the frequency at the minimum available frequency.
This governor always returns 0 as frequency so that
@@ -55,7 +55,7 @@ config DEVFREQ_GOV_POWERSAVE
at any time.
config DEVFREQ_GOV_USERSPACE
bool "Userspace"
tristate "Userspace"
help
Sets the frequency at the user specified one.
This governor returns the user configured frequency if there

Plik diff jest za duży Load Diff

Wyświetl plik

@@ -987,7 +987,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int err = 0;
data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
if (data == NULL) {
dev_err(dev, "Cannot allocate memory.\n");
return -ENOMEM;
@@ -1012,31 +1012,26 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
err = -EINVAL;
}
if (err)
goto err_regulator;
return err;
data->vdd_int = regulator_get(dev, "vdd_int");
data->vdd_int = devm_regulator_get(dev, "vdd_int");
if (IS_ERR(data->vdd_int)) {
dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
err = PTR_ERR(data->vdd_int);
goto err_regulator;
return PTR_ERR(data->vdd_int);
}
if (data->type == TYPE_BUSF_EXYNOS4x12) {
data->vdd_mif = regulator_get(dev, "vdd_mif");
data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
if (IS_ERR(data->vdd_mif)) {
dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
err = PTR_ERR(data->vdd_mif);
regulator_put(data->vdd_int);
goto err_regulator;
return PTR_ERR(data->vdd_mif);
}
}
opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
if (IS_ERR(opp)) {
dev_err(dev, "Invalid initial frequency %lu kHz.\n",
exynos4_devfreq_profile.initial_freq);
err = PTR_ERR(opp);
goto err_opp_add;
exynos4_devfreq_profile.initial_freq);
return PTR_ERR(opp);
}
data->curr_opp = opp;
@@ -1045,30 +1040,20 @@ 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);
if (IS_ERR(data->devfreq)) {
err = PTR_ERR(data->devfreq);
goto err_opp_add;
}
"simple_ondemand", NULL);
if (IS_ERR(data->devfreq))
return PTR_ERR(data->devfreq);
devfreq_register_opp_notifier(dev, data->devfreq);
err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
goto err_devfreq_add;
devfreq_remove_device(data->devfreq);
return err;
}
return 0;
err_devfreq_add:
devfreq_remove_device(data->devfreq);
err_opp_add:
if (data->vdd_mif)
regulator_put(data->vdd_mif);
regulator_put(data->vdd_int);
err_regulator:
kfree(data);
return err;
}
static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
@@ -1077,10 +1062,6 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
unregister_pm_notifier(&data->pm_notifier);
devfreq_remove_device(data->devfreq);
regulator_put(data->vdd_int);
if (data->vdd_mif)
regulator_put(data->vdd_mif);
kfree(data);
return 0;
}

Wyświetl plik

@@ -18,7 +18,24 @@
#define to_devfreq(DEV) container_of((DEV), struct devfreq, dev)
/* Devfreq events */
#define DEVFREQ_GOV_START 0x1
#define DEVFREQ_GOV_STOP 0x2
#define DEVFREQ_GOV_INTERVAL 0x3
#define DEVFREQ_GOV_SUSPEND 0x4
#define DEVFREQ_GOV_RESUME 0x5
/* Caution: devfreq->lock must be locked before calling update_devfreq */
extern int update_devfreq(struct devfreq *devfreq);
extern void devfreq_monitor_start(struct devfreq *devfreq);
extern void devfreq_monitor_stop(struct devfreq *devfreq);
extern void devfreq_monitor_suspend(struct devfreq *devfreq);
extern void devfreq_monitor_resume(struct devfreq *devfreq);
extern void devfreq_interval_update(struct devfreq *devfreq,
unsigned int *delay);
extern int devfreq_add_governor(struct devfreq_governor *governor);
extern int devfreq_remove_governor(struct devfreq_governor *governor);
#endif /* _GOVERNOR_H */

Wyświetl plik

@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
#include <linux/module.h>
#include "governor.h"
static int devfreq_performance_func(struct devfreq *df,
@@ -26,14 +27,41 @@ static int devfreq_performance_func(struct devfreq *df,
return 0;
}
static int performance_init(struct devfreq *devfreq)
static int devfreq_performance_handler(struct devfreq *devfreq,
unsigned int event, void *data)
{
return update_devfreq(devfreq);
int ret = 0;
if (event == DEVFREQ_GOV_START) {
mutex_lock(&devfreq->lock);
ret = update_devfreq(devfreq);
mutex_unlock(&devfreq->lock);
}
return ret;
}
const struct devfreq_governor devfreq_performance = {
static struct devfreq_governor devfreq_performance = {
.name = "performance",
.init = performance_init,
.get_target_freq = devfreq_performance_func,
.no_central_polling = true,
.event_handler = devfreq_performance_handler,
};
static int __init devfreq_performance_init(void)
{
return devfreq_add_governor(&devfreq_performance);
}
subsys_initcall(devfreq_performance_init);
static void __exit devfreq_performance_exit(void)
{
int ret;
ret = devfreq_remove_governor(&devfreq_performance);
if (ret)
pr_err("%s: failed remove governor %d\n", __func__, ret);
return;
}
module_exit(devfreq_performance_exit);
MODULE_LICENSE("GPL");

Wyświetl plik

@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
#include <linux/module.h>
#include "governor.h"
static int devfreq_powersave_func(struct devfreq *df,
@@ -23,14 +24,41 @@ static int devfreq_powersave_func(struct devfreq *df,
return 0;
}
static int powersave_init(struct devfreq *devfreq)
static int devfreq_powersave_handler(struct devfreq *devfreq,
unsigned int event, void *data)
{
return update_devfreq(devfreq);
int ret = 0;
if (event == DEVFREQ_GOV_START) {
mutex_lock(&devfreq->lock);
ret = update_devfreq(devfreq);
mutex_unlock(&devfreq->lock);
}
return ret;
}
const struct devfreq_governor devfreq_powersave = {
static struct devfreq_governor devfreq_powersave = {
.name = "powersave",
.init = powersave_init,
.get_target_freq = devfreq_powersave_func,
.no_central_polling = true,
.event_handler = devfreq_powersave_handler,
};
static int __init devfreq_powersave_init(void)
{
return devfreq_add_governor(&devfreq_powersave);
}
subsys_initcall(devfreq_powersave_init);
static void __exit devfreq_powersave_exit(void)
{
int ret;
ret = devfreq_remove_governor(&devfreq_powersave);
if (ret)
pr_err("%s: failed remove governor %d\n", __func__, ret);
return;
}
module_exit(devfreq_powersave_exit);
MODULE_LICENSE("GPL");

Wyświetl plik

@@ -10,8 +10,10 @@
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/devfreq.h>
#include <linux/math64.h>
#include "governor.h"
/* Default constants for DevFreq-Simple-Ondemand (DFSO) */
#define DFSO_UPTHRESHOLD (90)
@@ -88,7 +90,58 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
return 0;
}
const struct devfreq_governor devfreq_simple_ondemand = {
static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
unsigned int event, void *data)
{
switch (event) {
case DEVFREQ_GOV_START:
devfreq_monitor_start(devfreq);
break;
case DEVFREQ_GOV_STOP:
devfreq_monitor_stop(devfreq);
break;
case DEVFREQ_GOV_INTERVAL:
devfreq_interval_update(devfreq, (unsigned int *)data);
break;
case DEVFREQ_GOV_SUSPEND:
devfreq_monitor_suspend(devfreq);
break;
case DEVFREQ_GOV_RESUME:
devfreq_monitor_resume(devfreq);
break;
default:
break;
}
return 0;
}
static struct devfreq_governor devfreq_simple_ondemand = {
.name = "simple_ondemand",
.get_target_freq = devfreq_simple_ondemand_func,
.event_handler = devfreq_simple_ondemand_handler,
};
static int __init devfreq_simple_ondemand_init(void)
{
return devfreq_add_governor(&devfreq_simple_ondemand);
}
subsys_initcall(devfreq_simple_ondemand_init);
static void __exit devfreq_simple_ondemand_exit(void)
{
int ret;
ret = devfreq_remove_governor(&devfreq_simple_ondemand);
if (ret)
pr_err("%s: failed remove governor %d\n", __func__, ret);
return;
}
module_exit(devfreq_simple_ondemand_exit);
MODULE_LICENSE("GPL");

Wyświetl plik

@@ -14,6 +14,7 @@
#include <linux/devfreq.h>
#include <linux/pm.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include "governor.h"
struct userspace_data {
@@ -116,10 +117,46 @@ static void userspace_exit(struct devfreq *devfreq)
devfreq->data = NULL;
}
const struct devfreq_governor devfreq_userspace = {
static int devfreq_userspace_handler(struct devfreq *devfreq,
unsigned int event, void *data)
{
int ret = 0;
switch (event) {
case DEVFREQ_GOV_START:
ret = userspace_init(devfreq);
break;
case DEVFREQ_GOV_STOP:
userspace_exit(devfreq);
break;
default:
break;
}
return ret;
}
static struct devfreq_governor devfreq_userspace = {
.name = "userspace",
.get_target_freq = devfreq_userspace_func,
.init = userspace_init,
.exit = userspace_exit,
.no_central_polling = true,
.event_handler = devfreq_userspace_handler,
};
static int __init devfreq_userspace_init(void)
{
return devfreq_add_governor(&devfreq_userspace);
}
subsys_initcall(devfreq_userspace_init);
static void __exit devfreq_userspace_exit(void)
{
int ret;
ret = devfreq_remove_governor(&devfreq_userspace);
if (ret)
pr_err("%s: failed remove governor %d\n", __func__, ret);
return;
}
module_exit(devfreq_userspace_exit);
MODULE_LICENSE("GPL");