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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128#undef DEBUG
129
130#include <linux/kernel.h>
131#include <linux/errno.h>
132#include <linux/io.h>
133#include <linux/clk-provider.h>
134#include <linux/delay.h>
135#include <linux/err.h>
136#include <linux/list.h>
137#include <linux/mutex.h>
138#include <linux/spinlock.h>
139#include <linux/slab.h>
140#include <linux/bootmem.h>
141#include <linux/cpu.h>
142#include <linux/of.h>
143#include <linux/of_address.h>
144
145#include <asm/system_misc.h>
146
147#include "clock.h"
148#include "omap_hwmod.h"
149
150#include "soc.h"
151#include "common.h"
152#include "clockdomain.h"
153#include "powerdomain.h"
154#include "cm2xxx.h"
155#include "cm3xxx.h"
156#include "cm33xx.h"
157#include "prm.h"
158#include "prm3xxx.h"
159#include "prm44xx.h"
160#include "prm33xx.h"
161#include "prminst44xx.h"
162#include "mux.h"
163#include "pm.h"
164
165
166#define MPU_INITIATOR_NAME "mpu"
167
168
169
170
171
172#define LINKS_PER_OCP_IF 2
173
174
175
176
177
178
179
180
181
182
183struct omap_hwmod_soc_ops {
184 void (*enable_module)(struct omap_hwmod *oh);
185 int (*disable_module)(struct omap_hwmod *oh);
186 int (*wait_target_ready)(struct omap_hwmod *oh);
187 int (*assert_hardreset)(struct omap_hwmod *oh,
188 struct omap_hwmod_rst_info *ohri);
189 int (*deassert_hardreset)(struct omap_hwmod *oh,
190 struct omap_hwmod_rst_info *ohri);
191 int (*is_hardreset_asserted)(struct omap_hwmod *oh,
192 struct omap_hwmod_rst_info *ohri);
193 int (*init_clkdm)(struct omap_hwmod *oh);
194 void (*update_context_lost)(struct omap_hwmod *oh);
195 int (*get_context_lost)(struct omap_hwmod *oh);
196};
197
198
199static struct omap_hwmod_soc_ops soc_ops;
200
201
202static LIST_HEAD(omap_hwmod_list);
203
204
205static struct omap_hwmod *mpu_oh;
206
207
208static DEFINE_SPINLOCK(io_chain_lock);
209
210
211
212
213
214
215static struct omap_hwmod_link *linkspace;
216
217
218
219
220
221
222static unsigned short free_ls, max_ls, ls_supp;
223
224
225static bool inited;
226
227
228
229
230
231
232
233
234
235
236
237
238
239static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p,
240 int *i)
241{
242 struct omap_hwmod_ocp_if *oi;
243
244 oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if;
245 *p = (*p)->next;
246
247 *i = *i + 1;
248
249 return oi;
250}
251
252
253
254
255
256
257
258
259
260static int _update_sysc_cache(struct omap_hwmod *oh)
261{
262 if (!oh->class->sysc) {
263 WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
264 return -EINVAL;
265 }
266
267
268
269 oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
270
271 if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
272 oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
273
274 return 0;
275}
276
277
278
279
280
281
282
283
284
285static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
286{
287 if (!oh->class->sysc) {
288 WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
289 return;
290 }
291
292
293
294
295 oh->_sysc_cache = v;
296 omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
297}
298
299
300
301
302
303
304
305
306
307
308
309static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
310 u32 *v)
311{
312 u32 mstandby_mask;
313 u8 mstandby_shift;
314
315 if (!oh->class->sysc ||
316 !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
317 return -EINVAL;
318
319 if (!oh->class->sysc->sysc_fields) {
320 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
321 return -EINVAL;
322 }
323
324 mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
325 mstandby_mask = (0x3 << mstandby_shift);
326
327 *v &= ~mstandby_mask;
328 *v |= __ffs(standbymode) << mstandby_shift;
329
330 return 0;
331}
332
333
334
335
336
337
338
339
340
341
342
343static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
344{
345 u32 sidle_mask;
346 u8 sidle_shift;
347
348 if (!oh->class->sysc ||
349 !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
350 return -EINVAL;
351
352 if (!oh->class->sysc->sysc_fields) {
353 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
354 return -EINVAL;
355 }
356
357 sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
358 sidle_mask = (0x3 << sidle_shift);
359
360 *v &= ~sidle_mask;
361 *v |= __ffs(idlemode) << sidle_shift;
362
363 return 0;
364}
365
366
367
368
369
370
371
372
373
374
375
376
377static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
378{
379 u32 clkact_mask;
380 u8 clkact_shift;
381
382 if (!oh->class->sysc ||
383 !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
384 return -EINVAL;
385
386 if (!oh->class->sysc->sysc_fields) {
387 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
388 return -EINVAL;
389 }
390
391 clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
392 clkact_mask = (0x3 << clkact_shift);
393
394 *v &= ~clkact_mask;
395 *v |= clockact << clkact_shift;
396
397 return 0;
398}
399
400
401
402
403
404
405
406
407
408static int _set_softreset(struct omap_hwmod *oh, u32 *v)
409{
410 u32 softrst_mask;
411
412 if (!oh->class->sysc ||
413 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
414 return -EINVAL;
415
416 if (!oh->class->sysc->sysc_fields) {
417 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
418 return -EINVAL;
419 }
420
421 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
422
423 *v |= softrst_mask;
424
425 return 0;
426}
427
428
429
430
431
432
433
434
435
436static int _clear_softreset(struct omap_hwmod *oh, u32 *v)
437{
438 u32 softrst_mask;
439
440 if (!oh->class->sysc ||
441 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
442 return -EINVAL;
443
444 if (!oh->class->sysc->sysc_fields) {
445 WARN(1,
446 "omap_hwmod: %s: sysc_fields absent for sysconfig class\n",
447 oh->name);
448 return -EINVAL;
449 }
450
451 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
452
453 *v &= ~softrst_mask;
454
455 return 0;
456}
457
458
459
460
461
462
463
464
465
466
467
468static int _wait_softreset_complete(struct omap_hwmod *oh)
469{
470 struct omap_hwmod_class_sysconfig *sysc;
471 u32 softrst_mask;
472 int c = 0;
473
474 sysc = oh->class->sysc;
475
476 if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
477 omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
478 & SYSS_RESETDONE_MASK),
479 MAX_MODULE_SOFTRESET_WAIT, c);
480 else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
481 softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
482 omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
483 & softrst_mask),
484 MAX_MODULE_SOFTRESET_WAIT, c);
485 }
486
487 return c;
488}
489
490
491
492
493
494
495
496
497
498
499
500
501
502static int _set_dmadisable(struct omap_hwmod *oh)
503{
504 u32 v;
505 u32 dmadisable_mask;
506
507 if (!oh->class->sysc ||
508 !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE))
509 return -EINVAL;
510
511 if (!oh->class->sysc->sysc_fields) {
512 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
513 return -EINVAL;
514 }
515
516
517 if (oh->_state != _HWMOD_STATE_ENABLED) {
518 pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name);
519 return -EINVAL;
520 }
521
522 pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name);
523
524 v = oh->_sysc_cache;
525 dmadisable_mask =
526 (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift);
527 v |= dmadisable_mask;
528 _write_sysconfig(v, oh);
529
530 return 0;
531}
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
547 u32 *v)
548{
549 u32 autoidle_mask;
550 u8 autoidle_shift;
551
552 if (!oh->class->sysc ||
553 !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
554 return -EINVAL;
555
556 if (!oh->class->sysc->sysc_fields) {
557 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
558 return -EINVAL;
559 }
560
561 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
562 autoidle_mask = (0x1 << autoidle_shift);
563
564 *v &= ~autoidle_mask;
565 *v |= autoidle << autoidle_shift;
566
567 return 0;
568}
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
585{
586 struct omap_device_pad *pad;
587 bool change = false;
588 u16 prev_idle;
589 int j;
590
591 if (!oh->mux || !oh->mux->enabled)
592 return;
593
594 for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
595 pad = oh->mux->pads_dynamic[j];
596
597 if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
598 continue;
599
600 prev_idle = pad->idle;
601
602 if (set_wake)
603 pad->idle |= OMAP_WAKEUP_EN;
604 else
605 pad->idle &= ~OMAP_WAKEUP_EN;
606
607 if (prev_idle != pad->idle)
608 change = true;
609 }
610
611 if (change && oh->_state == _HWMOD_STATE_IDLE)
612 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
613}
614
615
616
617
618
619
620
621
622static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
623{
624 if (!oh->class->sysc ||
625 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
626 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
627 (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
628 return -EINVAL;
629
630 if (!oh->class->sysc->sysc_fields) {
631 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
632 return -EINVAL;
633 }
634
635 if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
636 *v |= 0x1 << oh->class->sysc->sysc_fields->enwkup_shift;
637
638 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
639 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
640 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
641 _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
642
643
644
645 return 0;
646}
647
648
649
650
651
652
653
654
655static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
656{
657 if (!oh->class->sysc ||
658 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
659 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
660 (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
661 return -EINVAL;
662
663 if (!oh->class->sysc->sysc_fields) {
664 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
665 return -EINVAL;
666 }
667
668 if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
669 *v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
670
671 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
672 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
673 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
674 _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
675
676
677
678 return 0;
679}
680
681static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
682{
683 struct clk_hw_omap *clk;
684
685 if (oh->clkdm) {
686 return oh->clkdm;
687 } else if (oh->_clk) {
688 if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC)
689 return NULL;
690 clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
691 return clk->clkdm;
692 }
693 return NULL;
694}
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
710{
711 struct clockdomain *clkdm, *init_clkdm;
712
713 clkdm = _get_clkdm(oh);
714 init_clkdm = _get_clkdm(init_oh);
715
716 if (!clkdm || !init_clkdm)
717 return -EINVAL;
718
719 if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
720 return 0;
721
722 return clkdm_add_sleepdep(clkdm, init_clkdm);
723}
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
739{
740 struct clockdomain *clkdm, *init_clkdm;
741
742 clkdm = _get_clkdm(oh);
743 init_clkdm = _get_clkdm(init_oh);
744
745 if (!clkdm || !init_clkdm)
746 return -EINVAL;
747
748 if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
749 return 0;
750
751 return clkdm_del_sleepdep(clkdm, init_clkdm);
752}
753
754
755
756
757
758
759
760
761
762static int _init_main_clk(struct omap_hwmod *oh)
763{
764 int ret = 0;
765
766 if (!oh->main_clk)
767 return 0;
768
769 oh->_clk = clk_get(NULL, oh->main_clk);
770 if (IS_ERR(oh->_clk)) {
771 pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
772 oh->name, oh->main_clk);
773 return -EINVAL;
774 }
775
776
777
778
779
780
781
782
783 clk_prepare(oh->_clk);
784
785 if (!_get_clkdm(oh))
786 pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
787 oh->name, oh->main_clk);
788
789 return ret;
790}
791
792
793
794
795
796
797
798
799static int _init_interface_clks(struct omap_hwmod *oh)
800{
801 struct omap_hwmod_ocp_if *os;
802 struct list_head *p;
803 struct clk *c;
804 int i = 0;
805 int ret = 0;
806
807 p = oh->slave_ports.next;
808
809 while (i < oh->slaves_cnt) {
810 os = _fetch_next_ocp_if(&p, &i);
811 if (!os->clk)
812 continue;
813
814 c = clk_get(NULL, os->clk);
815 if (IS_ERR(c)) {
816 pr_warn("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
817 oh->name, os->clk);
818 ret = -EINVAL;
819 continue;
820 }
821 os->_clk = c;
822
823
824
825
826
827
828
829
830 clk_prepare(os->_clk);
831 }
832
833 return ret;
834}
835
836
837
838
839
840
841
842
843static int _init_opt_clks(struct omap_hwmod *oh)
844{
845 struct omap_hwmod_opt_clk *oc;
846 struct clk *c;
847 int i;
848 int ret = 0;
849
850 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
851 c = clk_get(NULL, oc->clk);
852 if (IS_ERR(c)) {
853 pr_warn("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
854 oh->name, oc->clk);
855 ret = -EINVAL;
856 continue;
857 }
858 oc->_clk = c;
859
860
861
862
863
864
865
866
867 clk_prepare(oc->_clk);
868 }
869
870 return ret;
871}
872
873
874
875
876
877
878
879
880static int _enable_clocks(struct omap_hwmod *oh)
881{
882 struct omap_hwmod_ocp_if *os;
883 struct list_head *p;
884 int i = 0;
885
886 pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
887
888 if (oh->_clk)
889 clk_enable(oh->_clk);
890
891 p = oh->slave_ports.next;
892
893 while (i < oh->slaves_cnt) {
894 os = _fetch_next_ocp_if(&p, &i);
895
896 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
897 clk_enable(os->_clk);
898 }
899
900
901
902 return 0;
903}
904
905
906
907
908
909
910
911static int _disable_clocks(struct omap_hwmod *oh)
912{
913 struct omap_hwmod_ocp_if *os;
914 struct list_head *p;
915 int i = 0;
916
917 pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
918
919 if (oh->_clk)
920 clk_disable(oh->_clk);
921
922 p = oh->slave_ports.next;
923
924 while (i < oh->slaves_cnt) {
925 os = _fetch_next_ocp_if(&p, &i);
926
927 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
928 clk_disable(os->_clk);
929 }
930
931
932
933 return 0;
934}
935
936static void _enable_optional_clocks(struct omap_hwmod *oh)
937{
938 struct omap_hwmod_opt_clk *oc;
939 int i;
940
941 pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
942
943 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
944 if (oc->_clk) {
945 pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
946 __clk_get_name(oc->_clk));
947 clk_enable(oc->_clk);
948 }
949}
950
951static void _disable_optional_clocks(struct omap_hwmod *oh)
952{
953 struct omap_hwmod_opt_clk *oc;
954 int i;
955
956 pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
957
958 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
959 if (oc->_clk) {
960 pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
961 __clk_get_name(oc->_clk));
962 clk_disable(oc->_clk);
963 }
964}
965
966
967
968
969
970
971
972
973static void _omap4_enable_module(struct omap_hwmod *oh)
974{
975 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
976 return;
977
978 pr_debug("omap_hwmod: %s: %s: %d\n",
979 oh->name, __func__, oh->prcm.omap4.modulemode);
980
981 omap_cm_module_enable(oh->prcm.omap4.modulemode,
982 oh->clkdm->prcm_partition,
983 oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs);
984}
985
986
987
988
989
990
991
992
993
994
995static int _omap4_wait_target_disable(struct omap_hwmod *oh)
996{
997 if (!oh)
998 return -EINVAL;
999
1000 if (oh->_int_flags & _HWMOD_NO_MPU_PORT || !oh->clkdm)
1001 return 0;
1002
1003 if (oh->flags & HWMOD_NO_IDLEST)
1004 return 0;
1005
1006 return omap_cm_wait_module_idle(oh->clkdm->prcm_partition,
1007 oh->clkdm->cm_inst,
1008 oh->prcm.omap4.clkctrl_offs, 0);
1009}
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019static int _count_mpu_irqs(struct omap_hwmod *oh)
1020{
1021 struct omap_hwmod_irq_info *ohii;
1022 int i = 0;
1023
1024 if (!oh || !oh->mpu_irqs)
1025 return 0;
1026
1027 do {
1028 ohii = &oh->mpu_irqs[i++];
1029 } while (ohii->irq != -1);
1030
1031 return i-1;
1032}
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042static int _count_sdma_reqs(struct omap_hwmod *oh)
1043{
1044 struct omap_hwmod_dma_info *ohdi;
1045 int i = 0;
1046
1047 if (!oh || !oh->sdma_reqs)
1048 return 0;
1049
1050 do {
1051 ohdi = &oh->sdma_reqs[i++];
1052 } while (ohdi->dma_req != -1);
1053
1054 return i-1;
1055}
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os)
1066{
1067 struct omap_hwmod_addr_space *mem;
1068 int i = 0;
1069
1070 if (!os || !os->addr)
1071 return 0;
1072
1073 do {
1074 mem = &os->addr[i++];
1075 } while (mem->pa_start != mem->pa_end);
1076
1077 return i-1;
1078}
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097static int _get_mpu_irq_by_name(struct omap_hwmod *oh, const char *name,
1098 unsigned int *irq)
1099{
1100 int i;
1101 bool found = false;
1102
1103 if (!oh->mpu_irqs)
1104 return -ENOENT;
1105
1106 i = 0;
1107 while (oh->mpu_irqs[i].irq != -1) {
1108 if (name == oh->mpu_irqs[i].name ||
1109 !strcmp(name, oh->mpu_irqs[i].name)) {
1110 found = true;
1111 break;
1112 }
1113 i++;
1114 }
1115
1116 if (!found)
1117 return -ENOENT;
1118
1119 *irq = oh->mpu_irqs[i].irq;
1120
1121 return 0;
1122}
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140static int _get_sdma_req_by_name(struct omap_hwmod *oh, const char *name,
1141 unsigned int *dma)
1142{
1143 int i;
1144 bool found = false;
1145
1146 if (!oh->sdma_reqs)
1147 return -ENOENT;
1148
1149 i = 0;
1150 while (oh->sdma_reqs[i].dma_req != -1) {
1151 if (name == oh->sdma_reqs[i].name ||
1152 !strcmp(name, oh->sdma_reqs[i].name)) {
1153 found = true;
1154 break;
1155 }
1156 i++;
1157 }
1158
1159 if (!found)
1160 return -ENOENT;
1161
1162 *dma = oh->sdma_reqs[i].dma_req;
1163
1164 return 0;
1165}
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name,
1186 u32 *pa_start, u32 *pa_end)
1187{
1188 int i, j;
1189 struct omap_hwmod_ocp_if *os;
1190 struct list_head *p = NULL;
1191 bool found = false;
1192
1193 p = oh->slave_ports.next;
1194
1195 i = 0;
1196 while (i < oh->slaves_cnt) {
1197 os = _fetch_next_ocp_if(&p, &i);
1198
1199 if (!os->addr)
1200 return -ENOENT;
1201
1202 j = 0;
1203 while (os->addr[j].pa_start != os->addr[j].pa_end) {
1204 if (name == os->addr[j].name ||
1205 !strcmp(name, os->addr[j].name)) {
1206 found = true;
1207 break;
1208 }
1209 j++;
1210 }
1211
1212 if (found)
1213 break;
1214 }
1215
1216 if (!found)
1217 return -ENOENT;
1218
1219 *pa_start = os->addr[j].pa_start;
1220 *pa_end = os->addr[j].pa_end;
1221
1222 return 0;
1223}
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234static void __init _save_mpu_port_index(struct omap_hwmod *oh)
1235{
1236 struct omap_hwmod_ocp_if *os = NULL;
1237 struct list_head *p;
1238 int i = 0;
1239
1240 if (!oh)
1241 return;
1242
1243 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1244
1245 p = oh->slave_ports.next;
1246
1247 while (i < oh->slaves_cnt) {
1248 os = _fetch_next_ocp_if(&p, &i);
1249 if (os->user & OCP_USER_MPU) {
1250 oh->_mpu_port = os;
1251 oh->_int_flags &= ~_HWMOD_NO_MPU_PORT;
1252 break;
1253 }
1254 }
1255
1256 return;
1257}
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh)
1273{
1274 if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0)
1275 return NULL;
1276
1277 return oh->_mpu_port;
1278};
1279
1280
1281
1282
1283
1284
1285
1286
1287static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap_hwmod *oh)
1288{
1289 struct omap_hwmod_ocp_if *os;
1290 struct omap_hwmod_addr_space *mem;
1291 int found = 0, i = 0;
1292
1293 os = _find_mpu_rt_port(oh);
1294 if (!os || !os->addr)
1295 return NULL;
1296
1297 do {
1298 mem = &os->addr[i++];
1299 if (mem->flags & ADDR_TYPE_RT)
1300 found = 1;
1301 } while (!found && mem->pa_start != mem->pa_end);
1302
1303 return (found) ? mem : NULL;
1304}
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317static void _enable_sysc(struct omap_hwmod *oh)
1318{
1319 u8 idlemode, sf;
1320 u32 v;
1321 bool clkdm_act;
1322 struct clockdomain *clkdm;
1323
1324 if (!oh->class->sysc)
1325 return;
1326
1327
1328
1329
1330
1331
1332
1333 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1334 _enable_optional_clocks(oh);
1335 _wait_softreset_complete(oh);
1336 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1337 _disable_optional_clocks(oh);
1338
1339 v = oh->_sysc_cache;
1340 sf = oh->class->sysc->sysc_flags;
1341
1342 clkdm = _get_clkdm(oh);
1343 if (sf & SYSC_HAS_SIDLEMODE) {
1344 if (oh->flags & HWMOD_SWSUP_SIDLE ||
1345 oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
1346 idlemode = HWMOD_IDLEMODE_NO;
1347 } else {
1348 if (sf & SYSC_HAS_ENAWAKEUP)
1349 _enable_wakeup(oh, &v);
1350 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1351 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1352 else
1353 idlemode = HWMOD_IDLEMODE_SMART;
1354 }
1355
1356
1357
1358
1359
1360 clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
1361 if (clkdm_act && !(oh->class->sysc->idlemodes &
1362 (SIDLE_SMART | SIDLE_SMART_WKUP)))
1363 idlemode = HWMOD_IDLEMODE_FORCE;
1364
1365 _set_slave_idlemode(oh, idlemode, &v);
1366 }
1367
1368 if (sf & SYSC_HAS_MIDLEMODE) {
1369 if (oh->flags & HWMOD_FORCE_MSTANDBY) {
1370 idlemode = HWMOD_IDLEMODE_FORCE;
1371 } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
1372 idlemode = HWMOD_IDLEMODE_NO;
1373 } else {
1374 if (sf & SYSC_HAS_ENAWAKEUP)
1375 _enable_wakeup(oh, &v);
1376 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
1377 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1378 else
1379 idlemode = HWMOD_IDLEMODE_SMART;
1380 }
1381 _set_master_standbymode(oh, idlemode, &v);
1382 }
1383
1384
1385
1386
1387
1388
1389 if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
1390 (sf & SYSC_HAS_CLOCKACTIVITY))
1391 _set_clockactivity(oh, oh->class->sysc->clockact, &v);
1392
1393
1394 if (oh->_sysc_cache != v)
1395 _write_sysconfig(v, oh);
1396
1397
1398
1399
1400
1401 if (sf & SYSC_HAS_AUTOIDLE) {
1402 idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
1403 0 : 1;
1404 _set_module_autoidle(oh, idlemode, &v);
1405 _write_sysconfig(v, oh);
1406 }
1407}
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418static void _idle_sysc(struct omap_hwmod *oh)
1419{
1420 u8 idlemode, sf;
1421 u32 v;
1422
1423 if (!oh->class->sysc)
1424 return;
1425
1426 v = oh->_sysc_cache;
1427 sf = oh->class->sysc->sysc_flags;
1428
1429 if (sf & SYSC_HAS_SIDLEMODE) {
1430 if (oh->flags & HWMOD_SWSUP_SIDLE) {
1431 idlemode = HWMOD_IDLEMODE_FORCE;
1432 } else {
1433 if (sf & SYSC_HAS_ENAWAKEUP)
1434 _enable_wakeup(oh, &v);
1435 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1436 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1437 else
1438 idlemode = HWMOD_IDLEMODE_SMART;
1439 }
1440 _set_slave_idlemode(oh, idlemode, &v);
1441 }
1442
1443 if (sf & SYSC_HAS_MIDLEMODE) {
1444 if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
1445 (oh->flags & HWMOD_FORCE_MSTANDBY)) {
1446 idlemode = HWMOD_IDLEMODE_FORCE;
1447 } else {
1448 if (sf & SYSC_HAS_ENAWAKEUP)
1449 _enable_wakeup(oh, &v);
1450 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
1451 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1452 else
1453 idlemode = HWMOD_IDLEMODE_SMART;
1454 }
1455 _set_master_standbymode(oh, idlemode, &v);
1456 }
1457
1458 _write_sysconfig(v, oh);
1459}
1460
1461
1462
1463
1464
1465
1466
1467
1468static void _shutdown_sysc(struct omap_hwmod *oh)
1469{
1470 u32 v;
1471 u8 sf;
1472
1473 if (!oh->class->sysc)
1474 return;
1475
1476 v = oh->_sysc_cache;
1477 sf = oh->class->sysc->sysc_flags;
1478
1479 if (sf & SYSC_HAS_SIDLEMODE)
1480 _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
1481
1482 if (sf & SYSC_HAS_MIDLEMODE)
1483 _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
1484
1485 if (sf & SYSC_HAS_AUTOIDLE)
1486 _set_module_autoidle(oh, 1, &v);
1487
1488 _write_sysconfig(v, oh);
1489}
1490
1491
1492
1493
1494
1495
1496
1497static struct omap_hwmod *_lookup(const char *name)
1498{
1499 struct omap_hwmod *oh, *temp_oh;
1500
1501 oh = NULL;
1502
1503 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1504 if (!strcmp(name, temp_oh->name)) {
1505 oh = temp_oh;
1506 break;
1507 }
1508 }
1509
1510 return oh;
1511}
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521static int _init_clkdm(struct omap_hwmod *oh)
1522{
1523 if (!oh->clkdm_name) {
1524 pr_debug("omap_hwmod: %s: missing clockdomain\n", oh->name);
1525 return 0;
1526 }
1527
1528 oh->clkdm = clkdm_lookup(oh->clkdm_name);
1529 if (!oh->clkdm) {
1530 pr_warn("omap_hwmod: %s: could not associate to clkdm %s\n",
1531 oh->name, oh->clkdm_name);
1532 return 0;
1533 }
1534
1535 pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
1536 oh->name, oh->clkdm_name);
1537
1538 return 0;
1539}
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551static int _init_clocks(struct omap_hwmod *oh, void *data)
1552{
1553 int ret = 0;
1554
1555 if (oh->_state != _HWMOD_STATE_REGISTERED)
1556 return 0;
1557
1558 pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
1559
1560 if (soc_ops.init_clkdm)
1561 ret |= soc_ops.init_clkdm(oh);
1562
1563 ret |= _init_main_clk(oh);
1564 ret |= _init_interface_clks(oh);
1565 ret |= _init_opt_clks(oh);
1566
1567 if (!ret)
1568 oh->_state = _HWMOD_STATE_CLKS_INITED;
1569 else
1570 pr_warn("omap_hwmod: %s: cannot _init_clocks\n", oh->name);
1571
1572 return ret;
1573}
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584static int _lookup_hardreset(struct omap_hwmod *oh, const char *name,
1585 struct omap_hwmod_rst_info *ohri)
1586{
1587 int i;
1588
1589 for (i = 0; i < oh->rst_lines_cnt; i++) {
1590 const char *rst_line = oh->rst_lines[i].name;
1591 if (!strcmp(rst_line, name)) {
1592 ohri->rst_shift = oh->rst_lines[i].rst_shift;
1593 ohri->st_shift = oh->rst_lines[i].st_shift;
1594 pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
1595 oh->name, __func__, rst_line, ohri->rst_shift,
1596 ohri->st_shift);
1597
1598 return 0;
1599 }
1600 }
1601
1602 return -ENOENT;
1603}
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1619{
1620 struct omap_hwmod_rst_info ohri;
1621 int ret = -EINVAL;
1622
1623 if (!oh)
1624 return -EINVAL;
1625
1626 if (!soc_ops.assert_hardreset)
1627 return -ENOSYS;
1628
1629 ret = _lookup_hardreset(oh, name, &ohri);
1630 if (ret < 0)
1631 return ret;
1632
1633 ret = soc_ops.assert_hardreset(oh, &ohri);
1634
1635 return ret;
1636}
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1652{
1653 struct omap_hwmod_rst_info ohri;
1654 int ret = -EINVAL;
1655 int hwsup = 0;
1656
1657 if (!oh)
1658 return -EINVAL;
1659
1660 if (!soc_ops.deassert_hardreset)
1661 return -ENOSYS;
1662
1663 ret = _lookup_hardreset(oh, name, &ohri);
1664 if (ret < 0)
1665 return ret;
1666
1667 if (oh->clkdm) {
1668
1669
1670
1671
1672
1673 hwsup = clkdm_in_hwsup(oh->clkdm);
1674 ret = clkdm_hwmod_enable(oh->clkdm, oh);
1675 if (ret) {
1676 WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
1677 oh->name, oh->clkdm->name, ret);
1678 return ret;
1679 }
1680 }
1681
1682 _enable_clocks(oh);
1683 if (soc_ops.enable_module)
1684 soc_ops.enable_module(oh);
1685
1686 ret = soc_ops.deassert_hardreset(oh, &ohri);
1687
1688 if (soc_ops.disable_module)
1689 soc_ops.disable_module(oh);
1690 _disable_clocks(oh);
1691
1692 if (ret == -EBUSY)
1693 pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name);
1694
1695 if (!ret) {
1696
1697
1698
1699
1700 if (oh->clkdm && hwsup)
1701 clkdm_allow_idle(oh->clkdm);
1702 } else {
1703 if (oh->clkdm)
1704 clkdm_hwmod_disable(oh->clkdm, oh);
1705 }
1706
1707 return ret;
1708}
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1723{
1724 struct omap_hwmod_rst_info ohri;
1725 int ret = -EINVAL;
1726
1727 if (!oh)
1728 return -EINVAL;
1729
1730 if (!soc_ops.is_hardreset_asserted)
1731 return -ENOSYS;
1732
1733 ret = _lookup_hardreset(oh, name, &ohri);
1734 if (ret < 0)
1735 return ret;
1736
1737 return soc_ops.is_hardreset_asserted(oh, &ohri);
1738}
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
1751{
1752 int i, rst_cnt = 0;
1753
1754 if (oh->rst_lines_cnt == 0)
1755 return false;
1756
1757 for (i = 0; i < oh->rst_lines_cnt; i++)
1758 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1759 rst_cnt++;
1760
1761 if (oh->rst_lines_cnt == rst_cnt)
1762 return true;
1763
1764 return false;
1765}
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
1779{
1780 int rst_cnt = 0;
1781 int i;
1782
1783 for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
1784 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1785 rst_cnt++;
1786
1787 return (rst_cnt) ? true : false;
1788}
1789
1790
1791
1792
1793
1794
1795
1796
1797static int _omap4_disable_module(struct omap_hwmod *oh)
1798{
1799 int v;
1800
1801 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
1802 return -EINVAL;
1803
1804
1805
1806
1807
1808 if (_are_any_hardreset_lines_asserted(oh))
1809 return 0;
1810
1811 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1812
1813 omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst,
1814 oh->prcm.omap4.clkctrl_offs);
1815
1816 v = _omap4_wait_target_disable(oh);
1817 if (v)
1818 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1819 oh->name);
1820
1821 return 0;
1822}
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840static int _ocp_softreset(struct omap_hwmod *oh)
1841{
1842 u32 v;
1843 int c = 0;
1844 int ret = 0;
1845
1846 if (!oh->class->sysc ||
1847 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
1848 return -ENOENT;
1849
1850
1851 if (oh->_state != _HWMOD_STATE_ENABLED) {
1852 pr_warn("omap_hwmod: %s: reset can only be entered from enabled state\n",
1853 oh->name);
1854 return -EINVAL;
1855 }
1856
1857
1858 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1859 _enable_optional_clocks(oh);
1860
1861 pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name);
1862
1863 v = oh->_sysc_cache;
1864 ret = _set_softreset(oh, &v);
1865 if (ret)
1866 goto dis_opt_clks;
1867
1868 _write_sysconfig(v, oh);
1869
1870 if (oh->class->sysc->srst_udelay)
1871 udelay(oh->class->sysc->srst_udelay);
1872
1873 c = _wait_softreset_complete(oh);
1874 if (c == MAX_MODULE_SOFTRESET_WAIT) {
1875 pr_warn("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1876 oh->name, MAX_MODULE_SOFTRESET_WAIT);
1877 ret = -ETIMEDOUT;
1878 goto dis_opt_clks;
1879 } else {
1880 pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
1881 }
1882
1883 ret = _clear_softreset(oh, &v);
1884 if (ret)
1885 goto dis_opt_clks;
1886
1887 _write_sysconfig(v, oh);
1888
1889
1890
1891
1892
1893
1894dis_opt_clks:
1895 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1896 _disable_optional_clocks(oh);
1897
1898 return ret;
1899}
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934static int _reset(struct omap_hwmod *oh)
1935{
1936 int i, r;
1937
1938 pr_debug("omap_hwmod: %s: resetting\n", oh->name);
1939
1940 if (oh->class->reset) {
1941 r = oh->class->reset(oh);
1942 } else {
1943 if (oh->rst_lines_cnt > 0) {
1944 for (i = 0; i < oh->rst_lines_cnt; i++)
1945 _assert_hardreset(oh, oh->rst_lines[i].name);
1946 return 0;
1947 } else {
1948 r = _ocp_softreset(oh);
1949 if (r == -ENOENT)
1950 r = 0;
1951 }
1952 }
1953
1954 _set_dmadisable(oh);
1955
1956
1957
1958
1959
1960
1961 if (oh->class->sysc) {
1962 _update_sysc_cache(oh);
1963 _enable_sysc(oh);
1964 }
1965
1966 return r;
1967}
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981static void _reconfigure_io_chain(void)
1982{
1983 unsigned long flags;
1984
1985 spin_lock_irqsave(&io_chain_lock, flags);
1986
1987 omap_prm_reconfigure_io_chain();
1988
1989 spin_unlock_irqrestore(&io_chain_lock, flags);
1990}
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001static void _omap4_update_context_lost(struct omap_hwmod *oh)
2002{
2003 if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
2004 return;
2005
2006 if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
2007 oh->clkdm->pwrdm.ptr->prcm_offs,
2008 oh->prcm.omap4.context_offs))
2009 return;
2010
2011 oh->prcm.omap4.context_lost_counter++;
2012 prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
2013 oh->clkdm->pwrdm.ptr->prcm_offs,
2014 oh->prcm.omap4.context_offs);
2015}
2016
2017
2018
2019
2020
2021
2022
2023static int _omap4_get_context_lost(struct omap_hwmod *oh)
2024{
2025 return oh->prcm.omap4.context_lost_counter;
2026}
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037static int _enable_preprogram(struct omap_hwmod *oh)
2038{
2039 if (!oh->class->enable_preprogram)
2040 return 0;
2041
2042 return oh->class->enable_preprogram(oh);
2043}
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053static int _enable(struct omap_hwmod *oh)
2054{
2055 int r;
2056 int hwsup = 0;
2057
2058 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
2059
2060
2061
2062
2063
2064
2065 if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
2066
2067
2068
2069
2070
2071 if (oh->mux)
2072 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
2073
2074 oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
2075 return 0;
2076 }
2077
2078 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
2079 oh->_state != _HWMOD_STATE_IDLE &&
2080 oh->_state != _HWMOD_STATE_DISABLED) {
2081 WARN(1, "omap_hwmod: %s: enabled state can only be entered from initialized, idle, or disabled state\n",
2082 oh->name);
2083 return -EINVAL;
2084 }
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095 if (_are_all_hardreset_lines_asserted(oh))
2096 return 0;
2097
2098
2099 if (oh->mux && (!oh->mux->enabled ||
2100 ((oh->_state == _HWMOD_STATE_IDLE) &&
2101 oh->mux->pads_dynamic))) {
2102 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
2103 _reconfigure_io_chain();
2104 } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
2105 _reconfigure_io_chain();
2106 }
2107
2108 _add_initiator_dep(oh, mpu_oh);
2109
2110 if (oh->clkdm) {
2111
2112
2113
2114
2115
2116 hwsup = clkdm_in_hwsup(oh->clkdm) &&
2117 !clkdm_missing_idle_reporting(oh->clkdm);
2118 r = clkdm_hwmod_enable(oh->clkdm, oh);
2119 if (r) {
2120 WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
2121 oh->name, oh->clkdm->name, r);
2122 return r;
2123 }
2124 }
2125
2126 _enable_clocks(oh);
2127 if (soc_ops.enable_module)
2128 soc_ops.enable_module(oh);
2129 if (oh->flags & HWMOD_BLOCK_WFI)
2130 cpu_idle_poll_ctrl(true);
2131
2132 if (soc_ops.update_context_lost)
2133 soc_ops.update_context_lost(oh);
2134
2135 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
2136 -EINVAL;
2137 if (!r) {
2138
2139
2140
2141
2142 if (oh->clkdm && hwsup)
2143 clkdm_allow_idle(oh->clkdm);
2144
2145 oh->_state = _HWMOD_STATE_ENABLED;
2146
2147
2148 if (oh->class->sysc) {
2149 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
2150 _update_sysc_cache(oh);
2151 _enable_sysc(oh);
2152 }
2153 r = _enable_preprogram(oh);
2154 } else {
2155 if (soc_ops.disable_module)
2156 soc_ops.disable_module(oh);
2157 _disable_clocks(oh);
2158 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
2159 oh->name, r);
2160
2161 if (oh->clkdm)
2162 clkdm_hwmod_disable(oh->clkdm, oh);
2163 }
2164
2165 return r;
2166}
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176static int _idle(struct omap_hwmod *oh)
2177{
2178 pr_debug("omap_hwmod: %s: idling\n", oh->name);
2179
2180 if (oh->_state != _HWMOD_STATE_ENABLED) {
2181 WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
2182 oh->name);
2183 return -EINVAL;
2184 }
2185
2186 if (_are_all_hardreset_lines_asserted(oh))
2187 return 0;
2188
2189 if (oh->class->sysc)
2190 _idle_sysc(oh);
2191 _del_initiator_dep(oh, mpu_oh);
2192
2193 if (oh->flags & HWMOD_BLOCK_WFI)
2194 cpu_idle_poll_ctrl(false);
2195 if (soc_ops.disable_module)
2196 soc_ops.disable_module(oh);
2197
2198
2199
2200
2201
2202
2203
2204 _disable_clocks(oh);
2205 if (oh->clkdm)
2206 clkdm_hwmod_disable(oh->clkdm, oh);
2207
2208
2209 if (oh->mux && oh->mux->pads_dynamic) {
2210 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
2211 _reconfigure_io_chain();
2212 } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
2213 _reconfigure_io_chain();
2214 }
2215
2216 oh->_state = _HWMOD_STATE_IDLE;
2217
2218 return 0;
2219}
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230static int _shutdown(struct omap_hwmod *oh)
2231{
2232 int ret, i;
2233 u8 prev_state;
2234
2235 if (oh->_state != _HWMOD_STATE_IDLE &&
2236 oh->_state != _HWMOD_STATE_ENABLED) {
2237 WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
2238 oh->name);
2239 return -EINVAL;
2240 }
2241
2242 if (_are_all_hardreset_lines_asserted(oh))
2243 return 0;
2244
2245 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
2246
2247 if (oh->class->pre_shutdown) {
2248 prev_state = oh->_state;
2249 if (oh->_state == _HWMOD_STATE_IDLE)
2250 _enable(oh);
2251 ret = oh->class->pre_shutdown(oh);
2252 if (ret) {
2253 if (prev_state == _HWMOD_STATE_IDLE)
2254 _idle(oh);
2255 return ret;
2256 }
2257 }
2258
2259 if (oh->class->sysc) {
2260 if (oh->_state == _HWMOD_STATE_IDLE)
2261 _enable(oh);
2262 _shutdown_sysc(oh);
2263 }
2264
2265
2266 if (oh->_state == _HWMOD_STATE_ENABLED) {
2267 _del_initiator_dep(oh, mpu_oh);
2268
2269 if (oh->flags & HWMOD_BLOCK_WFI)
2270 cpu_idle_poll_ctrl(false);
2271 if (soc_ops.disable_module)
2272 soc_ops.disable_module(oh);
2273 _disable_clocks(oh);
2274 if (oh->clkdm)
2275 clkdm_hwmod_disable(oh->clkdm, oh);
2276 }
2277
2278
2279 for (i = 0; i < oh->rst_lines_cnt; i++)
2280 _assert_hardreset(oh, oh->rst_lines[i].name);
2281
2282
2283 if (oh->mux)
2284 omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
2285
2286 oh->_state = _HWMOD_STATE_DISABLED;
2287
2288 return 0;
2289}
2290
2291static int of_dev_find_hwmod(struct device_node *np,
2292 struct omap_hwmod *oh)
2293{
2294 int count, i, res;
2295 const char *p;
2296
2297 count = of_property_count_strings(np, "ti,hwmods");
2298 if (count < 1)
2299 return -ENODEV;
2300
2301 for (i = 0; i < count; i++) {
2302 res = of_property_read_string_index(np, "ti,hwmods",
2303 i, &p);
2304 if (res)
2305 continue;
2306 if (!strcmp(p, oh->name)) {
2307 pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
2308 np->name, i, oh->name);
2309 return i;
2310 }
2311 }
2312
2313 return -ENODEV;
2314}
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327static int of_dev_hwmod_lookup(struct device_node *np,
2328 struct omap_hwmod *oh,
2329 int *index,
2330 struct device_node **found)
2331{
2332 struct device_node *np0 = NULL;
2333 int res;
2334
2335 res = of_dev_find_hwmod(np, oh);
2336 if (res >= 0) {
2337 *found = np;
2338 *index = res;
2339 return 0;
2340 }
2341
2342 for_each_child_of_node(np, np0) {
2343 struct device_node *fc;
2344 int i;
2345
2346 res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
2347 if (res == 0) {
2348 *found = fc;
2349 *index = i;
2350 return 0;
2351 }
2352 }
2353
2354 *found = NULL;
2355 *index = 0;
2356
2357 return -ENODEV;
2358}
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2375 int index, struct device_node *np)
2376{
2377 struct omap_hwmod_addr_space *mem;
2378 void __iomem *va_start = NULL;
2379
2380 if (!oh)
2381 return -EINVAL;
2382
2383 _save_mpu_port_index(oh);
2384
2385 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
2386 return -ENXIO;
2387
2388 mem = _find_mpu_rt_addr_space(oh);
2389 if (!mem) {
2390 pr_debug("omap_hwmod: %s: no MPU register target found\n",
2391 oh->name);
2392
2393
2394 if (!np)
2395 return -ENXIO;
2396
2397 va_start = of_iomap(np, index + oh->mpu_rt_idx);
2398 } else {
2399 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
2400 }
2401
2402 if (!va_start) {
2403 if (mem)
2404 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
2405 else
2406 pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
2407 oh->name, index, np->full_name);
2408 return -ENXIO;
2409 }
2410
2411 pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
2412 oh->name, va_start);
2413
2414 oh->_mpu_rt_va = va_start;
2415 return 0;
2416}
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431static int __init _init(struct omap_hwmod *oh, void *data)
2432{
2433 int r, index;
2434 struct device_node *np = NULL;
2435
2436 if (oh->_state != _HWMOD_STATE_REGISTERED)
2437 return 0;
2438
2439 if (of_have_populated_dt()) {
2440 struct device_node *bus;
2441
2442 bus = of_find_node_by_name(NULL, "ocp");
2443 if (!bus)
2444 return -ENODEV;
2445
2446 r = of_dev_hwmod_lookup(bus, oh, &index, &np);
2447 if (r)
2448 pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
2449 else if (np && index)
2450 pr_warn("omap_hwmod: %s using broken dt data from %s\n",
2451 oh->name, np->name);
2452 }
2453
2454 if (oh->class->sysc) {
2455 r = _init_mpu_rt_base(oh, NULL, index, np);
2456 if (r < 0) {
2457 WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
2458 oh->name);
2459 return 0;
2460 }
2461 }
2462
2463 r = _init_clocks(oh, NULL);
2464 if (r < 0) {
2465 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
2466 return -EINVAL;
2467 }
2468
2469 if (np) {
2470 if (of_find_property(np, "ti,no-reset-on-init", NULL))
2471 oh->flags |= HWMOD_INIT_NO_RESET;
2472 if (of_find_property(np, "ti,no-idle-on-init", NULL))
2473 oh->flags |= HWMOD_INIT_NO_IDLE;
2474 }
2475
2476 oh->_state = _HWMOD_STATE_INITIALIZED;
2477
2478 return 0;
2479}
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489static void __init _setup_iclk_autoidle(struct omap_hwmod *oh)
2490{
2491 struct omap_hwmod_ocp_if *os;
2492 struct list_head *p;
2493 int i = 0;
2494 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2495 return;
2496
2497 p = oh->slave_ports.next;
2498
2499 while (i < oh->slaves_cnt) {
2500 os = _fetch_next_ocp_if(&p, &i);
2501 if (!os->_clk)
2502 continue;
2503
2504 if (os->flags & OCPIF_SWSUP_IDLE) {
2505
2506 } else {
2507
2508 clk_enable(os->_clk);
2509 }
2510 }
2511
2512 return;
2513}
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524static int __init _setup_reset(struct omap_hwmod *oh)
2525{
2526 int r;
2527
2528 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2529 return -EINVAL;
2530
2531 if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
2532 return -EPERM;
2533
2534 if (oh->rst_lines_cnt == 0) {
2535 r = _enable(oh);
2536 if (r) {
2537 pr_warn("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
2538 oh->name, oh->_state);
2539 return -EINVAL;
2540 }
2541 }
2542
2543 if (!(oh->flags & HWMOD_INIT_NO_RESET))
2544 r = _reset(oh);
2545
2546 return r;
2547}
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585static void __init _setup_postsetup(struct omap_hwmod *oh)
2586{
2587 u8 postsetup_state;
2588
2589 if (oh->rst_lines_cnt > 0)
2590 return;
2591
2592 postsetup_state = oh->_postsetup_state;
2593 if (postsetup_state == _HWMOD_STATE_UNKNOWN)
2594 postsetup_state = _HWMOD_STATE_ENABLED;
2595
2596
2597
2598
2599
2600 if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
2601 (postsetup_state == _HWMOD_STATE_IDLE)) {
2602 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
2603 postsetup_state = _HWMOD_STATE_ENABLED;
2604 }
2605
2606 if (postsetup_state == _HWMOD_STATE_IDLE)
2607 _idle(oh);
2608 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2609 _shutdown(oh);
2610 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2611 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2612 oh->name, postsetup_state);
2613
2614 return;
2615}
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633static int __init _setup(struct omap_hwmod *oh, void *data)
2634{
2635 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2636 return 0;
2637
2638 if (oh->parent_hwmod) {
2639 int r;
2640
2641 r = _enable(oh->parent_hwmod);
2642 WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n",
2643 oh->name, oh->parent_hwmod->name);
2644 }
2645
2646 _setup_iclk_autoidle(oh);
2647
2648 if (!_setup_reset(oh))
2649 _setup_postsetup(oh);
2650
2651 if (oh->parent_hwmod) {
2652 u8 postsetup_state;
2653
2654 postsetup_state = oh->parent_hwmod->_postsetup_state;
2655
2656 if (postsetup_state == _HWMOD_STATE_IDLE)
2657 _idle(oh->parent_hwmod);
2658 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2659 _shutdown(oh->parent_hwmod);
2660 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2661 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2662 oh->parent_hwmod->name, postsetup_state);
2663 }
2664
2665 return 0;
2666}
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685static int __init _register(struct omap_hwmod *oh)
2686{
2687 if (!oh || !oh->name || !oh->class || !oh->class->name ||
2688 (oh->_state != _HWMOD_STATE_UNKNOWN))
2689 return -EINVAL;
2690
2691 pr_debug("omap_hwmod: %s: registering\n", oh->name);
2692
2693 if (_lookup(oh->name))
2694 return -EEXIST;
2695
2696 list_add_tail(&oh->node, &omap_hwmod_list);
2697
2698 INIT_LIST_HEAD(&oh->master_ports);
2699 INIT_LIST_HEAD(&oh->slave_ports);
2700 spin_lock_init(&oh->_lock);
2701
2702 oh->_state = _HWMOD_STATE_REGISTERED;
2703
2704
2705
2706
2707
2708 if (!strcmp(oh->name, MPU_INITIATOR_NAME))
2709 mpu_oh = oh;
2710
2711 return 0;
2712}
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727static int __init _alloc_links(struct omap_hwmod_link **ml,
2728 struct omap_hwmod_link **sl)
2729{
2730 unsigned int sz;
2731
2732 if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) {
2733 *ml = &linkspace[free_ls++];
2734 *sl = &linkspace[free_ls++];
2735 return 0;
2736 }
2737
2738 sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF;
2739
2740 *sl = NULL;
2741 *ml = memblock_virt_alloc(sz, 0);
2742
2743 *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link);
2744
2745 ls_supp++;
2746 pr_debug("omap_hwmod: supplemental link allocations needed: %d\n",
2747 ls_supp * LINKS_PER_OCP_IF);
2748
2749 return 0;
2750};
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763static int __init _add_link(struct omap_hwmod_ocp_if *oi)
2764{
2765 struct omap_hwmod_link *ml, *sl;
2766
2767 pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
2768 oi->slave->name);
2769
2770 _alloc_links(&ml, &sl);
2771
2772 ml->ocp_if = oi;
2773 list_add(&ml->node, &oi->master->master_ports);
2774 oi->master->masters_cnt++;
2775
2776 sl->ocp_if = oi;
2777 list_add(&sl->node, &oi->slave->slave_ports);
2778 oi->slave->slaves_cnt++;
2779
2780 return 0;
2781}
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796static int __init _register_link(struct omap_hwmod_ocp_if *oi)
2797{
2798 if (!oi || !oi->master || !oi->slave || !oi->user)
2799 return -EINVAL;
2800
2801 if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
2802 return -EEXIST;
2803
2804 pr_debug("omap_hwmod: registering link from %s to %s\n",
2805 oi->master->name, oi->slave->name);
2806
2807
2808
2809
2810
2811 if (oi->master->_state != _HWMOD_STATE_REGISTERED)
2812 _register(oi->master);
2813
2814 if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
2815 _register(oi->slave);
2816
2817 _add_link(oi);
2818
2819 oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
2820
2821 return 0;
2822}
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2840{
2841 unsigned int i = 0;
2842 unsigned int sz;
2843
2844 if (linkspace) {
2845 WARN(1, "linkspace already allocated\n");
2846 return -EEXIST;
2847 }
2848
2849 if (max_ls == 0)
2850 while (ois[i++])
2851 max_ls += LINKS_PER_OCP_IF;
2852
2853 sz = sizeof(struct omap_hwmod_link) * max_ls;
2854
2855 pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n",
2856 __func__, sz, max_ls);
2857
2858 linkspace = memblock_virt_alloc(sz, 0);
2859
2860 return 0;
2861}
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh)
2875{
2876 if (!oh)
2877 return -EINVAL;
2878
2879 if (oh->flags & HWMOD_NO_IDLEST)
2880 return 0;
2881
2882 if (!_find_mpu_rt_port(oh))
2883 return 0;
2884
2885
2886
2887 return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs,
2888 oh->prcm.omap2.idlest_reg_id,
2889 oh->prcm.omap2.idlest_idle_bit);
2890}
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901static int _omap4_wait_target_ready(struct omap_hwmod *oh)
2902{
2903 if (!oh)
2904 return -EINVAL;
2905
2906 if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm)
2907 return 0;
2908
2909 if (!_find_mpu_rt_port(oh))
2910 return 0;
2911
2912
2913
2914 return omap_cm_wait_module_ready(oh->clkdm->prcm_partition,
2915 oh->clkdm->cm_inst,
2916 oh->prcm.omap4.clkctrl_offs, 0);
2917}
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930static int _omap2_assert_hardreset(struct omap_hwmod *oh,
2931 struct omap_hwmod_rst_info *ohri)
2932{
2933 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
2934 oh->prcm.omap2.module_offs, 0);
2935}
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
2949 struct omap_hwmod_rst_info *ohri)
2950{
2951 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
2952 oh->prcm.omap2.module_offs, 0, 0);
2953}
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
2968 struct omap_hwmod_rst_info *ohri)
2969{
2970 return omap_prm_is_hardreset_asserted(ohri->st_shift, 0,
2971 oh->prcm.omap2.module_offs, 0);
2972}
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986static int _omap4_assert_hardreset(struct omap_hwmod *oh,
2987 struct omap_hwmod_rst_info *ohri)
2988{
2989 if (!oh->clkdm)
2990 return -EINVAL;
2991
2992 return omap_prm_assert_hardreset(ohri->rst_shift,
2993 oh->clkdm->pwrdm.ptr->prcm_partition,
2994 oh->clkdm->pwrdm.ptr->prcm_offs,
2995 oh->prcm.omap4.rstctrl_offs);
2996}
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
3011 struct omap_hwmod_rst_info *ohri)
3012{
3013 if (!oh->clkdm)
3014 return -EINVAL;
3015
3016 if (ohri->st_shift)
3017 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
3018 oh->name, ohri->name);
3019 return omap_prm_deassert_hardreset(ohri->rst_shift, 0,
3020 oh->clkdm->pwrdm.ptr->prcm_partition,
3021 oh->clkdm->pwrdm.ptr->prcm_offs,
3022 oh->prcm.omap4.rstctrl_offs, 0);
3023}
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
3038 struct omap_hwmod_rst_info *ohri)
3039{
3040 if (!oh->clkdm)
3041 return -EINVAL;
3042
3043 return omap_prm_is_hardreset_asserted(ohri->rst_shift,
3044 oh->clkdm->pwrdm.ptr->
3045 prcm_partition,
3046 oh->clkdm->pwrdm.ptr->prcm_offs,
3047 oh->prcm.omap4.rstctrl_offs);
3048}
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
3063 struct omap_hwmod_rst_info *ohri)
3064
3065{
3066 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
3067 oh->clkdm->pwrdm.ptr->prcm_offs,
3068 oh->prcm.omap4.rstctrl_offs);
3069}
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
3084 struct omap_hwmod_rst_info *ohri)
3085{
3086 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
3087 oh->clkdm->pwrdm.ptr->prcm_offs,
3088 oh->prcm.omap4.rstctrl_offs,
3089 oh->prcm.omap4.rstst_offs);
3090}
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
3105 struct omap_hwmod_rst_info *ohri)
3106{
3107 return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0,
3108 oh->clkdm->pwrdm.ptr->prcm_offs,
3109 oh->prcm.omap4.rstctrl_offs);
3110}
3111
3112
3113
3114u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
3115{
3116 if (oh->flags & HWMOD_16BIT_REG)
3117 return readw_relaxed(oh->_mpu_rt_va + reg_offs);
3118 else
3119 return readl_relaxed(oh->_mpu_rt_va + reg_offs);
3120}
3121
3122void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
3123{
3124 if (oh->flags & HWMOD_16BIT_REG)
3125 writew_relaxed(v, oh->_mpu_rt_va + reg_offs);
3126 else
3127 writel_relaxed(v, oh->_mpu_rt_va + reg_offs);
3128}
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139int omap_hwmod_softreset(struct omap_hwmod *oh)
3140{
3141 u32 v;
3142 int ret;
3143
3144 if (!oh || !(oh->_sysc_cache))
3145 return -EINVAL;
3146
3147 v = oh->_sysc_cache;
3148 ret = _set_softreset(oh, &v);
3149 if (ret)
3150 goto error;
3151 _write_sysconfig(v, oh);
3152
3153 ret = _clear_softreset(oh, &v);
3154 if (ret)
3155 goto error;
3156 _write_sysconfig(v, oh);
3157
3158error:
3159 return ret;
3160}
3161
3162
3163
3164
3165
3166
3167
3168
3169struct omap_hwmod *omap_hwmod_lookup(const char *name)
3170{
3171 struct omap_hwmod *oh;
3172
3173 if (!name)
3174 return NULL;
3175
3176 oh = _lookup(name);
3177
3178 return oh;
3179}
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
3194 void *data)
3195{
3196 struct omap_hwmod *temp_oh;
3197 int ret = 0;
3198
3199 if (!fn)
3200 return -EINVAL;
3201
3202 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3203 ret = (*fn)(temp_oh, data);
3204 if (ret)
3205 break;
3206 }
3207
3208 return ret;
3209}
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois)
3223{
3224 int r, i;
3225
3226 if (!inited)
3227 return -EINVAL;
3228
3229 if (!ois)
3230 return 0;
3231
3232 if (ois[0] == NULL)
3233 return 0;
3234
3235 if (!linkspace) {
3236 if (_alloc_linkspace(ois)) {
3237 pr_err("omap_hwmod: could not allocate link space\n");
3238 return -ENOMEM;
3239 }
3240 }
3241
3242 i = 0;
3243 do {
3244 r = _register_link(ois[i]);
3245 WARN(r && r != -EEXIST,
3246 "omap_hwmod: _register_link(%s -> %s) returned %d\n",
3247 ois[i]->master->name, ois[i]->slave->name, r);
3248 } while (ois[++i]);
3249
3250 return 0;
3251}
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
3264{
3265 if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
3266 pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
3267 __func__, MPU_INITIATOR_NAME);
3268 else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
3269 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
3270}
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283int __init omap_hwmod_setup_one(const char *oh_name)
3284{
3285 struct omap_hwmod *oh;
3286
3287 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
3288
3289 oh = _lookup(oh_name);
3290 if (!oh) {
3291 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
3292 return -EINVAL;
3293 }
3294
3295 _ensure_mpu_hwmod_is_setup(oh);
3296
3297 _init(oh, NULL);
3298 _setup(oh, NULL);
3299
3300 return 0;
3301}
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311static int __init omap_hwmod_setup_all(void)
3312{
3313 _ensure_mpu_hwmod_is_setup(NULL);
3314
3315 omap_hwmod_for_each(_init, NULL);
3316 omap_hwmod_for_each(_setup, NULL);
3317
3318 return 0;
3319}
3320omap_core_initcall(omap_hwmod_setup_all);
3321
3322
3323
3324
3325
3326
3327
3328
3329int omap_hwmod_enable(struct omap_hwmod *oh)
3330{
3331 int r;
3332 unsigned long flags;
3333
3334 if (!oh)
3335 return -EINVAL;
3336
3337 spin_lock_irqsave(&oh->_lock, flags);
3338 r = _enable(oh);
3339 spin_unlock_irqrestore(&oh->_lock, flags);
3340
3341 return r;
3342}
3343
3344
3345
3346
3347
3348
3349
3350
3351int omap_hwmod_idle(struct omap_hwmod *oh)
3352{
3353 unsigned long flags;
3354
3355 if (!oh)
3356 return -EINVAL;
3357
3358 spin_lock_irqsave(&oh->_lock, flags);
3359 _idle(oh);
3360 spin_unlock_irqrestore(&oh->_lock, flags);
3361
3362 return 0;
3363}
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373int omap_hwmod_shutdown(struct omap_hwmod *oh)
3374{
3375 unsigned long flags;
3376
3377 if (!oh)
3378 return -EINVAL;
3379
3380 spin_lock_irqsave(&oh->_lock, flags);
3381 _shutdown(oh);
3382 spin_unlock_irqrestore(&oh->_lock, flags);
3383
3384 return 0;
3385}
3386
3387
3388
3389
3390
3391
3392
3393int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
3394{
3395 unsigned long flags;
3396
3397 spin_lock_irqsave(&oh->_lock, flags);
3398 _enable_clocks(oh);
3399 spin_unlock_irqrestore(&oh->_lock, flags);
3400
3401 return 0;
3402}
3403
3404
3405
3406
3407
3408
3409
3410int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
3411{
3412 unsigned long flags;
3413
3414 spin_lock_irqsave(&oh->_lock, flags);
3415 _disable_clocks(oh);
3416 spin_unlock_irqrestore(&oh->_lock, flags);
3417
3418 return 0;
3419}
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
3433{
3434 BUG_ON(!oh);
3435
3436 if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
3437 WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n",
3438 oh->name);
3439 return;
3440 }
3441
3442
3443
3444
3445
3446 omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
3447}
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457int omap_hwmod_reset(struct omap_hwmod *oh)
3458{
3459 int r;
3460 unsigned long flags;
3461
3462 if (!oh)
3463 return -EINVAL;
3464
3465 spin_lock_irqsave(&oh->_lock, flags);
3466 r = _reset(oh);
3467 spin_unlock_irqrestore(&oh->_lock, flags);
3468
3469 return r;
3470}
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
3493{
3494 int ret = 0;
3495
3496 if (flags & IORESOURCE_IRQ)
3497 ret += _count_mpu_irqs(oh);
3498
3499 if (flags & IORESOURCE_DMA)
3500 ret += _count_sdma_reqs(oh);
3501
3502 if (flags & IORESOURCE_MEM) {
3503 int i = 0;
3504 struct omap_hwmod_ocp_if *os;
3505 struct list_head *p = oh->slave_ports.next;
3506
3507 while (i < oh->slaves_cnt) {
3508 os = _fetch_next_ocp_if(&p, &i);
3509 ret += _count_ocp_if_addr_spaces(os);
3510 }
3511 }
3512
3513 return ret;
3514}
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
3527{
3528 struct omap_hwmod_ocp_if *os;
3529 struct list_head *p;
3530 int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt;
3531 int r = 0;
3532
3533
3534
3535 mpu_irqs_cnt = _count_mpu_irqs(oh);
3536 for (i = 0; i < mpu_irqs_cnt; i++) {
3537 unsigned int irq;
3538
3539 if (oh->xlate_irq)
3540 irq = oh->xlate_irq((oh->mpu_irqs + i)->irq);
3541 else
3542 irq = (oh->mpu_irqs + i)->irq;
3543 (res + r)->name = (oh->mpu_irqs + i)->name;
3544 (res + r)->start = irq;
3545 (res + r)->end = irq;
3546 (res + r)->flags = IORESOURCE_IRQ;
3547 r++;
3548 }
3549
3550 sdma_reqs_cnt = _count_sdma_reqs(oh);
3551 for (i = 0; i < sdma_reqs_cnt; i++) {
3552 (res + r)->name = (oh->sdma_reqs + i)->name;
3553 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
3554 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
3555 (res + r)->flags = IORESOURCE_DMA;
3556 r++;
3557 }
3558
3559 p = oh->slave_ports.next;
3560
3561 i = 0;
3562 while (i < oh->slaves_cnt) {
3563 os = _fetch_next_ocp_if(&p, &i);
3564 addr_cnt = _count_ocp_if_addr_spaces(os);
3565
3566 for (j = 0; j < addr_cnt; j++) {
3567 (res + r)->name = (os->addr + j)->name;
3568 (res + r)->start = (os->addr + j)->pa_start;
3569 (res + r)->end = (os->addr + j)->pa_end;
3570 (res + r)->flags = IORESOURCE_MEM;
3571 r++;
3572 }
3573 }
3574
3575 return r;
3576}
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res)
3589{
3590 int i, sdma_reqs_cnt;
3591 int r = 0;
3592
3593 sdma_reqs_cnt = _count_sdma_reqs(oh);
3594 for (i = 0; i < sdma_reqs_cnt; i++) {
3595 (res + r)->name = (oh->sdma_reqs + i)->name;
3596 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
3597 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
3598 (res + r)->flags = IORESOURCE_DMA;
3599 r++;
3600 }
3601
3602 return r;
3603}
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
3628 const char *name, struct resource *rsrc)
3629{
3630 int r;
3631 unsigned int irq, dma;
3632 u32 pa_start, pa_end;
3633
3634 if (!oh || !rsrc)
3635 return -EINVAL;
3636
3637 if (type == IORESOURCE_IRQ) {
3638 r = _get_mpu_irq_by_name(oh, name, &irq);
3639 if (r)
3640 return r;
3641
3642 rsrc->start = irq;
3643 rsrc->end = irq;
3644 } else if (type == IORESOURCE_DMA) {
3645 r = _get_sdma_req_by_name(oh, name, &dma);
3646 if (r)
3647 return r;
3648
3649 rsrc->start = dma;
3650 rsrc->end = dma;
3651 } else if (type == IORESOURCE_MEM) {
3652 r = _get_addr_space_by_name(oh, name, &pa_start, &pa_end);
3653 if (r)
3654 return r;
3655
3656 rsrc->start = pa_start;
3657 rsrc->end = pa_end;
3658 } else {
3659 return -EINVAL;
3660 }
3661
3662 rsrc->flags = type;
3663 rsrc->name = name;
3664
3665 return 0;
3666}
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
3680{
3681 struct clk *c;
3682 struct omap_hwmod_ocp_if *oi;
3683 struct clockdomain *clkdm;
3684 struct clk_hw_omap *clk;
3685
3686 if (!oh)
3687 return NULL;
3688
3689 if (oh->clkdm)
3690 return oh->clkdm->pwrdm.ptr;
3691
3692 if (oh->_clk) {
3693 c = oh->_clk;
3694 } else {
3695 oi = _find_mpu_rt_port(oh);
3696 if (!oi)
3697 return NULL;
3698 c = oi->_clk;
3699 }
3700
3701 clk = to_clk_hw_omap(__clk_get_hw(c));
3702 clkdm = clk->clkdm;
3703 if (!clkdm)
3704 return NULL;
3705
3706 return clkdm->pwrdm.ptr;
3707}
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
3719{
3720 if (!oh)
3721 return NULL;
3722
3723 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
3724 return NULL;
3725
3726 if (oh->_state == _HWMOD_STATE_UNKNOWN)
3727 return NULL;
3728
3729 return oh->_mpu_rt_va;
3730}
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
3747 struct omap_hwmod *init_oh)
3748{
3749 return _add_initiator_dep(oh, init_oh);
3750}
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
3772 struct omap_hwmod *init_oh)
3773{
3774 return _del_initiator_dep(oh, init_oh);
3775}
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
3791{
3792 unsigned long flags;
3793 u32 v;
3794
3795 spin_lock_irqsave(&oh->_lock, flags);
3796
3797 if (oh->class->sysc &&
3798 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3799 v = oh->_sysc_cache;
3800 _enable_wakeup(oh, &v);
3801 _write_sysconfig(v, oh);
3802 }
3803
3804 _set_idle_ioring_wakeup(oh, true);
3805 spin_unlock_irqrestore(&oh->_lock, flags);
3806
3807 return 0;
3808}
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
3824{
3825 unsigned long flags;
3826 u32 v;
3827
3828 spin_lock_irqsave(&oh->_lock, flags);
3829
3830 if (oh->class->sysc &&
3831 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3832 v = oh->_sysc_cache;
3833 _disable_wakeup(oh, &v);
3834 _write_sysconfig(v, oh);
3835 }
3836
3837 _set_idle_ioring_wakeup(oh, false);
3838 spin_unlock_irqrestore(&oh->_lock, flags);
3839
3840 return 0;
3841}
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
3856{
3857 int ret;
3858 unsigned long flags;
3859
3860 if (!oh)
3861 return -EINVAL;
3862
3863 spin_lock_irqsave(&oh->_lock, flags);
3864 ret = _assert_hardreset(oh, name);
3865 spin_unlock_irqrestore(&oh->_lock, flags);
3866
3867 return ret;
3868}
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
3883{
3884 int ret;
3885 unsigned long flags;
3886
3887 if (!oh)
3888 return -EINVAL;
3889
3890 spin_lock_irqsave(&oh->_lock, flags);
3891 ret = _deassert_hardreset(oh, name);
3892 spin_unlock_irqrestore(&oh->_lock, flags);
3893
3894 return ret;
3895}
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
3909{
3910 int ret;
3911 unsigned long flags;
3912
3913 if (!oh)
3914 return -EINVAL;
3915
3916 spin_lock_irqsave(&oh->_lock, flags);
3917 ret = _read_hardreset(oh, name);
3918 spin_unlock_irqrestore(&oh->_lock, flags);
3919
3920 return ret;
3921}
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936int omap_hwmod_for_each_by_class(const char *classname,
3937 int (*fn)(struct omap_hwmod *oh,
3938 void *user),
3939 void *user)
3940{
3941 struct omap_hwmod *temp_oh;
3942 int ret = 0;
3943
3944 if (!classname || !fn)
3945 return -EINVAL;
3946
3947 pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
3948 __func__, classname);
3949
3950 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3951 if (!strcmp(temp_oh->class->name, classname)) {
3952 pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
3953 __func__, temp_oh->name);
3954 ret = (*fn)(temp_oh, user);
3955 if (ret)
3956 break;
3957 }
3958 }
3959
3960 if (ret)
3961 pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
3962 __func__, ret);
3963
3964 return ret;
3965}
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
3979{
3980 int ret;
3981 unsigned long flags;
3982
3983 if (!oh)
3984 return -EINVAL;
3985
3986 if (state != _HWMOD_STATE_DISABLED &&
3987 state != _HWMOD_STATE_ENABLED &&
3988 state != _HWMOD_STATE_IDLE)
3989 return -EINVAL;
3990
3991 spin_lock_irqsave(&oh->_lock, flags);
3992
3993 if (oh->_state != _HWMOD_STATE_REGISTERED) {
3994 ret = -EINVAL;
3995 goto ohsps_unlock;
3996 }
3997
3998 oh->_postsetup_state = state;
3999 ret = 0;
4000
4001ohsps_unlock:
4002 spin_unlock_irqrestore(&oh->_lock, flags);
4003
4004 return ret;
4005}
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
4019{
4020 struct powerdomain *pwrdm;
4021 int ret = 0;
4022
4023 if (soc_ops.get_context_lost)
4024 return soc_ops.get_context_lost(oh);
4025
4026 pwrdm = omap_hwmod_get_pwrdm(oh);
4027 if (pwrdm)
4028 ret = pwrdm_get_context_loss_count(pwrdm);
4029
4030 return ret;
4031}
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
4044{
4045 if (!oh)
4046 return -EINVAL;
4047
4048 if (oh->_state != _HWMOD_STATE_REGISTERED) {
4049 pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
4050 oh->name);
4051 return -EINVAL;
4052 }
4053
4054 oh->flags |= HWMOD_INIT_NO_RESET;
4055
4056 return 0;
4057}
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
4085{
4086 int nr_irqs;
4087
4088 might_sleep();
4089
4090 if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
4091 pad_idx >= oh->mux->nr_pads_dynamic)
4092 return -EINVAL;
4093
4094
4095 for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
4096 ;
4097
4098 if (irq_idx >= nr_irqs)
4099 return -EINVAL;
4100
4101 if (!oh->mux->irqs) {
4102
4103 oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
4104 GFP_KERNEL);
4105 if (!oh->mux->irqs)
4106 return -ENOMEM;
4107 }
4108 oh->mux->irqs[pad_idx] = irq_idx;
4109
4110 return 0;
4111}
4112
4113
4114
4115
4116
4117
4118
4119
4120void __init omap_hwmod_init(void)
4121{
4122 if (cpu_is_omap24xx()) {
4123 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
4124 soc_ops.assert_hardreset = _omap2_assert_hardreset;
4125 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
4126 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
4127 } else if (cpu_is_omap34xx()) {
4128 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
4129 soc_ops.assert_hardreset = _omap2_assert_hardreset;
4130 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
4131 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
4132 soc_ops.init_clkdm = _init_clkdm;
4133 } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
4134 soc_ops.enable_module = _omap4_enable_module;
4135 soc_ops.disable_module = _omap4_disable_module;
4136 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4137 soc_ops.assert_hardreset = _omap4_assert_hardreset;
4138 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
4139 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4140 soc_ops.init_clkdm = _init_clkdm;
4141 soc_ops.update_context_lost = _omap4_update_context_lost;
4142 soc_ops.get_context_lost = _omap4_get_context_lost;
4143 } else if (soc_is_am43xx()) {
4144 soc_ops.enable_module = _omap4_enable_module;
4145 soc_ops.disable_module = _omap4_disable_module;
4146 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4147 soc_ops.assert_hardreset = _omap4_assert_hardreset;
4148 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
4149 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4150 soc_ops.init_clkdm = _init_clkdm;
4151 } else if (soc_is_am33xx()) {
4152 soc_ops.enable_module = _omap4_enable_module;
4153 soc_ops.disable_module = _omap4_disable_module;
4154 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4155 soc_ops.assert_hardreset = _am33xx_assert_hardreset;
4156 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
4157 soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
4158 soc_ops.init_clkdm = _init_clkdm;
4159 } else {
4160 WARN(1, "omap_hwmod: unknown SoC type\n");
4161 }
4162
4163 inited = true;
4164}
4165
4166
4167
4168
4169
4170
4171
4172
4173const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
4174{
4175 if (!oh)
4176 return NULL;
4177
4178 return oh->main_clk;
4179}
4180