xref: /openbmc/linux/drivers/base/power/clock_ops.c (revision be709d48)
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 #include <linux/pm_domain.h>
19 #include <linux/pm_runtime.h>
20 
21 #ifdef CONFIG_PM_CLK
22 
23 enum pce_status {
24 	PCE_STATUS_NONE = 0,
25 	PCE_STATUS_ACQUIRED,
26 	PCE_STATUS_ENABLED,
27 	PCE_STATUS_ERROR,
28 };
29 
30 struct pm_clock_entry {
31 	struct list_head node;
32 	char *con_id;
33 	struct clk *clk;
34 	enum pce_status status;
35 };
36 
37 /**
38  * pm_clk_enable - Enable a clock, reporting any errors
39  * @dev: The device for the given clock
40  * @ce: PM clock entry corresponding to the clock.
41  */
42 static inline void __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce)
43 {
44 	int ret;
45 
46 	if (ce->status < PCE_STATUS_ERROR) {
47 		ret = clk_enable(ce->clk);
48 		if (!ret)
49 			ce->status = PCE_STATUS_ENABLED;
50 		else
51 			dev_err(dev, "%s: failed to enable clk %p, error %d\n",
52 				__func__, ce->clk, ret);
53 	}
54 }
55 
56 /**
57  * pm_clk_acquire - Acquire a device clock.
58  * @dev: Device whose clock is to be acquired.
59  * @ce: PM clock entry corresponding to the clock.
60  */
61 static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
62 {
63 	if (!ce->clk)
64 		ce->clk = clk_get(dev, ce->con_id);
65 	if (IS_ERR(ce->clk)) {
66 		ce->status = PCE_STATUS_ERROR;
67 	} else {
68 		if (clk_prepare(ce->clk)) {
69 			ce->status = PCE_STATUS_ERROR;
70 			dev_err(dev, "clk_prepare() failed\n");
71 		} else {
72 			ce->status = PCE_STATUS_ACQUIRED;
73 			dev_dbg(dev,
74 				"Clock %pC con_id %s managed by runtime PM.\n",
75 				ce->clk, ce->con_id);
76 		}
77 	}
78 }
79 
80 static int __pm_clk_add(struct device *dev, const char *con_id,
81 			struct clk *clk)
82 {
83 	struct pm_subsys_data *psd = dev_to_psd(dev);
84 	struct pm_clock_entry *ce;
85 
86 	if (!psd)
87 		return -EINVAL;
88 
89 	ce = kzalloc(sizeof(*ce), GFP_KERNEL);
90 	if (!ce)
91 		return -ENOMEM;
92 
93 	if (con_id) {
94 		ce->con_id = kstrdup(con_id, GFP_KERNEL);
95 		if (!ce->con_id) {
96 			dev_err(dev,
97 				"Not enough memory for clock connection ID.\n");
98 			kfree(ce);
99 			return -ENOMEM;
100 		}
101 	} else {
102 		if (IS_ERR(clk)) {
103 			kfree(ce);
104 			return -ENOENT;
105 		}
106 		ce->clk = clk;
107 	}
108 
109 	pm_clk_acquire(dev, ce);
110 
111 	spin_lock_irq(&psd->lock);
112 	list_add_tail(&ce->node, &psd->clock_list);
113 	spin_unlock_irq(&psd->lock);
114 	return 0;
115 }
116 
117 /**
118  * pm_clk_add - Start using a device clock for power management.
119  * @dev: Device whose clock is going to be used for power management.
120  * @con_id: Connection ID of the clock.
121  *
122  * Add the clock represented by @con_id to the list of clocks used for
123  * the power management of @dev.
124  */
125 int pm_clk_add(struct device *dev, const char *con_id)
126 {
127 	return __pm_clk_add(dev, con_id, NULL);
128 }
129 EXPORT_SYMBOL_GPL(pm_clk_add);
130 
131 /**
132  * pm_clk_add_clk - Start using a device clock for power management.
133  * @dev: Device whose clock is going to be used for power management.
134  * @clk: Clock pointer
135  *
136  * Add the clock to the list of clocks used for the power management of @dev.
137  * The power-management code will take control of the clock reference, so
138  * callers should not call clk_put() on @clk after this function sucessfully
139  * returned.
140  */
141 int pm_clk_add_clk(struct device *dev, struct clk *clk)
142 {
143 	return __pm_clk_add(dev, NULL, clk);
144 }
145 EXPORT_SYMBOL_GPL(pm_clk_add_clk);
146 
147 
148 /**
149  * of_pm_clk_add_clk - Start using a device clock for power management.
150  * @dev: Device whose clock is going to be used for power management.
151  * @name: Name of clock that is going to be used for power management.
152  *
153  * Add the clock described in the 'clocks' device-tree node that matches
154  * with the 'name' provided, to the list of clocks used for the power
155  * management of @dev. On success, returns 0. Returns a negative error
156  * code if the clock is not found or cannot be added.
157  */
158 int of_pm_clk_add_clk(struct device *dev, const char *name)
159 {
160 	struct clk *clk;
161 	int ret;
162 
163 	if (!dev || !dev->of_node || !name)
164 		return -EINVAL;
165 
166 	clk = of_clk_get_by_name(dev->of_node, name);
167 	if (IS_ERR(clk))
168 		return PTR_ERR(clk);
169 
170 	ret = pm_clk_add_clk(dev, clk);
171 	if (ret) {
172 		clk_put(clk);
173 		return ret;
174 	}
175 
176 	return 0;
177 }
178 EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
179 
180 /**
181  * of_pm_clk_add_clks - Start using device clock(s) for power management.
182  * @dev: Device whose clock(s) is going to be used for power management.
183  *
184  * Add a series of clocks described in the 'clocks' device-tree node for
185  * a device to the list of clocks used for the power management of @dev.
186  * On success, returns the number of clocks added. Returns a negative
187  * error code if there are no clocks in the device node for the device
188  * or if adding a clock fails.
189  */
190 int of_pm_clk_add_clks(struct device *dev)
191 {
192 	struct clk **clks;
193 	int i, count;
194 	int ret;
195 
196 	if (!dev || !dev->of_node)
197 		return -EINVAL;
198 
199 	count = of_count_phandle_with_args(dev->of_node, "clocks",
200 					   "#clock-cells");
201 	if (count <= 0)
202 		return -ENODEV;
203 
204 	clks = kcalloc(count, sizeof(*clks), GFP_KERNEL);
205 	if (!clks)
206 		return -ENOMEM;
207 
208 	for (i = 0; i < count; i++) {
209 		clks[i] = of_clk_get(dev->of_node, i);
210 		if (IS_ERR(clks[i])) {
211 			ret = PTR_ERR(clks[i]);
212 			goto error;
213 		}
214 
215 		ret = pm_clk_add_clk(dev, clks[i]);
216 		if (ret) {
217 			clk_put(clks[i]);
218 			goto error;
219 		}
220 	}
221 
222 	kfree(clks);
223 
224 	return i;
225 
226 error:
227 	while (i--)
228 		pm_clk_remove_clk(dev, clks[i]);
229 
230 	kfree(clks);
231 
232 	return ret;
233 }
234 EXPORT_SYMBOL_GPL(of_pm_clk_add_clks);
235 
236 /**
237  * __pm_clk_remove - Destroy PM clock entry.
238  * @ce: PM clock entry to destroy.
239  */
240 static void __pm_clk_remove(struct pm_clock_entry *ce)
241 {
242 	if (!ce)
243 		return;
244 
245 	if (ce->status < PCE_STATUS_ERROR) {
246 		if (ce->status == PCE_STATUS_ENABLED)
247 			clk_disable(ce->clk);
248 
249 		if (ce->status >= PCE_STATUS_ACQUIRED) {
250 			clk_unprepare(ce->clk);
251 			clk_put(ce->clk);
252 		}
253 	}
254 
255 	kfree(ce->con_id);
256 	kfree(ce);
257 }
258 
259 /**
260  * pm_clk_remove - Stop using a device clock for power management.
261  * @dev: Device whose clock should not be used for PM any more.
262  * @con_id: Connection ID of the clock.
263  *
264  * Remove the clock represented by @con_id from the list of clocks used for
265  * the power management of @dev.
266  */
267 void pm_clk_remove(struct device *dev, const char *con_id)
268 {
269 	struct pm_subsys_data *psd = dev_to_psd(dev);
270 	struct pm_clock_entry *ce;
271 
272 	if (!psd)
273 		return;
274 
275 	spin_lock_irq(&psd->lock);
276 
277 	list_for_each_entry(ce, &psd->clock_list, node) {
278 		if (!con_id && !ce->con_id)
279 			goto remove;
280 		else if (!con_id || !ce->con_id)
281 			continue;
282 		else if (!strcmp(con_id, ce->con_id))
283 			goto remove;
284 	}
285 
286 	spin_unlock_irq(&psd->lock);
287 	return;
288 
289  remove:
290 	list_del(&ce->node);
291 	spin_unlock_irq(&psd->lock);
292 
293 	__pm_clk_remove(ce);
294 }
295 EXPORT_SYMBOL_GPL(pm_clk_remove);
296 
297 /**
298  * pm_clk_remove_clk - Stop using a device clock for power management.
299  * @dev: Device whose clock should not be used for PM any more.
300  * @clk: Clock pointer
301  *
302  * Remove the clock pointed to by @clk from the list of clocks used for
303  * the power management of @dev.
304  */
305 void pm_clk_remove_clk(struct device *dev, struct clk *clk)
306 {
307 	struct pm_subsys_data *psd = dev_to_psd(dev);
308 	struct pm_clock_entry *ce;
309 
310 	if (!psd || !clk)
311 		return;
312 
313 	spin_lock_irq(&psd->lock);
314 
315 	list_for_each_entry(ce, &psd->clock_list, node) {
316 		if (clk == ce->clk)
317 			goto remove;
318 	}
319 
320 	spin_unlock_irq(&psd->lock);
321 	return;
322 
323  remove:
324 	list_del(&ce->node);
325 	spin_unlock_irq(&psd->lock);
326 
327 	__pm_clk_remove(ce);
328 }
329 EXPORT_SYMBOL_GPL(pm_clk_remove_clk);
330 
331 /**
332  * pm_clk_init - Initialize a device's list of power management clocks.
333  * @dev: Device to initialize the list of PM clocks for.
334  *
335  * Initialize the lock and clock_list members of the device's pm_subsys_data
336  * object.
337  */
338 void pm_clk_init(struct device *dev)
339 {
340 	struct pm_subsys_data *psd = dev_to_psd(dev);
341 	if (psd)
342 		INIT_LIST_HEAD(&psd->clock_list);
343 }
344 EXPORT_SYMBOL_GPL(pm_clk_init);
345 
346 /**
347  * pm_clk_create - Create and initialize a device's list of PM clocks.
348  * @dev: Device to create and initialize the list of PM clocks for.
349  *
350  * Allocate a struct pm_subsys_data object, initialize its lock and clock_list
351  * members and make the @dev's power.subsys_data field point to it.
352  */
353 int pm_clk_create(struct device *dev)
354 {
355 	return dev_pm_get_subsys_data(dev);
356 }
357 EXPORT_SYMBOL_GPL(pm_clk_create);
358 
359 /**
360  * pm_clk_destroy - Destroy a device's list of power management clocks.
361  * @dev: Device to destroy the list of PM clocks for.
362  *
363  * Clear the @dev's power.subsys_data field, remove the list of clock entries
364  * from the struct pm_subsys_data object pointed to by it before and free
365  * that object.
366  */
367 void pm_clk_destroy(struct device *dev)
368 {
369 	struct pm_subsys_data *psd = dev_to_psd(dev);
370 	struct pm_clock_entry *ce, *c;
371 	struct list_head list;
372 
373 	if (!psd)
374 		return;
375 
376 	INIT_LIST_HEAD(&list);
377 
378 	spin_lock_irq(&psd->lock);
379 
380 	list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node)
381 		list_move(&ce->node, &list);
382 
383 	spin_unlock_irq(&psd->lock);
384 
385 	dev_pm_put_subsys_data(dev);
386 
387 	list_for_each_entry_safe_reverse(ce, c, &list, node) {
388 		list_del(&ce->node);
389 		__pm_clk_remove(ce);
390 	}
391 }
392 EXPORT_SYMBOL_GPL(pm_clk_destroy);
393 
394 /**
395  * pm_clk_suspend - Disable clocks in a device's PM clock list.
396  * @dev: Device to disable the clocks for.
397  */
398 int pm_clk_suspend(struct device *dev)
399 {
400 	struct pm_subsys_data *psd = dev_to_psd(dev);
401 	struct pm_clock_entry *ce;
402 	unsigned long flags;
403 
404 	dev_dbg(dev, "%s()\n", __func__);
405 
406 	if (!psd)
407 		return 0;
408 
409 	spin_lock_irqsave(&psd->lock, flags);
410 
411 	list_for_each_entry_reverse(ce, &psd->clock_list, node) {
412 		if (ce->status < PCE_STATUS_ERROR) {
413 			if (ce->status == PCE_STATUS_ENABLED)
414 				clk_disable(ce->clk);
415 			ce->status = PCE_STATUS_ACQUIRED;
416 		}
417 	}
418 
419 	spin_unlock_irqrestore(&psd->lock, flags);
420 
421 	return 0;
422 }
423 EXPORT_SYMBOL_GPL(pm_clk_suspend);
424 
425 /**
426  * pm_clk_resume - Enable clocks in a device's PM clock list.
427  * @dev: Device to enable the clocks for.
428  */
429 int pm_clk_resume(struct device *dev)
430 {
431 	struct pm_subsys_data *psd = dev_to_psd(dev);
432 	struct pm_clock_entry *ce;
433 	unsigned long flags;
434 
435 	dev_dbg(dev, "%s()\n", __func__);
436 
437 	if (!psd)
438 		return 0;
439 
440 	spin_lock_irqsave(&psd->lock, flags);
441 
442 	list_for_each_entry(ce, &psd->clock_list, node)
443 		__pm_clk_enable(dev, ce);
444 
445 	spin_unlock_irqrestore(&psd->lock, flags);
446 
447 	return 0;
448 }
449 EXPORT_SYMBOL_GPL(pm_clk_resume);
450 
451 /**
452  * pm_clk_notify - Notify routine for device addition and removal.
453  * @nb: Notifier block object this function is a member of.
454  * @action: Operation being carried out by the caller.
455  * @data: Device the routine is being run for.
456  *
457  * For this function to work, @nb must be a member of an object of type
458  * struct pm_clk_notifier_block containing all of the requisite data.
459  * Specifically, the pm_domain member of that object is copied to the device's
460  * pm_domain field and its con_ids member is used to populate the device's list
461  * of PM clocks, depending on @action.
462  *
463  * If the device's pm_domain field is already populated with a value different
464  * from the one stored in the struct pm_clk_notifier_block object, the function
465  * does nothing.
466  */
467 static int pm_clk_notify(struct notifier_block *nb,
468 				 unsigned long action, void *data)
469 {
470 	struct pm_clk_notifier_block *clknb;
471 	struct device *dev = data;
472 	char **con_id;
473 	int error;
474 
475 	dev_dbg(dev, "%s() %ld\n", __func__, action);
476 
477 	clknb = container_of(nb, struct pm_clk_notifier_block, nb);
478 
479 	switch (action) {
480 	case BUS_NOTIFY_ADD_DEVICE:
481 		if (dev->pm_domain)
482 			break;
483 
484 		error = pm_clk_create(dev);
485 		if (error)
486 			break;
487 
488 		dev_pm_domain_set(dev, clknb->pm_domain);
489 		if (clknb->con_ids[0]) {
490 			for (con_id = clknb->con_ids; *con_id; con_id++)
491 				pm_clk_add(dev, *con_id);
492 		} else {
493 			pm_clk_add(dev, NULL);
494 		}
495 
496 		break;
497 	case BUS_NOTIFY_DEL_DEVICE:
498 		if (dev->pm_domain != clknb->pm_domain)
499 			break;
500 
501 		dev_pm_domain_set(dev, NULL);
502 		pm_clk_destroy(dev);
503 		break;
504 	}
505 
506 	return 0;
507 }
508 
509 int pm_clk_runtime_suspend(struct device *dev)
510 {
511 	int ret;
512 
513 	dev_dbg(dev, "%s\n", __func__);
514 
515 	ret = pm_generic_runtime_suspend(dev);
516 	if (ret) {
517 		dev_err(dev, "failed to suspend device\n");
518 		return ret;
519 	}
520 
521 	ret = pm_clk_suspend(dev);
522 	if (ret) {
523 		dev_err(dev, "failed to suspend clock\n");
524 		pm_generic_runtime_resume(dev);
525 		return ret;
526 	}
527 
528 	return 0;
529 }
530 EXPORT_SYMBOL_GPL(pm_clk_runtime_suspend);
531 
532 int pm_clk_runtime_resume(struct device *dev)
533 {
534 	int ret;
535 
536 	dev_dbg(dev, "%s\n", __func__);
537 
538 	ret = pm_clk_resume(dev);
539 	if (ret) {
540 		dev_err(dev, "failed to resume clock\n");
541 		return ret;
542 	}
543 
544 	return pm_generic_runtime_resume(dev);
545 }
546 EXPORT_SYMBOL_GPL(pm_clk_runtime_resume);
547 
548 #else /* !CONFIG_PM_CLK */
549 
550 /**
551  * enable_clock - Enable a device clock.
552  * @dev: Device whose clock is to be enabled.
553  * @con_id: Connection ID of the clock.
554  */
555 static void enable_clock(struct device *dev, const char *con_id)
556 {
557 	struct clk *clk;
558 
559 	clk = clk_get(dev, con_id);
560 	if (!IS_ERR(clk)) {
561 		clk_prepare_enable(clk);
562 		clk_put(clk);
563 		dev_info(dev, "Runtime PM disabled, clock forced on.\n");
564 	}
565 }
566 
567 /**
568  * disable_clock - Disable a device clock.
569  * @dev: Device whose clock is to be disabled.
570  * @con_id: Connection ID of the clock.
571  */
572 static void disable_clock(struct device *dev, const char *con_id)
573 {
574 	struct clk *clk;
575 
576 	clk = clk_get(dev, con_id);
577 	if (!IS_ERR(clk)) {
578 		clk_disable_unprepare(clk);
579 		clk_put(clk);
580 		dev_info(dev, "Runtime PM disabled, clock forced off.\n");
581 	}
582 }
583 
584 /**
585  * pm_clk_notify - Notify routine for device addition and removal.
586  * @nb: Notifier block object this function is a member of.
587  * @action: Operation being carried out by the caller.
588  * @data: Device the routine is being run for.
589  *
590  * For this function to work, @nb must be a member of an object of type
591  * struct pm_clk_notifier_block containing all of the requisite data.
592  * Specifically, the con_ids member of that object is used to enable or disable
593  * the device's clocks, depending on @action.
594  */
595 static int pm_clk_notify(struct notifier_block *nb,
596 				 unsigned long action, void *data)
597 {
598 	struct pm_clk_notifier_block *clknb;
599 	struct device *dev = data;
600 	char **con_id;
601 
602 	dev_dbg(dev, "%s() %ld\n", __func__, action);
603 
604 	clknb = container_of(nb, struct pm_clk_notifier_block, nb);
605 
606 	switch (action) {
607 	case BUS_NOTIFY_BIND_DRIVER:
608 		if (clknb->con_ids[0]) {
609 			for (con_id = clknb->con_ids; *con_id; con_id++)
610 				enable_clock(dev, *con_id);
611 		} else {
612 			enable_clock(dev, NULL);
613 		}
614 		break;
615 	case BUS_NOTIFY_DRIVER_NOT_BOUND:
616 	case BUS_NOTIFY_UNBOUND_DRIVER:
617 		if (clknb->con_ids[0]) {
618 			for (con_id = clknb->con_ids; *con_id; con_id++)
619 				disable_clock(dev, *con_id);
620 		} else {
621 			disable_clock(dev, NULL);
622 		}
623 		break;
624 	}
625 
626 	return 0;
627 }
628 
629 #endif /* !CONFIG_PM_CLK */
630 
631 /**
632  * pm_clk_add_notifier - Add bus type notifier for power management clocks.
633  * @bus: Bus type to add the notifier to.
634  * @clknb: Notifier to be added to the given bus type.
635  *
636  * The nb member of @clknb is not expected to be initialized and its
637  * notifier_call member will be replaced with pm_clk_notify().  However,
638  * the remaining members of @clknb should be populated prior to calling this
639  * routine.
640  */
641 void pm_clk_add_notifier(struct bus_type *bus,
642 				 struct pm_clk_notifier_block *clknb)
643 {
644 	if (!bus || !clknb)
645 		return;
646 
647 	clknb->nb.notifier_call = pm_clk_notify;
648 	bus_register_notifier(bus, &clknb->nb);
649 }
650 EXPORT_SYMBOL_GPL(pm_clk_add_notifier);
651