1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#undef DEBUG
22
23#include <linux/kernel.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/clk.h>
29#include <linux/clkdev.h>
30#include <linux/pm_domain.h>
31#include <linux/pm_runtime.h>
32#include <linux/of.h>
33#include <linux/of_address.h>
34#include <linux/of_irq.h>
35#include <linux/notifier.h>
36
37#include "common.h"
38#include "soc.h"
39#include "omap_device.h"
40#include "omap_hwmod.h"
41
42
43
44static void _add_clkdev(struct omap_device *od, const char *clk_alias,
45 const char *clk_name)
46{
47 struct clk *r;
48 int rc;
49
50 if (!clk_alias || !clk_name)
51 return;
52
53 dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name);
54
55 r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias);
56 if (!IS_ERR(r)) {
57 dev_dbg(&od->pdev->dev,
58 "alias %s already exists\n", clk_alias);
59 clk_put(r);
60 return;
61 }
62
63 r = clk_get_sys(NULL, clk_name);
64
65 if (IS_ERR(r)) {
66 struct of_phandle_args clkspec;
67
68 clkspec.np = of_find_node_by_name(NULL, clk_name);
69
70 r = of_clk_get_from_provider(&clkspec);
71
72 rc = clk_register_clkdev(r, clk_alias,
73 dev_name(&od->pdev->dev));
74 } else {
75 rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev),
76 clk_name, NULL);
77 }
78
79 if (rc) {
80 if (rc == -ENODEV || rc == -ENOMEM)
81 dev_err(&od->pdev->dev,
82 "clkdev_alloc for %s failed\n", clk_alias);
83 else
84 dev_err(&od->pdev->dev,
85 "clk_get for %s failed\n", clk_name);
86 }
87}
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108static void _add_hwmod_clocks_clkdev(struct omap_device *od,
109 struct omap_hwmod *oh)
110{
111 int i;
112
113 _add_clkdev(od, "fck", oh->main_clk);
114
115 for (i = 0; i < oh->opt_clks_cnt; i++)
116 _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
117}
118
119
120
121
122
123
124
125
126
127
128static int omap_device_build_from_dt(struct platform_device *pdev)
129{
130 struct omap_hwmod **hwmods;
131 struct omap_device *od;
132 struct omap_hwmod *oh;
133 struct device_node *node = pdev->dev.of_node;
134 struct resource res;
135 const char *oh_name;
136 int oh_cnt, i, ret = 0;
137 bool device_active = false, skip_pm_domain = false;
138
139 oh_cnt = of_property_count_strings(node, "ti,hwmods");
140 if (oh_cnt <= 0) {
141 dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n");
142 return -ENODEV;
143 }
144
145
146 ret = of_property_read_string_index(node, "ti,hwmods", 0, &oh_name);
147 if (!ret && (!strncmp("dma_system", oh_name, 10) ||
148 !strncmp("dma", oh_name, 3)))
149 skip_pm_domain = true;
150
151
152 if (!skip_pm_domain &&
153 !omap_hwmod_parse_module_range(NULL, node, &res))
154 return -ENODEV;
155
156 hwmods = kcalloc(oh_cnt, sizeof(struct omap_hwmod *), GFP_KERNEL);
157 if (!hwmods) {
158 ret = -ENOMEM;
159 goto odbfd_exit;
160 }
161
162 for (i = 0; i < oh_cnt; i++) {
163 of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
164 oh = omap_hwmod_lookup(oh_name);
165 if (!oh) {
166 dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
167 oh_name);
168 ret = -EINVAL;
169 goto odbfd_exit1;
170 }
171 hwmods[i] = oh;
172 if (oh->flags & HWMOD_INIT_NO_IDLE)
173 device_active = true;
174 }
175
176 od = omap_device_alloc(pdev, hwmods, oh_cnt);
177 if (IS_ERR(od)) {
178 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
179 oh_name);
180 ret = PTR_ERR(od);
181 goto odbfd_exit1;
182 }
183
184
185 for (i = 0; i < pdev->num_resources; i++) {
186 struct resource *r = &pdev->resource[i];
187
188 if (r->name == NULL)
189 r->name = dev_name(&pdev->dev);
190 }
191
192 if (!skip_pm_domain) {
193 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
194 if (device_active) {
195 omap_device_enable(pdev);
196 pm_runtime_set_active(&pdev->dev);
197 }
198 }
199
200odbfd_exit1:
201 kfree(hwmods);
202odbfd_exit:
203
204 if (ret)
205 dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain);
206
207 return ret;
208}
209
210static int _omap_device_notifier_call(struct notifier_block *nb,
211 unsigned long event, void *dev)
212{
213 struct platform_device *pdev = to_platform_device(dev);
214 struct omap_device *od;
215 int err;
216
217 switch (event) {
218 case BUS_NOTIFY_REMOVED_DEVICE:
219 if (pdev->archdata.od)
220 omap_device_delete(pdev->archdata.od);
221 break;
222 case BUS_NOTIFY_UNBOUND_DRIVER:
223 od = to_omap_device(pdev);
224 if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) {
225 dev_info(dev, "enabled after unload, idling\n");
226 err = omap_device_idle(pdev);
227 if (err)
228 dev_err(dev, "failed to idle\n");
229 }
230 break;
231 case BUS_NOTIFY_BIND_DRIVER:
232 od = to_omap_device(pdev);
233 if (od) {
234 od->_driver_status = BUS_NOTIFY_BIND_DRIVER;
235 if (od->_state == OMAP_DEVICE_STATE_ENABLED &&
236 pm_runtime_status_suspended(dev)) {
237 pm_runtime_set_active(dev);
238 }
239 }
240 break;
241 case BUS_NOTIFY_ADD_DEVICE:
242 if (pdev->dev.of_node)
243 omap_device_build_from_dt(pdev);
244 omap_auxdata_legacy_init(dev);
245 fallthrough;
246 default:
247 od = to_omap_device(pdev);
248 if (od)
249 od->_driver_status = event;
250 }
251
252 return NOTIFY_DONE;
253}
254
255
256
257
258
259
260
261static int _omap_device_enable_hwmods(struct omap_device *od)
262{
263 int ret = 0;
264 int i;
265
266 for (i = 0; i < od->hwmods_cnt; i++)
267 ret |= omap_hwmod_enable(od->hwmods[i]);
268
269 return ret;
270}
271
272
273
274
275
276
277
278static int _omap_device_idle_hwmods(struct omap_device *od)
279{
280 int ret = 0;
281 int i;
282
283 for (i = 0; i < od->hwmods_cnt; i++)
284 ret |= omap_hwmod_idle(od->hwmods[i]);
285
286 return ret;
287}
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306int omap_device_get_context_loss_count(struct platform_device *pdev)
307{
308 struct omap_device *od;
309 u32 ret = 0;
310
311 od = to_omap_device(pdev);
312
313 if (od->hwmods_cnt)
314 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
315
316 return ret;
317}
318
319
320
321
322
323
324
325
326
327
328
329
330struct omap_device *omap_device_alloc(struct platform_device *pdev,
331 struct omap_hwmod **ohs, int oh_cnt)
332{
333 int ret = -ENOMEM;
334 struct omap_device *od;
335 int i;
336 struct omap_hwmod **hwmods;
337
338 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
339 if (!od)
340 goto oda_exit1;
341
342 od->hwmods_cnt = oh_cnt;
343
344 hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
345 if (!hwmods)
346 goto oda_exit2;
347
348 od->hwmods = hwmods;
349 od->pdev = pdev;
350 pdev->archdata.od = od;
351
352 for (i = 0; i < oh_cnt; i++) {
353 hwmods[i]->od = od;
354 _add_hwmod_clocks_clkdev(od, hwmods[i]);
355 }
356
357 return od;
358
359oda_exit2:
360 kfree(od);
361oda_exit1:
362 dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
363
364 return ERR_PTR(ret);
365}
366
367void omap_device_delete(struct omap_device *od)
368{
369 if (!od)
370 return;
371
372 od->pdev->archdata.od = NULL;
373 kfree(od->hwmods);
374 kfree(od);
375}
376
377#ifdef CONFIG_PM
378static int _od_runtime_suspend(struct device *dev)
379{
380 struct platform_device *pdev = to_platform_device(dev);
381 int ret;
382
383 ret = pm_generic_runtime_suspend(dev);
384 if (ret)
385 return ret;
386
387 return omap_device_idle(pdev);
388}
389
390static int _od_runtime_resume(struct device *dev)
391{
392 struct platform_device *pdev = to_platform_device(dev);
393 int ret;
394
395 ret = omap_device_enable(pdev);
396 if (ret) {
397 dev_err(dev, "use pm_runtime_put_sync_suspend() in driver?\n");
398 return ret;
399 }
400
401 return pm_generic_runtime_resume(dev);
402}
403
404static int _od_fail_runtime_suspend(struct device *dev)
405{
406 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
407 return -ENODEV;
408}
409
410static int _od_fail_runtime_resume(struct device *dev)
411{
412 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
413 return -ENODEV;
414}
415
416#endif
417
418#ifdef CONFIG_SUSPEND
419static int _od_suspend_noirq(struct device *dev)
420{
421 struct platform_device *pdev = to_platform_device(dev);
422 struct omap_device *od = to_omap_device(pdev);
423 int ret;
424
425
426 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER)
427 return 0;
428
429 ret = pm_generic_suspend_noirq(dev);
430
431 if (!ret && !pm_runtime_status_suspended(dev)) {
432 if (pm_generic_runtime_suspend(dev) == 0) {
433 omap_device_idle(pdev);
434 od->flags |= OMAP_DEVICE_SUSPENDED;
435 }
436 }
437
438 return ret;
439}
440
441static int _od_resume_noirq(struct device *dev)
442{
443 struct platform_device *pdev = to_platform_device(dev);
444 struct omap_device *od = to_omap_device(pdev);
445
446 if (od->flags & OMAP_DEVICE_SUSPENDED) {
447 od->flags &= ~OMAP_DEVICE_SUSPENDED;
448 omap_device_enable(pdev);
449 pm_generic_runtime_resume(dev);
450 }
451
452 return pm_generic_resume_noirq(dev);
453}
454#else
455#define _od_suspend_noirq NULL
456#define _od_resume_noirq NULL
457#endif
458
459struct dev_pm_domain omap_device_fail_pm_domain = {
460 .ops = {
461 SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend,
462 _od_fail_runtime_resume, NULL)
463 }
464};
465
466struct dev_pm_domain omap_device_pm_domain = {
467 .ops = {
468 SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
469 NULL)
470 USE_PLATFORM_PM_SLEEP_OPS
471 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq,
472 _od_resume_noirq)
473 }
474};
475
476
477
478
479
480
481
482
483
484int omap_device_register(struct platform_device *pdev)
485{
486 pr_debug("omap_device: %s: registering\n", pdev->name);
487
488 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
489 return platform_device_add(pdev);
490}
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507int omap_device_enable(struct platform_device *pdev)
508{
509 int ret;
510 struct omap_device *od;
511
512 od = to_omap_device(pdev);
513
514 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
515 dev_warn(&pdev->dev,
516 "omap_device: %s() called from invalid state %d\n",
517 __func__, od->_state);
518 return -EINVAL;
519 }
520
521 ret = _omap_device_enable_hwmods(od);
522
523 if (ret == 0)
524 od->_state = OMAP_DEVICE_STATE_ENABLED;
525
526 return ret;
527}
528
529
530
531
532
533
534
535
536
537
538int omap_device_idle(struct platform_device *pdev)
539{
540 int ret;
541 struct omap_device *od;
542
543 od = to_omap_device(pdev);
544
545 if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
546 dev_warn(&pdev->dev,
547 "omap_device: %s() called from invalid state %d\n",
548 __func__, od->_state);
549 return -EINVAL;
550 }
551
552 ret = _omap_device_idle_hwmods(od);
553
554 if (ret == 0)
555 od->_state = OMAP_DEVICE_STATE_IDLE;
556
557 return ret;
558}
559
560
561
562
563
564
565
566
567
568
569
570
571
572int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
573{
574 struct omap_device *od = to_omap_device(pdev);
575 int ret = 0;
576 int i;
577
578 for (i = 0; i < od->hwmods_cnt; i++) {
579 ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
580 if (ret)
581 break;
582 }
583
584 return ret;
585}
586
587
588
589
590
591
592
593
594
595
596
597
598
599int omap_device_deassert_hardreset(struct platform_device *pdev,
600 const char *name)
601{
602 struct omap_device *od = to_omap_device(pdev);
603 int ret = 0;
604 int i;
605
606 for (i = 0; i < od->hwmods_cnt; i++) {
607 ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
608 if (ret)
609 break;
610 }
611
612 return ret;
613}
614
615
616
617
618
619
620
621
622
623struct device *omap_device_get_by_hwmod_name(const char *oh_name)
624{
625 struct omap_hwmod *oh;
626
627 if (!oh_name) {
628 WARN(1, "%s: no hwmod name!\n", __func__);
629 return ERR_PTR(-EINVAL);
630 }
631
632 oh = omap_hwmod_lookup(oh_name);
633 if (!oh) {
634 WARN(1, "%s: no hwmod for %s\n", __func__,
635 oh_name);
636 return ERR_PTR(-ENODEV);
637 }
638 if (!oh->od) {
639 WARN(1, "%s: no omap_device for %s\n", __func__,
640 oh_name);
641 return ERR_PTR(-ENODEV);
642 }
643
644 return &oh->od->pdev->dev;
645}
646
647static struct notifier_block platform_nb = {
648 .notifier_call = _omap_device_notifier_call,
649};
650
651static int __init omap_device_init(void)
652{
653 bus_register_notifier(&platform_bus_type, &platform_nb);
654 return 0;
655}
656omap_postcore_initcall(omap_device_init);
657
658
659
660
661
662
663
664
665
666static int __init omap_device_late_idle(struct device *dev, void *data)
667{
668 struct platform_device *pdev = to_platform_device(dev);
669 struct omap_device *od = to_omap_device(pdev);
670 int i;
671
672 if (!od)
673 return 0;
674
675
676
677
678
679
680
681
682
683
684 for (i = 0; i < od->hwmods_cnt; i++)
685 if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
686 return 0;
687
688 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
689 od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
690 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
691 dev_warn(dev, "%s: enabled but no driver. Idling\n",
692 __func__);
693 omap_device_idle(pdev);
694 }
695 }
696
697 return 0;
698}
699
700static int __init omap_device_late_init(void)
701{
702 bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
703
704 return 0;
705}
706omap_late_initcall_sync(omap_device_late_init);
707