1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#undef DEBUG
27
28#include <linux/kernel.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/err.h>
32#include <linux/io.h>
33#include <linux/clk.h>
34#include <linux/clkdev.h>
35#include <linux/pm_domain.h>
36#include <linux/pm_runtime.h>
37#include <linux/of.h>
38#include <linux/notifier.h>
39
40#include "common.h"
41#include "soc.h"
42#include "omap_device.h"
43#include "omap_hwmod.h"
44
45
46
47static void _add_clkdev(struct omap_device *od, const char *clk_alias,
48 const char *clk_name)
49{
50 struct clk *r;
51 int rc;
52
53 if (!clk_alias || !clk_name)
54 return;
55
56 dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name);
57
58 r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias);
59 if (!IS_ERR(r)) {
60 dev_dbg(&od->pdev->dev,
61 "alias %s already exists\n", clk_alias);
62 clk_put(r);
63 return;
64 }
65
66 r = clk_get_sys(NULL, clk_name);
67
68 if (IS_ERR(r)) {
69 struct of_phandle_args clkspec;
70
71 clkspec.np = of_find_node_by_name(NULL, clk_name);
72
73 r = of_clk_get_from_provider(&clkspec);
74
75 rc = clk_register_clkdev(r, clk_alias,
76 dev_name(&od->pdev->dev));
77 } else {
78 rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev),
79 clk_name, NULL);
80 }
81
82 if (rc) {
83 if (rc == -ENODEV || rc == -ENOMEM)
84 dev_err(&od->pdev->dev,
85 "clkdev_alloc for %s failed\n", clk_alias);
86 else
87 dev_err(&od->pdev->dev,
88 "clk_get for %s failed\n", clk_name);
89 }
90}
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111static void _add_hwmod_clocks_clkdev(struct omap_device *od,
112 struct omap_hwmod *oh)
113{
114 int i;
115
116 _add_clkdev(od, "fck", oh->main_clk);
117
118 for (i = 0; i < oh->opt_clks_cnt; i++)
119 _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
120}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135static int omap_device_build_from_dt(struct platform_device *pdev)
136{
137 struct omap_hwmod **hwmods;
138 struct omap_device *od;
139 struct omap_hwmod *oh;
140 struct device_node *node = pdev->dev.of_node;
141 const char *oh_name;
142 int oh_cnt, i, ret = 0;
143 bool device_active = false;
144
145 oh_cnt = of_property_count_strings(node, "ti,hwmods");
146 if (oh_cnt <= 0) {
147 dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n");
148 return -ENODEV;
149 }
150
151 hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
152 if (!hwmods) {
153 ret = -ENOMEM;
154 goto odbfd_exit;
155 }
156
157 for (i = 0; i < oh_cnt; i++) {
158 of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
159 oh = omap_hwmod_lookup(oh_name);
160 if (!oh) {
161 dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
162 oh_name);
163 ret = -EINVAL;
164 goto odbfd_exit1;
165 }
166 hwmods[i] = oh;
167 if (oh->flags & HWMOD_INIT_NO_IDLE)
168 device_active = true;
169 }
170
171 od = omap_device_alloc(pdev, hwmods, oh_cnt);
172 if (IS_ERR(od)) {
173 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
174 oh_name);
175 ret = PTR_ERR(od);
176 goto odbfd_exit1;
177 }
178
179
180 for (i = 0; i < pdev->num_resources; i++) {
181 struct resource *r = &pdev->resource[i];
182
183 if (r->name == NULL)
184 r->name = dev_name(&pdev->dev);
185 }
186
187 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
188
189 if (device_active) {
190 omap_device_enable(pdev);
191 pm_runtime_set_active(&pdev->dev);
192 }
193
194odbfd_exit1:
195 kfree(hwmods);
196odbfd_exit:
197
198 if (ret)
199 dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain);
200
201 return ret;
202}
203
204static int _omap_device_notifier_call(struct notifier_block *nb,
205 unsigned long event, void *dev)
206{
207 struct platform_device *pdev = to_platform_device(dev);
208 struct omap_device *od;
209 int err;
210
211 switch (event) {
212 case BUS_NOTIFY_REMOVED_DEVICE:
213 if (pdev->archdata.od)
214 omap_device_delete(pdev->archdata.od);
215 break;
216 case BUS_NOTIFY_UNBOUND_DRIVER:
217 od = to_omap_device(pdev);
218 if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) {
219 dev_info(dev, "enabled after unload, idling\n");
220 err = omap_device_idle(pdev);
221 if (err)
222 dev_err(dev, "failed to idle\n");
223 }
224 break;
225 case BUS_NOTIFY_BIND_DRIVER:
226 od = to_omap_device(pdev);
227 if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) &&
228 pm_runtime_status_suspended(dev)) {
229 od->_driver_status = BUS_NOTIFY_BIND_DRIVER;
230 pm_runtime_set_active(dev);
231 }
232 break;
233 case BUS_NOTIFY_ADD_DEVICE:
234 if (pdev->dev.of_node)
235 omap_device_build_from_dt(pdev);
236 omap_auxdata_legacy_init(dev);
237
238 default:
239 od = to_omap_device(pdev);
240 if (od)
241 od->_driver_status = event;
242 }
243
244 return NOTIFY_DONE;
245}
246
247
248
249
250
251
252
253static int _omap_device_enable_hwmods(struct omap_device *od)
254{
255 int ret = 0;
256 int i;
257
258 for (i = 0; i < od->hwmods_cnt; i++)
259 ret |= omap_hwmod_enable(od->hwmods[i]);
260
261 return ret;
262}
263
264
265
266
267
268
269
270static int _omap_device_idle_hwmods(struct omap_device *od)
271{
272 int ret = 0;
273 int i;
274
275 for (i = 0; i < od->hwmods_cnt; i++)
276 ret |= omap_hwmod_idle(od->hwmods[i]);
277
278 return ret;
279}
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298int omap_device_get_context_loss_count(struct platform_device *pdev)
299{
300 struct omap_device *od;
301 u32 ret = 0;
302
303 od = to_omap_device(pdev);
304
305 if (od->hwmods_cnt)
306 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
307
308 return ret;
309}
310
311
312
313
314
315
316
317
318
319
320
321static int omap_device_count_resources(struct omap_device *od,
322 unsigned long flags)
323{
324 int c = 0;
325 int i;
326
327 for (i = 0; i < od->hwmods_cnt; i++)
328 c += omap_hwmod_count_resources(od->hwmods[i], flags);
329
330 pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
331 od->pdev->name, c, od->hwmods_cnt);
332
333 return c;
334}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353static int omap_device_fill_resources(struct omap_device *od,
354 struct resource *res)
355{
356 int i, r;
357
358 for (i = 0; i < od->hwmods_cnt; i++) {
359 r = omap_hwmod_fill_resources(od->hwmods[i], res);
360 res += r;
361 }
362
363 return 0;
364}
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380static int _od_fill_dma_resources(struct omap_device *od,
381 struct resource *res)
382{
383 int i, r;
384
385 for (i = 0; i < od->hwmods_cnt; i++) {
386 r = omap_hwmod_fill_dma_resources(od->hwmods[i], res);
387 res += r;
388 }
389
390 return 0;
391}
392
393
394
395
396
397
398
399
400
401
402
403
404
405struct omap_device *omap_device_alloc(struct platform_device *pdev,
406 struct omap_hwmod **ohs, int oh_cnt)
407{
408 int ret = -ENOMEM;
409 struct omap_device *od;
410 struct resource *res = NULL;
411 int i, res_count;
412 struct omap_hwmod **hwmods;
413
414 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
415 if (!od) {
416 ret = -ENOMEM;
417 goto oda_exit1;
418 }
419 od->hwmods_cnt = oh_cnt;
420
421 hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
422 if (!hwmods)
423 goto oda_exit2;
424
425 od->hwmods = hwmods;
426 od->pdev = pdev;
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447 if (!pdev->num_resources) {
448
449 res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
450 IORESOURCE_DMA |
451 IORESOURCE_MEM);
452 } else {
453
454 for (i = 0; i < pdev->num_resources; i++) {
455 struct resource *r = &pdev->resource[i];
456
457
458 if (r->flags == IORESOURCE_DMA)
459 goto have_everything;
460 }
461
462 res_count = omap_device_count_resources(od, IORESOURCE_DMA);
463
464 if (!res_count)
465 goto have_everything;
466
467 res_count += pdev->num_resources;
468 }
469
470
471 res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
472 if (!res)
473 goto oda_exit3;
474
475 if (!pdev->num_resources) {
476 dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
477 __func__, res_count);
478 omap_device_fill_resources(od, res);
479 } else {
480 dev_dbg(&pdev->dev,
481 "%s: appending %d DMA resources from hwmod\n",
482 __func__, res_count - pdev->num_resources);
483 memcpy(res, pdev->resource,
484 sizeof(struct resource) * pdev->num_resources);
485 _od_fill_dma_resources(od, &res[pdev->num_resources]);
486 }
487
488 ret = platform_device_add_resources(pdev, res, res_count);
489 kfree(res);
490
491 if (ret)
492 goto oda_exit3;
493
494have_everything:
495 pdev->archdata.od = od;
496
497 for (i = 0; i < oh_cnt; i++) {
498 hwmods[i]->od = od;
499 _add_hwmod_clocks_clkdev(od, hwmods[i]);
500 }
501
502 return od;
503
504oda_exit3:
505 kfree(hwmods);
506oda_exit2:
507 kfree(od);
508oda_exit1:
509 dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
510
511 return ERR_PTR(ret);
512}
513
514void omap_device_delete(struct omap_device *od)
515{
516 if (!od)
517 return;
518
519 od->pdev->archdata.od = NULL;
520 kfree(od->hwmods);
521 kfree(od);
522}
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538struct platform_device __init *omap_device_build(const char *pdev_name,
539 int pdev_id,
540 struct omap_hwmod *oh,
541 void *pdata, int pdata_len)
542{
543 struct omap_hwmod *ohs[] = { oh };
544
545 if (!oh)
546 return ERR_PTR(-EINVAL);
547
548 return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
549 pdata_len);
550}
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566struct platform_device __init *omap_device_build_ss(const char *pdev_name,
567 int pdev_id,
568 struct omap_hwmod **ohs,
569 int oh_cnt, void *pdata,
570 int pdata_len)
571{
572 int ret = -ENOMEM;
573 struct platform_device *pdev;
574 struct omap_device *od;
575
576 if (!ohs || oh_cnt == 0 || !pdev_name)
577 return ERR_PTR(-EINVAL);
578
579 if (!pdata && pdata_len > 0)
580 return ERR_PTR(-EINVAL);
581
582 pdev = platform_device_alloc(pdev_name, pdev_id);
583 if (!pdev) {
584 ret = -ENOMEM;
585 goto odbs_exit;
586 }
587
588
589 if (pdev->id != -1)
590 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
591 else
592 dev_set_name(&pdev->dev, "%s", pdev->name);
593
594 od = omap_device_alloc(pdev, ohs, oh_cnt);
595 if (IS_ERR(od))
596 goto odbs_exit1;
597
598 ret = platform_device_add_data(pdev, pdata, pdata_len);
599 if (ret)
600 goto odbs_exit2;
601
602 ret = omap_device_register(pdev);
603 if (ret)
604 goto odbs_exit2;
605
606 return pdev;
607
608odbs_exit2:
609 omap_device_delete(od);
610odbs_exit1:
611 platform_device_put(pdev);
612odbs_exit:
613
614 pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
615
616 return ERR_PTR(ret);
617}
618
619#ifdef CONFIG_PM
620static int _od_runtime_suspend(struct device *dev)
621{
622 struct platform_device *pdev = to_platform_device(dev);
623 int ret;
624
625 ret = pm_generic_runtime_suspend(dev);
626 if (ret)
627 return ret;
628
629 return omap_device_idle(pdev);
630}
631
632static int _od_runtime_resume(struct device *dev)
633{
634 struct platform_device *pdev = to_platform_device(dev);
635 int ret;
636
637 ret = omap_device_enable(pdev);
638 if (ret) {
639 dev_err(dev, "use pm_runtime_put_sync_suspend() in driver?\n");
640 return ret;
641 }
642
643 return pm_generic_runtime_resume(dev);
644}
645
646static int _od_fail_runtime_suspend(struct device *dev)
647{
648 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
649 return -ENODEV;
650}
651
652static int _od_fail_runtime_resume(struct device *dev)
653{
654 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
655 return -ENODEV;
656}
657
658#endif
659
660#ifdef CONFIG_SUSPEND
661static int _od_suspend_noirq(struct device *dev)
662{
663 struct platform_device *pdev = to_platform_device(dev);
664 struct omap_device *od = to_omap_device(pdev);
665 int ret;
666
667
668 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER)
669 return 0;
670
671 ret = pm_generic_suspend_noirq(dev);
672
673 if (!ret && !pm_runtime_status_suspended(dev)) {
674 if (pm_generic_runtime_suspend(dev) == 0) {
675 omap_device_idle(pdev);
676 od->flags |= OMAP_DEVICE_SUSPENDED;
677 }
678 }
679
680 return ret;
681}
682
683static int _od_resume_noirq(struct device *dev)
684{
685 struct platform_device *pdev = to_platform_device(dev);
686 struct omap_device *od = to_omap_device(pdev);
687
688 if (od->flags & OMAP_DEVICE_SUSPENDED) {
689 od->flags &= ~OMAP_DEVICE_SUSPENDED;
690 omap_device_enable(pdev);
691 pm_generic_runtime_resume(dev);
692 }
693
694 return pm_generic_resume_noirq(dev);
695}
696#else
697#define _od_suspend_noirq NULL
698#define _od_resume_noirq NULL
699#endif
700
701struct dev_pm_domain omap_device_fail_pm_domain = {
702 .ops = {
703 SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend,
704 _od_fail_runtime_resume, NULL)
705 }
706};
707
708struct dev_pm_domain omap_device_pm_domain = {
709 .ops = {
710 SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
711 NULL)
712 USE_PLATFORM_PM_SLEEP_OPS
713 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq,
714 _od_resume_noirq)
715 }
716};
717
718
719
720
721
722
723
724
725
726int omap_device_register(struct platform_device *pdev)
727{
728 pr_debug("omap_device: %s: registering\n", pdev->name);
729
730 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
731 return platform_device_add(pdev);
732}
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749int omap_device_enable(struct platform_device *pdev)
750{
751 int ret;
752 struct omap_device *od;
753
754 od = to_omap_device(pdev);
755
756 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
757 dev_warn(&pdev->dev,
758 "omap_device: %s() called from invalid state %d\n",
759 __func__, od->_state);
760 return -EINVAL;
761 }
762
763 ret = _omap_device_enable_hwmods(od);
764
765 if (ret == 0)
766 od->_state = OMAP_DEVICE_STATE_ENABLED;
767
768 return ret;
769}
770
771
772
773
774
775
776
777
778
779
780int omap_device_idle(struct platform_device *pdev)
781{
782 int ret;
783 struct omap_device *od;
784
785 od = to_omap_device(pdev);
786
787 if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
788 dev_warn(&pdev->dev,
789 "omap_device: %s() called from invalid state %d\n",
790 __func__, od->_state);
791 return -EINVAL;
792 }
793
794 ret = _omap_device_idle_hwmods(od);
795
796 if (ret == 0)
797 od->_state = OMAP_DEVICE_STATE_IDLE;
798
799 return ret;
800}
801
802
803
804
805
806
807
808
809
810
811
812
813
814int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
815{
816 struct omap_device *od = to_omap_device(pdev);
817 int ret = 0;
818 int i;
819
820 for (i = 0; i < od->hwmods_cnt; i++) {
821 ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
822 if (ret)
823 break;
824 }
825
826 return ret;
827}
828
829
830
831
832
833
834
835
836
837
838
839
840
841int omap_device_deassert_hardreset(struct platform_device *pdev,
842 const char *name)
843{
844 struct omap_device *od = to_omap_device(pdev);
845 int ret = 0;
846 int i;
847
848 for (i = 0; i < od->hwmods_cnt; i++) {
849 ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
850 if (ret)
851 break;
852 }
853
854 return ret;
855}
856
857
858
859
860
861
862
863
864
865struct device *omap_device_get_by_hwmod_name(const char *oh_name)
866{
867 struct omap_hwmod *oh;
868
869 if (!oh_name) {
870 WARN(1, "%s: no hwmod name!\n", __func__);
871 return ERR_PTR(-EINVAL);
872 }
873
874 oh = omap_hwmod_lookup(oh_name);
875 if (!oh) {
876 WARN(1, "%s: no hwmod for %s\n", __func__,
877 oh_name);
878 return ERR_PTR(-ENODEV);
879 }
880 if (!oh->od) {
881 WARN(1, "%s: no omap_device for %s\n", __func__,
882 oh_name);
883 return ERR_PTR(-ENODEV);
884 }
885
886 return &oh->od->pdev->dev;
887}
888
889static struct notifier_block platform_nb = {
890 .notifier_call = _omap_device_notifier_call,
891};
892
893static int __init omap_device_init(void)
894{
895 bus_register_notifier(&platform_bus_type, &platform_nb);
896 return 0;
897}
898omap_postcore_initcall(omap_device_init);
899
900
901
902
903
904
905
906
907
908static int __init omap_device_late_idle(struct device *dev, void *data)
909{
910 struct platform_device *pdev = to_platform_device(dev);
911 struct omap_device *od = to_omap_device(pdev);
912 int i;
913
914 if (!od)
915 return 0;
916
917
918
919
920
921
922
923
924
925
926 for (i = 0; i < od->hwmods_cnt; i++)
927 if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
928 return 0;
929
930 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
931 od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
932 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
933 dev_warn(dev, "%s: enabled but no driver. Idling\n",
934 __func__);
935 omap_device_idle(pdev);
936 }
937 }
938
939 return 0;
940}
941
942static int __init omap_device_late_init(void)
943{
944 bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
945
946 return 0;
947}
948omap_late_initcall_sync(omap_device_late_init);
949