aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/qos.c
diff options
context:
space:
mode:
authorJean Pihet <j-pihet@ti.com>2011-08-25 09:35:27 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-08-25 09:35:27 -0400
commit4e1779baaa542c83b459b0a56585e0c1a04c7782 (patch)
tree0708390d5e00c000d97b89e846a94a7006249521 /kernel/power/qos.c
parent4a31a33425a1eb92f6a0b9846f081842268361c8 (diff)
PM QoS: Reorganize data structs
In preparation for the per-device constratins support, re-organize the data strctures: - add a struct pm_qos_constraints which contains the constraints related data - update struct pm_qos_object contents to the PM QoS internal object data. Add a pointer to struct pm_qos_constraints - update the internal code to use the new data structs. Signed-off-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'kernel/power/qos.c')
-rw-r--r--kernel/power/qos.c85
1 files changed, 41 insertions, 44 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 788c4cfe0cdb..4a35fe50b777 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -49,58 +49,53 @@
49 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 49 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
50 * held, taken with _irqsave. One lock to rule them all 50 * held, taken with _irqsave. One lock to rule them all
51 */ 51 */
52enum pm_qos_type {
53 PM_QOS_MAX, /* return the largest value */
54 PM_QOS_MIN /* return the smallest value */
55};
56
57/*
58 * Note: The lockless read path depends on the CPU accessing
59 * target_value atomically. Atomic access is only guaranteed on all CPU
60 * types linux supports for 32 bit quantites
61 */
62struct pm_qos_object { 52struct pm_qos_object {
63 struct plist_head constraints; 53 struct pm_qos_constraints *constraints;
64 struct blocking_notifier_head *notifiers;
65 struct miscdevice pm_qos_power_miscdev; 54 struct miscdevice pm_qos_power_miscdev;
66 char *name; 55 char *name;
67 s32 target_value; /* Do not change to 64 bit */
68 s32 default_value;
69 enum pm_qos_type type;
70}; 56};
71 57
72static DEFINE_SPINLOCK(pm_qos_lock); 58static DEFINE_SPINLOCK(pm_qos_lock);
73 59
74static struct pm_qos_object null_pm_qos; 60static struct pm_qos_object null_pm_qos;
61
75static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); 62static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
76static struct pm_qos_object cpu_dma_pm_qos = { 63static struct pm_qos_constraints cpu_dma_constraints = {
77 .constraints = PLIST_HEAD_INIT(cpu_dma_pm_qos.constraints), 64 .list = PLIST_HEAD_INIT(cpu_dma_constraints.list),
78 .notifiers = &cpu_dma_lat_notifier,
79 .name = "cpu_dma_latency",
80 .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 65 .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
81 .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 66 .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
82 .type = PM_QOS_MIN, 67 .type = PM_QOS_MIN,
68 .notifiers = &cpu_dma_lat_notifier,
69};
70static struct pm_qos_object cpu_dma_pm_qos = {
71 .constraints = &cpu_dma_constraints,
83}; 72};
84 73
85static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); 74static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
86static struct pm_qos_object network_lat_pm_qos = { 75static struct pm_qos_constraints network_lat_constraints = {
87 .constraints = PLIST_HEAD_INIT(network_lat_pm_qos.constraints), 76 .list = PLIST_HEAD_INIT(network_lat_constraints.list),
88 .notifiers = &network_lat_notifier,
89 .name = "network_latency",
90 .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, 77 .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
91 .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, 78 .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
92 .type = PM_QOS_MIN 79 .type = PM_QOS_MIN,
80 .notifiers = &network_lat_notifier,
81};
82static struct pm_qos_object network_lat_pm_qos = {
83 .constraints = &network_lat_constraints,
84 .name = "network_latency",
93}; 85};
94 86
95 87
96static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); 88static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
97static struct pm_qos_object network_throughput_pm_qos = { 89static struct pm_qos_constraints network_tput_constraints = {
98 .constraints = PLIST_HEAD_INIT(network_throughput_pm_qos.constraints), 90 .list = PLIST_HEAD_INIT(network_tput_constraints.list),
99 .notifiers = &network_throughput_notifier,
100 .name = "network_throughput",
101 .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, 91 .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
102 .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, 92 .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
103 .type = PM_QOS_MAX, 93 .type = PM_QOS_MAX,
94 .notifiers = &network_throughput_notifier,
95};
96static struct pm_qos_object network_throughput_pm_qos = {
97 .constraints = &network_tput_constraints,
98 .name = "network_throughput",
104}; 99};
105 100
106 101
@@ -129,15 +124,15 @@ static const struct file_operations pm_qos_power_fops = {
129/* unlocked internal variant */ 124/* unlocked internal variant */
130static inline int pm_qos_get_value(struct pm_qos_object *o) 125static inline int pm_qos_get_value(struct pm_qos_object *o)
131{ 126{
132 if (plist_head_empty(&o->constraints)) 127 if (plist_head_empty(&o->constraints->list))
133 return o->default_value; 128 return o->constraints->default_value;
134 129
135 switch (o->type) { 130 switch (o->constraints->type) {
136 case PM_QOS_MIN: 131 case PM_QOS_MIN:
137 return plist_first(&o->constraints)->prio; 132 return plist_first(&o->constraints->list)->prio;
138 133
139 case PM_QOS_MAX: 134 case PM_QOS_MAX:
140 return plist_last(&o->constraints)->prio; 135 return plist_last(&o->constraints->list)->prio;
141 136
142 default: 137 default:
143 /* runtime check for not using enum */ 138 /* runtime check for not using enum */
@@ -147,12 +142,12 @@ static inline int pm_qos_get_value(struct pm_qos_object *o)
147 142
148static inline s32 pm_qos_read_value(struct pm_qos_object *o) 143static inline s32 pm_qos_read_value(struct pm_qos_object *o)
149{ 144{
150 return o->target_value; 145 return o->constraints->target_value;
151} 146}
152 147
153static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) 148static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
154{ 149{
155 o->target_value = value; 150 o->constraints->target_value = value;
156} 151}
157 152
158static void update_target(struct pm_qos_object *o, struct plist_node *node, 153static void update_target(struct pm_qos_object *o, struct plist_node *node,
@@ -170,20 +165,20 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
170 * with new value and add, then see if the extremal 165 * with new value and add, then see if the extremal
171 * changed 166 * changed
172 */ 167 */
173 plist_del(node, &o->constraints); 168 plist_del(node, &o->constraints->list);
174 plist_node_init(node, value); 169 plist_node_init(node, value);
175 plist_add(node, &o->constraints); 170 plist_add(node, &o->constraints->list);
176 } else if (del) { 171 } else if (del) {
177 plist_del(node, &o->constraints); 172 plist_del(node, &o->constraints->list);
178 } else { 173 } else {
179 plist_add(node, &o->constraints); 174 plist_add(node, &o->constraints->list);
180 } 175 }
181 curr_value = pm_qos_get_value(o); 176 curr_value = pm_qos_get_value(o);
182 pm_qos_set_value(o, curr_value); 177 pm_qos_set_value(o, curr_value);
183 spin_unlock_irqrestore(&pm_qos_lock, flags); 178 spin_unlock_irqrestore(&pm_qos_lock, flags);
184 179
185 if (prev_value != curr_value) 180 if (prev_value != curr_value)
186 blocking_notifier_call_chain(o->notifiers, 181 blocking_notifier_call_chain(o->constraints->notifiers,
187 (unsigned long)curr_value, 182 (unsigned long)curr_value,
188 NULL); 183 NULL);
189} 184}
@@ -230,7 +225,7 @@ void pm_qos_add_request(struct pm_qos_request *req,
230 return; 225 return;
231 } 226 }
232 if (value == PM_QOS_DEFAULT_VALUE) 227 if (value == PM_QOS_DEFAULT_VALUE)
233 new_value = o->default_value; 228 new_value = o->constraints->default_value;
234 else 229 else
235 new_value = value; 230 new_value = value;
236 plist_node_init(&req->node, new_value); 231 plist_node_init(&req->node, new_value);
@@ -266,7 +261,7 @@ void pm_qos_update_request(struct pm_qos_request *req,
266 o = pm_qos_array[req->pm_qos_class]; 261 o = pm_qos_array[req->pm_qos_class];
267 262
268 if (new_value == PM_QOS_DEFAULT_VALUE) 263 if (new_value == PM_QOS_DEFAULT_VALUE)
269 temp = o->default_value; 264 temp = o->constraints->default_value;
270 else 265 else
271 temp = new_value; 266 temp = new_value;
272 267
@@ -315,7 +310,8 @@ int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
315 int retval; 310 int retval;
316 311
317 retval = blocking_notifier_chain_register( 312 retval = blocking_notifier_chain_register(
318 pm_qos_array[pm_qos_class]->notifiers, notifier); 313 pm_qos_array[pm_qos_class]->constraints->notifiers,
314 notifier);
319 315
320 return retval; 316 return retval;
321} 317}
@@ -334,7 +330,8 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
334 int retval; 330 int retval;
335 331
336 retval = blocking_notifier_chain_unregister( 332 retval = blocking_notifier_chain_unregister(
337 pm_qos_array[pm_qos_class]->notifiers, notifier); 333 pm_qos_array[pm_qos_class]->constraints->notifiers,
334 notifier);
338 335
339 return retval; 336 return retval;
340} 337}