diff options
author | Chanwoo Choi <cw00.choi@samsung.com> | 2017-01-31 01:38:16 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-12 00:41:44 -0500 |
commit | 2294b771a4b425d9365aabeaff8d33ccd0c0fffe (patch) | |
tree | f16438f5e986d75df62fdd1fb2a0810be43b25f9 | |
parent | d9cc31683a16f5619217d80c3d8e608c23c41afc (diff) |
PM / devfreq: Fix available_governor sysfs
commit bcf23c79c4e46130701370af4383b61a3cba755c upstream.
The devfreq using passive governor is not able to change the governor.
So, the user can not change the governor through 'available_governor' sysfs
entry. Also, the devfreq which don't use the passive governor is not able to
change to 'passive' governor on the fly.
Fixes: 996133119f57 ("PM / devfreq: Add new passive governor")
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/devfreq/devfreq.c | 31 | ||||
-rw-r--r-- | drivers/devfreq/governor_passive.c | 1 | ||||
-rw-r--r-- | include/linux/devfreq.h | 3 |
3 files changed, 31 insertions, 4 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 712592cef1a2..2eacfb4b905f 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -939,6 +939,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, | |||
939 | if (df->governor == governor) { | 939 | if (df->governor == governor) { |
940 | ret = 0; | 940 | ret = 0; |
941 | goto out; | 941 | goto out; |
942 | } else if (df->governor->immutable || governor->immutable) { | ||
943 | ret = -EINVAL; | ||
944 | goto out; | ||
942 | } | 945 | } |
943 | 946 | ||
944 | if (df->governor) { | 947 | if (df->governor) { |
@@ -968,13 +971,33 @@ static ssize_t available_governors_show(struct device *d, | |||
968 | struct device_attribute *attr, | 971 | struct device_attribute *attr, |
969 | char *buf) | 972 | char *buf) |
970 | { | 973 | { |
971 | struct devfreq_governor *tmp_governor; | 974 | struct devfreq *df = to_devfreq(d); |
972 | ssize_t count = 0; | 975 | ssize_t count = 0; |
973 | 976 | ||
974 | mutex_lock(&devfreq_list_lock); | 977 | mutex_lock(&devfreq_list_lock); |
975 | list_for_each_entry(tmp_governor, &devfreq_governor_list, node) | 978 | |
976 | count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), | 979 | /* |
977 | "%s ", tmp_governor->name); | 980 | * The devfreq with immutable governor (e.g., passive) shows |
981 | * only own governor. | ||
982 | */ | ||
983 | if (df->governor->immutable) { | ||
984 | count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, | ||
985 | "%s ", df->governor_name); | ||
986 | /* | ||
987 | * The devfreq device shows the registered governor except for | ||
988 | * immutable governors such as passive governor . | ||
989 | */ | ||
990 | } else { | ||
991 | struct devfreq_governor *governor; | ||
992 | |||
993 | list_for_each_entry(governor, &devfreq_governor_list, node) { | ||
994 | if (governor->immutable) | ||
995 | continue; | ||
996 | count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), | ||
997 | "%s ", governor->name); | ||
998 | } | ||
999 | } | ||
1000 | |||
978 | mutex_unlock(&devfreq_list_lock); | 1001 | mutex_unlock(&devfreq_list_lock); |
979 | 1002 | ||
980 | /* Truncate the trailing space */ | 1003 | /* Truncate the trailing space */ |
diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 9ef46e2592c4..93795b32dc09 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c | |||
@@ -179,6 +179,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, | |||
179 | 179 | ||
180 | static struct devfreq_governor devfreq_passive = { | 180 | static struct devfreq_governor devfreq_passive = { |
181 | .name = "passive", | 181 | .name = "passive", |
182 | .immutable = 1, | ||
182 | .get_target_freq = devfreq_passive_get_target_freq, | 183 | .get_target_freq = devfreq_passive_get_target_freq, |
183 | .event_handler = devfreq_passive_event_handler, | 184 | .event_handler = devfreq_passive_event_handler, |
184 | }; | 185 | }; |
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 2de4e2eea180..e0acb0e5243b 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h | |||
@@ -104,6 +104,8 @@ struct devfreq_dev_profile { | |||
104 | * struct devfreq_governor - Devfreq policy governor | 104 | * struct devfreq_governor - Devfreq policy governor |
105 | * @node: list node - contains registered devfreq governors | 105 | * @node: list node - contains registered devfreq governors |
106 | * @name: Governor's name | 106 | * @name: Governor's name |
107 | * @immutable: Immutable flag for governor. If the value is 1, | ||
108 | * this govenror is never changeable to other governor. | ||
107 | * @get_target_freq: Returns desired operating frequency for the device. | 109 | * @get_target_freq: Returns desired operating frequency for the device. |
108 | * Basically, get_target_freq will run | 110 | * Basically, get_target_freq will run |
109 | * devfreq_dev_profile.get_dev_status() to get the | 111 | * devfreq_dev_profile.get_dev_status() to get the |
@@ -121,6 +123,7 @@ struct devfreq_governor { | |||
121 | struct list_head node; | 123 | struct list_head node; |
122 | 124 | ||
123 | const char name[DEVFREQ_NAME_LEN]; | 125 | const char name[DEVFREQ_NAME_LEN]; |
126 | const unsigned int immutable; | ||
124 | int (*get_target_freq)(struct devfreq *this, unsigned long *freq); | 127 | int (*get_target_freq)(struct devfreq *this, unsigned long *freq); |
125 | int (*event_handler)(struct devfreq *devfreq, | 128 | int (*event_handler)(struct devfreq *devfreq, |
126 | unsigned int event, void *data); | 129 | unsigned int event, void *data); |