These changes are a raw update to a vanilla kernel 4.1.10, with the
[kvmfornfv.git] / kernel / drivers / base / power / clock_ops.c
1 /*
2  * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
3  *
4  * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
5  *
6  * This file is released under the GPLv2.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/device.h>
11 #include <linux/io.h>
12 #include <linux/pm.h>
13 #include <linux/pm_clock.h>
14 #include <linux/clk.h>
15 #include <linux/clkdev.h>
16 #include <linux/slab.h>
17 #include <linux/err.h>
18
19 #ifdef CONFIG_PM
20
21 enum pce_status {
22         PCE_STATUS_NONE = 0,
23         PCE_STATUS_ACQUIRED,
24         PCE_STATUS_ENABLED,
25         PCE_STATUS_ERROR,
26 };
27
28 struct pm_clock_entry {
29         struct list_head node;
30         char *con_id;
31         struct clk *clk;
32         enum pce_status status;
33 };
34
35 /**
36  * pm_clk_enable - Enable a clock, reporting any errors
37  * @dev: The device for the given clock
38  * @ce: PM clock entry corresponding to the clock.
39  */
40 static inline void __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce)
41 {
42         int ret;
43
44         if (ce->status < PCE_STATUS_ERROR) {
45                 ret = clk_enable(ce->clk);
46                 if (!ret)
47                         ce->status = PCE_STATUS_ENABLED;
48                 else
49                         dev_err(dev, "%s: failed to enable clk %p, error %d\n",
50                                 __func__, ce->clk, ret);
51         }
52 }
53
54 /**
55  * pm_clk_acquire - Acquire a device clock.
56  * @dev: Device whose clock is to be acquired.
57  * @ce: PM clock entry corresponding to the clock.
58  */
59 static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
60 {
61         if (!ce->clk)
62                 ce->clk = clk_get(dev, ce->con_id);
63         if (IS_ERR(ce->clk)) {
64                 ce->status = PCE_STATUS_ERROR;
65         } else {
66                 clk_prepare(ce->clk);
67                 ce->status = PCE_STATUS_ACQUIRED;
68                 dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
69         }
70 }
71
72 static int __pm_clk_add(struct device *dev, const char *con_id,
73                         struct clk *clk)
74 {
75         struct pm_subsys_data *psd = dev_to_psd(dev);
76         struct pm_clock_entry *ce;
77
78         if (!psd)
79                 return -EINVAL;
80
81         ce = kzalloc(sizeof(*ce), GFP_KERNEL);
82         if (!ce)
83                 return -ENOMEM;
84
85         if (con_id) {
86                 ce->con_id = kstrdup(con_id, GFP_KERNEL);
87                 if (!ce->con_id) {
88                         dev_err(dev,
89                                 "Not enough memory for clock connection ID.\n");
90                         kfree(ce);
91                         return -ENOMEM;
92                 }
93         } else {
94                 if (IS_ERR(clk) || !__clk_get(clk)) {
95                         kfree(ce);
96                         return -ENOENT;
97                 }
98                 ce->clk = clk;
99         }
100
101         pm_clk_acquire(dev, ce);
102
103         spin_lock_irq(&psd->lock);
104         list_add_tail(&ce->node, &psd->clock_list);
105         spin_unlock_irq(&psd->lock);
106         return 0;
107 }
108
109 /**
110  * pm_clk_add - Start using a device clock for power management.
111  * @dev: Device whose clock is going to be used for power management.
112  * @con_id: Connection ID of the clock.
113  *
114  * Add the clock represented by @con_id to the list of clocks used for
115  * the power management of @dev.
116  */
117 int pm_clk_add(struct device *dev, const char *con_id)
118 {
119         return __pm_clk_add(dev, con_id, NULL);
120 }
121
122 /**
123  * pm_clk_add_clk - Start using a device clock for power management.
124  * @dev: Device whose clock is going to be used for power management.
125  * @clk: Clock pointer
126  *
127  * Add the clock to the list of clocks used for the power management of @dev.
128  * It will increment refcount on clock pointer, use clk_put() on it when done.
129  */
130 int pm_clk_add_clk(struct device *dev, struct clk *clk)
131 {
132         return __pm_clk_add(dev, NULL, clk);
133 }
134
135 /**
136  * __pm_clk_remove - Destroy PM clock entry.
137  * @ce: PM clock entry to destroy.
138  */
139 static void __pm_clk_remove(struct pm_clock_entry *ce)
140 {
141         if (!ce)
142                 return;
143
144         if (ce->status < PCE_STATUS_ERROR) {
145                 if (ce->status == PCE_STATUS_ENABLED)
146                         clk_disable(ce->clk);
147
148                 if (ce->status >= PCE_STATUS_ACQUIRED) {
149                         clk_unprepare(ce->clk);
150                         clk_put(ce->clk);
151                 }
152         }
153
154         kfree(ce->con_id);
155         kfree(ce);
156 }
157
158 /**
159  * pm_clk_remove - Stop using a device clock for power management.
160  * @dev: Device whose clock should not be used for PM any more.
161  * @con_id: Connection ID of the clock.
162  *
163  * Remove the clock represented by @con_id from the list of clocks used for
164  * the power management of @dev.
165  */
166 void pm_clk_remove(struct device *dev, const char *con_id)
167 {
168         struct pm_subsys_data *psd = dev_to_psd(dev);
169         struct pm_clock_entry *ce;
170
171         if (!psd)
172                 return;
173
174         spin_lock_irq(&psd->lock);
175
176         list_for_each_entry(ce, &psd->clock_list, node) {
177                 if (!con_id && !ce->con_id)
178                         goto remove;
179                 else if (!con_id || !ce->con_id)
180                         continue;
181                 else if (!strcmp(con_id, ce->con_id))
182                         goto remove;
183         }
184
185         spin_unlock_irq(&psd->lock);
186         return;
187
188  remove:
189         list_del(&ce->node);
190         spin_unlock_irq(&psd->lock);
191
192         __pm_clk_remove(ce);
193 }
194
195 /**
196  * pm_clk_init - Initialize a device's list of power management clocks.
197  * @dev: Device to initialize the list of PM clocks for.
198  *
199  * Initialize the lock and clock_list members of the device's pm_subsys_data
200  * object.
201  */
202 void pm_clk_init(struct device *dev)
203 {
204         struct pm_subsys_data *psd = dev_to_psd(dev);
205         if (psd)
206                 INIT_LIST_HEAD(&psd->clock_list);
207 }
208
209 /**
210  * pm_clk_create - Create and initialize a device's list of PM clocks.
211  * @dev: Device to create and initialize the list of PM clocks for.
212  *
213  * Allocate a struct pm_subsys_data object, initialize its lock and clock_list
214  * members and make the @dev's power.subsys_data field point to it.
215  */
216 int pm_clk_create(struct device *dev)
217 {
218         return dev_pm_get_subsys_data(dev);
219 }
220
221 /**
222  * pm_clk_destroy - Destroy a device's list of power management clocks.
223  * @dev: Device to destroy the list of PM clocks for.
224  *
225  * Clear the @dev's power.subsys_data field, remove the list of clock entries
226  * from the struct pm_subsys_data object pointed to by it before and free
227  * that object.
228  */
229 void pm_clk_destroy(struct device *dev)
230 {
231         struct pm_subsys_data *psd = dev_to_psd(dev);
232         struct pm_clock_entry *ce, *c;
233         struct list_head list;
234
235         if (!psd)
236                 return;
237
238         INIT_LIST_HEAD(&list);
239
240         spin_lock_irq(&psd->lock);
241
242         list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node)
243                 list_move(&ce->node, &list);
244
245         spin_unlock_irq(&psd->lock);
246
247         dev_pm_put_subsys_data(dev);
248
249         list_for_each_entry_safe_reverse(ce, c, &list, node) {
250                 list_del(&ce->node);
251                 __pm_clk_remove(ce);
252         }
253 }
254
255 /**
256  * pm_clk_suspend - Disable clocks in a device's PM clock list.
257  * @dev: Device to disable the clocks for.
258  */
259 int pm_clk_suspend(struct device *dev)
260 {
261         struct pm_subsys_data *psd = dev_to_psd(dev);
262         struct pm_clock_entry *ce;
263         unsigned long flags;
264
265         dev_dbg(dev, "%s()\n", __func__);
266
267         if (!psd)
268                 return 0;
269
270         spin_lock_irqsave(&psd->lock, flags);
271
272         list_for_each_entry_reverse(ce, &psd->clock_list, node) {
273                 if (ce->status < PCE_STATUS_ERROR) {
274                         if (ce->status == PCE_STATUS_ENABLED)
275                                 clk_disable(ce->clk);
276                         ce->status = PCE_STATUS_ACQUIRED;
277                 }
278         }
279
280         spin_unlock_irqrestore(&psd->lock, flags);
281
282         return 0;
283 }
284
285 /**
286  * pm_clk_resume - Enable clocks in a device's PM clock list.
287  * @dev: Device to enable the clocks for.
288  */
289 int pm_clk_resume(struct device *dev)
290 {
291         struct pm_subsys_data *psd = dev_to_psd(dev);
292         struct pm_clock_entry *ce;
293         unsigned long flags;
294
295         dev_dbg(dev, "%s()\n", __func__);
296
297         if (!psd)
298                 return 0;
299
300         spin_lock_irqsave(&psd->lock, flags);
301
302         list_for_each_entry(ce, &psd->clock_list, node)
303                 __pm_clk_enable(dev, ce);
304
305         spin_unlock_irqrestore(&psd->lock, flags);
306
307         return 0;
308 }
309
310 /**
311  * pm_clk_notify - Notify routine for device addition and removal.
312  * @nb: Notifier block object this function is a member of.
313  * @action: Operation being carried out by the caller.
314  * @data: Device the routine is being run for.
315  *
316  * For this function to work, @nb must be a member of an object of type
317  * struct pm_clk_notifier_block containing all of the requisite data.
318  * Specifically, the pm_domain member of that object is copied to the device's
319  * pm_domain field and its con_ids member is used to populate the device's list
320  * of PM clocks, depending on @action.
321  *
322  * If the device's pm_domain field is already populated with a value different
323  * from the one stored in the struct pm_clk_notifier_block object, the function
324  * does nothing.
325  */
326 static int pm_clk_notify(struct notifier_block *nb,
327                                  unsigned long action, void *data)
328 {
329         struct pm_clk_notifier_block *clknb;
330         struct device *dev = data;
331         char **con_id;
332         int error;
333
334         dev_dbg(dev, "%s() %ld\n", __func__, action);
335
336         clknb = container_of(nb, struct pm_clk_notifier_block, nb);
337
338         switch (action) {
339         case BUS_NOTIFY_ADD_DEVICE:
340                 if (dev->pm_domain)
341                         break;
342
343                 error = pm_clk_create(dev);
344                 if (error)
345                         break;
346
347                 dev->pm_domain = clknb->pm_domain;
348                 if (clknb->con_ids[0]) {
349                         for (con_id = clknb->con_ids; *con_id; con_id++)
350                                 pm_clk_add(dev, *con_id);
351                 } else {
352                         pm_clk_add(dev, NULL);
353                 }
354
355                 break;
356         case BUS_NOTIFY_DEL_DEVICE:
357                 if (dev->pm_domain != clknb->pm_domain)
358                         break;
359
360                 dev->pm_domain = NULL;
361                 pm_clk_destroy(dev);
362                 break;
363         }
364
365         return 0;
366 }
367
368 #else /* !CONFIG_PM */
369
370 /**
371  * enable_clock - Enable a device clock.
372  * @dev: Device whose clock is to be enabled.
373  * @con_id: Connection ID of the clock.
374  */
375 static void enable_clock(struct device *dev, const char *con_id)
376 {
377         struct clk *clk;
378
379         clk = clk_get(dev, con_id);
380         if (!IS_ERR(clk)) {
381                 clk_prepare_enable(clk);
382                 clk_put(clk);
383                 dev_info(dev, "Runtime PM disabled, clock forced on.\n");
384         }
385 }
386
387 /**
388  * disable_clock - Disable a device clock.
389  * @dev: Device whose clock is to be disabled.
390  * @con_id: Connection ID of the clock.
391  */
392 static void disable_clock(struct device *dev, const char *con_id)
393 {
394         struct clk *clk;
395
396         clk = clk_get(dev, con_id);
397         if (!IS_ERR(clk)) {
398                 clk_disable_unprepare(clk);
399                 clk_put(clk);
400                 dev_info(dev, "Runtime PM disabled, clock forced off.\n");
401         }
402 }
403
404 /**
405  * pm_clk_notify - Notify routine for device addition and removal.
406  * @nb: Notifier block object this function is a member of.
407  * @action: Operation being carried out by the caller.
408  * @data: Device the routine is being run for.
409  *
410  * For this function to work, @nb must be a member of an object of type
411  * struct pm_clk_notifier_block containing all of the requisite data.
412  * Specifically, the con_ids member of that object is used to enable or disable
413  * the device's clocks, depending on @action.
414  */
415 static int pm_clk_notify(struct notifier_block *nb,
416                                  unsigned long action, void *data)
417 {
418         struct pm_clk_notifier_block *clknb;
419         struct device *dev = data;
420         char **con_id;
421
422         dev_dbg(dev, "%s() %ld\n", __func__, action);
423
424         clknb = container_of(nb, struct pm_clk_notifier_block, nb);
425
426         switch (action) {
427         case BUS_NOTIFY_BIND_DRIVER:
428                 if (clknb->con_ids[0]) {
429                         for (con_id = clknb->con_ids; *con_id; con_id++)
430                                 enable_clock(dev, *con_id);
431                 } else {
432                         enable_clock(dev, NULL);
433                 }
434                 break;
435         case BUS_NOTIFY_UNBOUND_DRIVER:
436                 if (clknb->con_ids[0]) {
437                         for (con_id = clknb->con_ids; *con_id; con_id++)
438                                 disable_clock(dev, *con_id);
439                 } else {
440                         disable_clock(dev, NULL);
441                 }
442                 break;
443         }
444
445         return 0;
446 }
447
448 #endif /* !CONFIG_PM */
449
450 /**
451  * pm_clk_add_notifier - Add bus type notifier for power management clocks.
452  * @bus: Bus type to add the notifier to.
453  * @clknb: Notifier to be added to the given bus type.
454  *
455  * The nb member of @clknb is not expected to be initialized and its
456  * notifier_call member will be replaced with pm_clk_notify().  However,
457  * the remaining members of @clknb should be populated prior to calling this
458  * routine.
459  */
460 void pm_clk_add_notifier(struct bus_type *bus,
461                                  struct pm_clk_notifier_block *clknb)
462 {
463         if (!bus || !clknb)
464                 return;
465
466         clknb->nb.notifier_call = pm_clk_notify;
467         bus_register_notifier(bus, &clknb->nb);
468 }