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:
@@ -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
@@ -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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
Reference in New Issue
Block a user