aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-10-30 06:11:21 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-10-30 06:11:21 -0400
commit82a1faa94989d92b65ef137030329b75aaa2737f (patch)
tree07ff9bbf99b5e0850c7c0723a59d0805a8c8f684
parent0b07194bb55ed836c2cc7c22e866b87a14681984 (diff)
parentaa7c352f9841ab3fee5bf1de127a45e6310124a6 (diff)
Merge tag 'pullreq_20171026' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq into pm-devfreq
Pull devfreq changes for v4.15 from MyungJoo Ham. * tag 'pullreq_20171026' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq: PM / devfreq: Define the constant governor name PM / devfreq: Remove unneeded conditional statement PM / devfreq: Show the all available frequencies PM / devfreq: Change return type of devfreq_set_freq_table() PM / devfreq: Use the available min/max frequency Revert "PM / devfreq: Add show_one macro to delete the duplicate code" PM / devfreq: Set min/max_freq when adding the devfreq device
-rw-r--r--drivers/devfreq/devfreq.c139
-rw-r--r--drivers/devfreq/exynos-bus.c5
-rw-r--r--drivers/devfreq/governor_passive.c2
-rw-r--r--drivers/devfreq/governor_performance.c2
-rw-r--r--drivers/devfreq/governor_powersave.c2
-rw-r--r--drivers/devfreq/governor_simpleondemand.c2
-rw-r--r--drivers/devfreq/governor_userspace.c2
-rw-r--r--drivers/devfreq/rk3399_dmc.c2
-rw-r--r--include/linux/devfreq.h16
9 files changed, 123 insertions, 49 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index a1c4ee818614..78fb496ecb4e 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -28,6 +28,9 @@
28#include <linux/of.h> 28#include <linux/of.h>
29#include "governor.h" 29#include "governor.h"
30 30
31#define MAX(a,b) ((a > b) ? a : b)
32#define MIN(a,b) ((a < b) ? a : b)
33
31static struct class *devfreq_class; 34static struct class *devfreq_class;
32 35
33/* 36/*
@@ -69,6 +72,34 @@ static struct devfreq *find_device_devfreq(struct device *dev)
69 return ERR_PTR(-ENODEV); 72 return ERR_PTR(-ENODEV);
70} 73}
71 74
75static unsigned long find_available_min_freq(struct devfreq *devfreq)
76{
77 struct dev_pm_opp *opp;
78 unsigned long min_freq = 0;
79
80 opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq);
81 if (IS_ERR(opp))
82 min_freq = 0;
83 else
84 dev_pm_opp_put(opp);
85
86 return min_freq;
87}
88
89static unsigned long find_available_max_freq(struct devfreq *devfreq)
90{
91 struct dev_pm_opp *opp;
92 unsigned long max_freq = ULONG_MAX;
93
94 opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq);
95 if (IS_ERR(opp))
96 max_freq = 0;
97 else
98 dev_pm_opp_put(opp);
99
100 return max_freq;
101}
102
72/** 103/**
73 * devfreq_get_freq_level() - Lookup freq_table for the frequency 104 * devfreq_get_freq_level() - Lookup freq_table for the frequency
74 * @devfreq: the devfreq instance 105 * @devfreq: the devfreq instance
@@ -85,11 +116,7 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
85 return -EINVAL; 116 return -EINVAL;
86} 117}
87 118
88/** 119static int set_freq_table(struct devfreq *devfreq)
89 * devfreq_set_freq_table() - Initialize freq_table for the frequency
90 * @devfreq: the devfreq instance
91 */
92static void devfreq_set_freq_table(struct devfreq *devfreq)
93{ 120{
94 struct devfreq_dev_profile *profile = devfreq->profile; 121 struct devfreq_dev_profile *profile = devfreq->profile;
95 struct dev_pm_opp *opp; 122 struct dev_pm_opp *opp;
@@ -99,7 +126,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
99 /* Initialize the freq_table from OPP table */ 126 /* Initialize the freq_table from OPP table */
100 count = dev_pm_opp_get_opp_count(devfreq->dev.parent); 127 count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
101 if (count <= 0) 128 if (count <= 0)
102 return; 129 return -EINVAL;
103 130
104 profile->max_state = count; 131 profile->max_state = count;
105 profile->freq_table = devm_kcalloc(devfreq->dev.parent, 132 profile->freq_table = devm_kcalloc(devfreq->dev.parent,
@@ -108,7 +135,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
108 GFP_KERNEL); 135 GFP_KERNEL);
109 if (!profile->freq_table) { 136 if (!profile->freq_table) {
110 profile->max_state = 0; 137 profile->max_state = 0;
111 return; 138 return -ENOMEM;
112 } 139 }
113 140
114 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { 141 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
@@ -116,11 +143,13 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
116 if (IS_ERR(opp)) { 143 if (IS_ERR(opp)) {
117 devm_kfree(devfreq->dev.parent, profile->freq_table); 144 devm_kfree(devfreq->dev.parent, profile->freq_table);
118 profile->max_state = 0; 145 profile->max_state = 0;
119 return; 146 return PTR_ERR(opp);
120 } 147 }
121 dev_pm_opp_put(opp); 148 dev_pm_opp_put(opp);
122 profile->freq_table[i] = freq; 149 profile->freq_table[i] = freq;
123 } 150 }
151
152 return 0;
124} 153}
125 154
126/** 155/**
@@ -227,7 +256,7 @@ static int devfreq_notify_transition(struct devfreq *devfreq,
227int update_devfreq(struct devfreq *devfreq) 256int update_devfreq(struct devfreq *devfreq)
228{ 257{
229 struct devfreq_freqs freqs; 258 struct devfreq_freqs freqs;
230 unsigned long freq, cur_freq; 259 unsigned long freq, cur_freq, min_freq, max_freq;
231 int err = 0; 260 int err = 0;
232 u32 flags = 0; 261 u32 flags = 0;
233 262
@@ -245,19 +274,21 @@ int update_devfreq(struct devfreq *devfreq)
245 return err; 274 return err;
246 275
247 /* 276 /*
248 * Adjust the frequency with user freq and QoS. 277 * Adjust the frequency with user freq, QoS and available freq.
249 * 278 *
250 * List from the highest priority 279 * List from the highest priority
251 * max_freq 280 * max_freq
252 * min_freq 281 * min_freq
253 */ 282 */
283 max_freq = MIN(devfreq->scaling_max_freq, devfreq->max_freq);
284 min_freq = MAX(devfreq->scaling_min_freq, devfreq->min_freq);
254 285
255 if (devfreq->min_freq && freq < devfreq->min_freq) { 286 if (min_freq && freq < min_freq) {
256 freq = devfreq->min_freq; 287 freq = min_freq;
257 flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ 288 flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
258 } 289 }
259 if (devfreq->max_freq && freq > devfreq->max_freq) { 290 if (max_freq && freq > max_freq) {
260 freq = devfreq->max_freq; 291 freq = max_freq;
261 flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ 292 flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
262 } 293 }
263 294
@@ -280,10 +311,9 @@ int update_devfreq(struct devfreq *devfreq)
280 freqs.new = freq; 311 freqs.new = freq;
281 devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); 312 devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);
282 313
283 if (devfreq->profile->freq_table) 314 if (devfreq_update_status(devfreq, freq))
284 if (devfreq_update_status(devfreq, freq)) 315 dev_err(&devfreq->dev,
285 dev_err(&devfreq->dev, 316 "Couldn't update frequency transition information.\n");
286 "Couldn't update frequency transition information.\n");
287 317
288 devfreq->previous_freq = freq; 318 devfreq->previous_freq = freq;
289 return err; 319 return err;
@@ -466,6 +496,19 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
466 int ret; 496 int ret;
467 497
468 mutex_lock(&devfreq->lock); 498 mutex_lock(&devfreq->lock);
499
500 devfreq->scaling_min_freq = find_available_min_freq(devfreq);
501 if (!devfreq->scaling_min_freq) {
502 mutex_unlock(&devfreq->lock);
503 return -EINVAL;
504 }
505
506 devfreq->scaling_max_freq = find_available_max_freq(devfreq);
507 if (!devfreq->scaling_max_freq) {
508 mutex_unlock(&devfreq->lock);
509 return -EINVAL;
510 }
511
469 ret = update_devfreq(devfreq); 512 ret = update_devfreq(devfreq);
470 mutex_unlock(&devfreq->lock); 513 mutex_unlock(&devfreq->lock);
471 514
@@ -555,10 +598,28 @@ struct devfreq *devfreq_add_device(struct device *dev,
555 598
556 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) { 599 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
557 mutex_unlock(&devfreq->lock); 600 mutex_unlock(&devfreq->lock);
558 devfreq_set_freq_table(devfreq); 601 err = set_freq_table(devfreq);
602 if (err < 0)
603 goto err_out;
559 mutex_lock(&devfreq->lock); 604 mutex_lock(&devfreq->lock);
560 } 605 }
561 606
607 devfreq->min_freq = find_available_min_freq(devfreq);
608 if (!devfreq->min_freq) {
609 mutex_unlock(&devfreq->lock);
610 err = -EINVAL;
611 goto err_dev;
612 }
613 devfreq->scaling_min_freq = devfreq->min_freq;
614
615 devfreq->max_freq = find_available_max_freq(devfreq);
616 if (!devfreq->max_freq) {
617 mutex_unlock(&devfreq->lock);
618 err = -EINVAL;
619 goto err_dev;
620 }
621 devfreq->scaling_max_freq = devfreq->max_freq;
622
562 dev_set_name(&devfreq->dev, "devfreq%d", 623 dev_set_name(&devfreq->dev, "devfreq%d",
563 atomic_inc_return(&devfreq_no)); 624 atomic_inc_return(&devfreq_no));
564 err = device_register(&devfreq->dev); 625 err = device_register(&devfreq->dev);
@@ -1082,6 +1143,14 @@ unlock:
1082 return ret; 1143 return ret;
1083} 1144}
1084 1145
1146static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
1147 char *buf)
1148{
1149 struct devfreq *df = to_devfreq(dev);
1150
1151 return sprintf(buf, "%lu\n", MAX(df->scaling_min_freq, df->min_freq));
1152}
1153
1085static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, 1154static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
1086 const char *buf, size_t count) 1155 const char *buf, size_t count)
1087{ 1156{
@@ -1108,17 +1177,15 @@ unlock:
1108 mutex_unlock(&df->lock); 1177 mutex_unlock(&df->lock);
1109 return ret; 1178 return ret;
1110} 1179}
1180static DEVICE_ATTR_RW(min_freq);
1111 1181
1112#define show_one(name) \ 1182static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
1113static ssize_t name##_show \ 1183 char *buf)
1114(struct device *dev, struct device_attribute *attr, char *buf) \ 1184{
1115{ \ 1185 struct devfreq *df = to_devfreq(dev);
1116 return sprintf(buf, "%lu\n", to_devfreq(dev)->name); \
1117}
1118show_one(min_freq);
1119show_one(max_freq);
1120 1186
1121static DEVICE_ATTR_RW(min_freq); 1187 return sprintf(buf, "%lu\n", MIN(df->scaling_max_freq, df->max_freq));
1188}
1122static DEVICE_ATTR_RW(max_freq); 1189static DEVICE_ATTR_RW(max_freq);
1123 1190
1124static ssize_t available_frequencies_show(struct device *d, 1191static ssize_t available_frequencies_show(struct device *d,
@@ -1126,22 +1193,16 @@ static ssize_t available_frequencies_show(struct device *d,
1126 char *buf) 1193 char *buf)
1127{ 1194{
1128 struct devfreq *df = to_devfreq(d); 1195 struct devfreq *df = to_devfreq(d);
1129 struct device *dev = df->dev.parent;
1130 struct dev_pm_opp *opp;
1131 ssize_t count = 0; 1196 ssize_t count = 0;
1132 unsigned long freq = 0; 1197 int i;
1133 1198
1134 do { 1199 mutex_lock(&df->lock);
1135 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
1136 if (IS_ERR(opp))
1137 break;
1138 1200
1139 dev_pm_opp_put(opp); 1201 for (i = 0; i < df->profile->max_state; i++)
1140 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 1202 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
1141 "%lu ", freq); 1203 "%lu ", df->profile->freq_table[i]);
1142 freq++;
1143 } while (1);
1144 1204
1205 mutex_unlock(&df->lock);
1145 /* Truncate the trailing space */ 1206 /* Truncate the trailing space */
1146 if (count) 1207 if (count)
1147 count--; 1208 count--;
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 49f68929e024..c25658b26598 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -436,7 +436,8 @@ static int exynos_bus_probe(struct platform_device *pdev)
436 ondemand_data->downdifferential = 5; 436 ondemand_data->downdifferential = 5;
437 437
438 /* Add devfreq device to monitor and handle the exynos bus */ 438 /* Add devfreq device to monitor and handle the exynos bus */
439 bus->devfreq = devm_devfreq_add_device(dev, profile, "simple_ondemand", 439 bus->devfreq = devm_devfreq_add_device(dev, profile,
440 DEVFREQ_GOV_SIMPLE_ONDEMAND,
440 ondemand_data); 441 ondemand_data);
441 if (IS_ERR(bus->devfreq)) { 442 if (IS_ERR(bus->devfreq)) {
442 dev_err(dev, "failed to add devfreq device\n"); 443 dev_err(dev, "failed to add devfreq device\n");
@@ -488,7 +489,7 @@ passive:
488 passive_data->parent = parent_devfreq; 489 passive_data->parent = parent_devfreq;
489 490
490 /* Add devfreq device for exynos bus with passive governor */ 491 /* Add devfreq device for exynos bus with passive governor */
491 bus->devfreq = devm_devfreq_add_device(dev, profile, "passive", 492 bus->devfreq = devm_devfreq_add_device(dev, profile, DEVFREQ_GOV_PASSIVE,
492 passive_data); 493 passive_data);
493 if (IS_ERR(bus->devfreq)) { 494 if (IS_ERR(bus->devfreq)) {
494 dev_err(dev, 495 dev_err(dev,
diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
index 673ad8cc9a1d..3bc29acbd54e 100644
--- a/drivers/devfreq/governor_passive.c
+++ b/drivers/devfreq/governor_passive.c
@@ -183,7 +183,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
183} 183}
184 184
185static struct devfreq_governor devfreq_passive = { 185static struct devfreq_governor devfreq_passive = {
186 .name = "passive", 186 .name = DEVFREQ_GOV_PASSIVE,
187 .immutable = 1, 187 .immutable = 1,
188 .get_target_freq = devfreq_passive_get_target_freq, 188 .get_target_freq = devfreq_passive_get_target_freq,
189 .event_handler = devfreq_passive_event_handler, 189 .event_handler = devfreq_passive_event_handler,
diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c
index c72f942f30a8..4d23ecfbd948 100644
--- a/drivers/devfreq/governor_performance.c
+++ b/drivers/devfreq/governor_performance.c
@@ -42,7 +42,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq,
42} 42}
43 43
44static struct devfreq_governor devfreq_performance = { 44static struct devfreq_governor devfreq_performance = {
45 .name = "performance", 45 .name = DEVFREQ_GOV_PERFORMANCE,
46 .get_target_freq = devfreq_performance_func, 46 .get_target_freq = devfreq_performance_func,
47 .event_handler = devfreq_performance_handler, 47 .event_handler = devfreq_performance_handler,
48}; 48};
diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c
index 0c6bed567e6d..0c42f23249ef 100644
--- a/drivers/devfreq/governor_powersave.c
+++ b/drivers/devfreq/governor_powersave.c
@@ -39,7 +39,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq,
39} 39}
40 40
41static struct devfreq_governor devfreq_powersave = { 41static struct devfreq_governor devfreq_powersave = {
42 .name = "powersave", 42 .name = DEVFREQ_GOV_POWERSAVE,
43 .get_target_freq = devfreq_powersave_func, 43 .get_target_freq = devfreq_powersave_func,
44 .event_handler = devfreq_powersave_handler, 44 .event_handler = devfreq_powersave_handler,
45}; 45};
diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c
index ae72ba5e78df..28e0f2de7100 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -125,7 +125,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
125} 125}
126 126
127static struct devfreq_governor devfreq_simple_ondemand = { 127static struct devfreq_governor devfreq_simple_ondemand = {
128 .name = "simple_ondemand", 128 .name = DEVFREQ_GOV_SIMPLE_ONDEMAND,
129 .get_target_freq = devfreq_simple_ondemand_func, 129 .get_target_freq = devfreq_simple_ondemand_func,
130 .event_handler = devfreq_simple_ondemand_handler, 130 .event_handler = devfreq_simple_ondemand_handler,
131}; 131};
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 77028c27593c..080607c3f34d 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -87,7 +87,7 @@ static struct attribute *dev_entries[] = {
87 NULL, 87 NULL,
88}; 88};
89static const struct attribute_group dev_attr_group = { 89static const struct attribute_group dev_attr_group = {
90 .name = "userspace", 90 .name = DEVFREQ_GOV_USERSPACE,
91 .attrs = dev_entries, 91 .attrs = dev_entries,
92}; 92};
93 93
diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 1b89ebbad02c..5dfbfa3cc878 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -431,7 +431,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
431 431
432 data->devfreq = devm_devfreq_add_device(dev, 432 data->devfreq = devm_devfreq_add_device(dev,
433 &rk3399_devfreq_dmc_profile, 433 &rk3399_devfreq_dmc_profile,
434 "simple_ondemand", 434 DEVFREQ_GOV_SIMPLE_ONDEMAND,
435 &data->ondemand_data); 435 &data->ondemand_data);
436 if (IS_ERR(data->devfreq)) 436 if (IS_ERR(data->devfreq))
437 return PTR_ERR(data->devfreq); 437 return PTR_ERR(data->devfreq);
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 597294e0cc40..3aae5b3af87c 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -19,6 +19,13 @@
19 19
20#define DEVFREQ_NAME_LEN 16 20#define DEVFREQ_NAME_LEN 16
21 21
22/* DEVFREQ governor name */
23#define DEVFREQ_GOV_SIMPLE_ONDEMAND "simple_ondemand"
24#define DEVFREQ_GOV_PERFORMANCE "performance"
25#define DEVFREQ_GOV_POWERSAVE "powersave"
26#define DEVFREQ_GOV_USERSPACE "userspace"
27#define DEVFREQ_GOV_PASSIVE "passive"
28
22/* DEVFREQ notifier interface */ 29/* DEVFREQ notifier interface */
23#define DEVFREQ_TRANSITION_NOTIFIER (0) 30#define DEVFREQ_TRANSITION_NOTIFIER (0)
24 31
@@ -84,8 +91,9 @@ struct devfreq_dev_status {
84 * from devfreq_remove_device() call. If the user 91 * from devfreq_remove_device() call. If the user
85 * has registered devfreq->nb at a notifier-head, 92 * has registered devfreq->nb at a notifier-head,
86 * this is the time to unregister it. 93 * this is the time to unregister it.
87 * @freq_table: Optional list of frequencies to support statistics. 94 * @freq_table: Optional list of frequencies to support statistics
88 * @max_state: The size of freq_table. 95 * and freq_table must be generated in ascending order.
96 * @max_state: The size of freq_table.
89 */ 97 */
90struct devfreq_dev_profile { 98struct devfreq_dev_profile {
91 unsigned long initial_freq; 99 unsigned long initial_freq;
@@ -120,6 +128,8 @@ struct devfreq_dev_profile {
120 * touch this. 128 * touch this.
121 * @min_freq: Limit minimum frequency requested by user (0: none) 129 * @min_freq: Limit minimum frequency requested by user (0: none)
122 * @max_freq: Limit maximum frequency requested by user (0: none) 130 * @max_freq: Limit maximum frequency requested by user (0: none)
131 * @scaling_min_freq: Limit minimum frequency requested by OPP interface
132 * @scaling_max_freq: Limit maximum frequency requested by OPP interface
123 * @stop_polling: devfreq polling status of a device. 133 * @stop_polling: devfreq polling status of a device.
124 * @total_trans: Number of devfreq transitions 134 * @total_trans: Number of devfreq transitions
125 * @trans_table: Statistics of devfreq transitions 135 * @trans_table: Statistics of devfreq transitions
@@ -153,6 +163,8 @@ struct devfreq {
153 163
154 unsigned long min_freq; 164 unsigned long min_freq;
155 unsigned long max_freq; 165 unsigned long max_freq;
166 unsigned long scaling_min_freq;
167 unsigned long scaling_max_freq;
156 bool stop_polling; 168 bool stop_polling;
157 169
158 /* information for device frequency transition */ 170 /* information for device frequency transition */