diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-05-14 15:37:04 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-05-14 15:37:04 -0400 |
commit | 853b20396becfe9425f4d5da74e10ea67811b188 (patch) | |
tree | 6cbd5db9ce11677769a34d205a47907a0f2a75a8 /arch | |
parent | b335d89cd455ef89c734b9a25de1ab0e745363eb (diff) | |
parent | ace1297f7222ec5d6a33f41e792a21e999551924 (diff) |
Merge branch 'mmp/dt' into next/pm
The mmp power management changes are based on this branch, so pull
it in as a dependency.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/boot/dts/mmp2-brownstone.dts | 38 | ||||
-rw-r--r-- | arch/arm/boot/dts/mmp2.dtsi | 220 | ||||
-rw-r--r-- | arch/arm/boot/dts/pxa168.dtsi | 67 | ||||
-rw-r--r-- | arch/arm/boot/dts/pxa910-dkb.dts | 38 | ||||
-rw-r--r-- | arch/arm/boot/dts/pxa910.dtsi | 140 | ||||
-rw-r--r-- | arch/arm/mach-mmp/Kconfig | 29 | ||||
-rw-r--r-- | arch/arm/mach-mmp/Makefile | 9 | ||||
-rw-r--r-- | arch/arm/mach-mmp/include/mach/entry-macro.S | 4 | ||||
-rw-r--r-- | arch/arm/mach-mmp/include/mach/irqs.h | 27 | ||||
-rw-r--r-- | arch/arm/mach-mmp/irq-mmp2.c | 158 | ||||
-rw-r--r-- | arch/arm/mach-mmp/irq-pxa168.c | 54 | ||||
-rw-r--r-- | arch/arm/mach-mmp/irq.c | 445 | ||||
-rw-r--r-- | arch/arm/mach-mmp/mmp-dt.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-mmp/mmp2-dt.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-mmp/time.c | 81 |
16 files changed, 1136 insertions, 301 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cf006d40342c..4cf9d4280972 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -632,6 +632,7 @@ config ARCH_MMP | |||
632 | select CLKDEV_LOOKUP | 632 | select CLKDEV_LOOKUP |
633 | select GENERIC_CLOCKEVENTS | 633 | select GENERIC_CLOCKEVENTS |
634 | select GPIO_PXA | 634 | select GPIO_PXA |
635 | select IRQ_DOMAIN | ||
635 | select TICK_ONESHOT | 636 | select TICK_ONESHOT |
636 | select PLAT_PXA | 637 | select PLAT_PXA |
637 | select SPARSE_IRQ | 638 | select SPARSE_IRQ |
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 000000000000..153a4b2d12b5 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Marvell Technology Group Ltd. | ||
3 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * publishhed by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /dts-v1/; | ||
11 | /include/ "mmp2.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "Marvell MMP2 Aspenite Development Board"; | ||
15 | compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; | ||
16 | |||
17 | chosen { | ||
18 | bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on"; | ||
19 | }; | ||
20 | |||
21 | memory { | ||
22 | reg = <0x00000000 0x04000000>; | ||
23 | }; | ||
24 | |||
25 | soc { | ||
26 | apb@d4000000 { | ||
27 | uart3: uart@d4018000 { | ||
28 | status = "okay"; | ||
29 | }; | ||
30 | twsi1: i2c@d4011000 { | ||
31 | status = "okay"; | ||
32 | }; | ||
33 | rtc: rtc@d4010000 { | ||
34 | status = "okay"; | ||
35 | }; | ||
36 | }; | ||
37 | }; | ||
38 | }; | ||
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi new file mode 100644 index 000000000000..80f74e256408 --- /dev/null +++ b/arch/arm/boot/dts/mmp2.dtsi | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Marvell Technology Group Ltd. | ||
3 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * publishhed by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /include/ "skeleton.dtsi" | ||
11 | |||
12 | / { | ||
13 | aliases { | ||
14 | serial0 = &uart1; | ||
15 | serial1 = &uart2; | ||
16 | serial2 = &uart3; | ||
17 | serial3 = &uart4; | ||
18 | i2c0 = &twsi1; | ||
19 | i2c1 = &twsi2; | ||
20 | }; | ||
21 | |||
22 | soc { | ||
23 | #address-cells = <1>; | ||
24 | #size-cells = <1>; | ||
25 | compatible = "simple-bus"; | ||
26 | interrupt-parent = <&intc>; | ||
27 | ranges; | ||
28 | |||
29 | axi@d4200000 { /* AXI */ | ||
30 | compatible = "mrvl,axi-bus", "simple-bus"; | ||
31 | #address-cells = <1>; | ||
32 | #size-cells = <1>; | ||
33 | reg = <0xd4200000 0x00200000>; | ||
34 | ranges; | ||
35 | |||
36 | intc: interrupt-controller@d4282000 { | ||
37 | compatible = "mrvl,mmp2-intc"; | ||
38 | interrupt-controller; | ||
39 | #interrupt-cells = <1>; | ||
40 | reg = <0xd4282000 0x1000>; | ||
41 | mrvl,intc-nr-irqs = <64>; | ||
42 | }; | ||
43 | |||
44 | intcmux4@d4282150 { | ||
45 | compatible = "mrvl,mmp2-mux-intc"; | ||
46 | interrupts = <4>; | ||
47 | interrupt-controller; | ||
48 | #interrupt-cells = <1>; | ||
49 | reg = <0x150 0x4>, <0x168 0x4>; | ||
50 | reg-names = "mux status", "mux mask"; | ||
51 | mrvl,intc-nr-irqs = <2>; | ||
52 | }; | ||
53 | |||
54 | intcmux5: interrupt-controller@d4282154 { | ||
55 | compatible = "mrvl,mmp2-mux-intc"; | ||
56 | interrupts = <5>; | ||
57 | interrupt-controller; | ||
58 | #interrupt-cells = <1>; | ||
59 | reg = <0x154 0x4>, <0x16c 0x4>; | ||
60 | reg-names = "mux status", "mux mask"; | ||
61 | mrvl,intc-nr-irqs = <2>; | ||
62 | mrvl,clr-mfp-irq = <1>; | ||
63 | }; | ||
64 | |||
65 | intcmux9: interrupt-controller@d4282180 { | ||
66 | compatible = "mrvl,mmp2-mux-intc"; | ||
67 | interrupts = <9>; | ||
68 | interrupt-controller; | ||
69 | #interrupt-cells = <1>; | ||
70 | reg = <0x180 0x4>, <0x17c 0x4>; | ||
71 | reg-names = "mux status", "mux mask"; | ||
72 | mrvl,intc-nr-irqs = <3>; | ||
73 | }; | ||
74 | |||
75 | intcmux17: interrupt-controller@d4282158 { | ||
76 | compatible = "mrvl,mmp2-mux-intc"; | ||
77 | interrupts = <17>; | ||
78 | interrupt-controller; | ||
79 | #interrupt-cells = <1>; | ||
80 | reg = <0x158 0x4>, <0x170 0x4>; | ||
81 | reg-names = "mux status", "mux mask"; | ||
82 | mrvl,intc-nr-irqs = <5>; | ||
83 | }; | ||
84 | |||
85 | intcmux35: interrupt-controller@d428215c { | ||
86 | compatible = "mrvl,mmp2-mux-intc"; | ||
87 | interrupts = <35>; | ||
88 | interrupt-controller; | ||
89 | #interrupt-cells = <1>; | ||
90 | reg = <0x15c 0x4>, <0x174 0x4>; | ||
91 | reg-names = "mux status", "mux mask"; | ||
92 | mrvl,intc-nr-irqs = <15>; | ||
93 | }; | ||
94 | |||
95 | intcmux51: interrupt-controller@d4282160 { | ||
96 | compatible = "mrvl,mmp2-mux-intc"; | ||
97 | interrupts = <51>; | ||
98 | interrupt-controller; | ||
99 | #interrupt-cells = <1>; | ||
100 | reg = <0x160 0x4>, <0x178 0x4>; | ||
101 | reg-names = "mux status", "mux mask"; | ||
102 | mrvl,intc-nr-irqs = <2>; | ||
103 | }; | ||
104 | |||
105 | intcmux55: interrupt-controller@d4282188 { | ||
106 | compatible = "mrvl,mmp2-mux-intc"; | ||
107 | interrupts = <55>; | ||
108 | interrupt-controller; | ||
109 | #interrupt-cells = <1>; | ||
110 | reg = <0x188 0x4>, <0x184 0x4>; | ||
111 | reg-names = "mux status", "mux mask"; | ||
112 | mrvl,intc-nr-irqs = <2>; | ||
113 | }; | ||
114 | }; | ||
115 | |||
116 | apb@d4000000 { /* APB */ | ||
117 | compatible = "mrvl,apb-bus", "simple-bus"; | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <1>; | ||
120 | reg = <0xd4000000 0x00200000>; | ||
121 | ranges; | ||
122 | |||
123 | timer0: timer@d4014000 { | ||
124 | compatible = "mrvl,mmp-timer"; | ||
125 | reg = <0xd4014000 0x100>; | ||
126 | interrupts = <13>; | ||
127 | }; | ||
128 | |||
129 | uart1: uart@d4030000 { | ||
130 | compatible = "mrvl,mmp-uart"; | ||
131 | reg = <0xd4030000 0x1000>; | ||
132 | interrupts = <27>; | ||
133 | status = "disabled"; | ||
134 | }; | ||
135 | |||
136 | uart2: uart@d4017000 { | ||
137 | compatible = "mrvl,mmp-uart"; | ||
138 | reg = <0xd4017000 0x1000>; | ||
139 | interrupts = <28>; | ||
140 | status = "disabled"; | ||
141 | }; | ||
142 | |||
143 | uart3: uart@d4018000 { | ||
144 | compatible = "mrvl,mmp-uart"; | ||
145 | reg = <0xd4018000 0x1000>; | ||
146 | interrupts = <24>; | ||
147 | status = "disabled"; | ||
148 | }; | ||
149 | |||
150 | uart4: uart@d4016000 { | ||
151 | compatible = "mrvl,mmp-uart"; | ||
152 | reg = <0xd4016000 0x1000>; | ||
153 | interrupts = <46>; | ||
154 | status = "disabled"; | ||
155 | }; | ||
156 | |||
157 | gpio@d4019000 { | ||
158 | compatible = "mrvl,mmp-gpio"; | ||
159 | #address-cells = <1>; | ||
160 | #size-cells = <1>; | ||
161 | reg = <0xd4019000 0x1000>; | ||
162 | gpio-controller; | ||
163 | #gpio-cells = <2>; | ||
164 | interrupts = <49>; | ||
165 | interrupt-names = "gpio_mux"; | ||
166 | interrupt-controller; | ||
167 | #interrupt-cells = <1>; | ||
168 | ranges; | ||
169 | |||
170 | gcb0: gpio@d4019000 { | ||
171 | reg = <0xd4019000 0x4>; | ||
172 | }; | ||
173 | |||
174 | gcb1: gpio@d4019004 { | ||
175 | reg = <0xd4019004 0x4>; | ||
176 | }; | ||
177 | |||
178 | gcb2: gpio@d4019008 { | ||
179 | reg = <0xd4019008 0x4>; | ||
180 | }; | ||
181 | |||
182 | gcb3: gpio@d4019100 { | ||
183 | reg = <0xd4019100 0x4>; | ||
184 | }; | ||
185 | |||
186 | gcb4: gpio@d4019104 { | ||
187 | reg = <0xd4019104 0x4>; | ||
188 | }; | ||
189 | |||
190 | gcb5: gpio@d4019108 { | ||
191 | reg = <0xd4019108 0x4>; | ||
192 | }; | ||
193 | }; | ||
194 | |||
195 | twsi1: i2c@d4011000 { | ||
196 | compatible = "mrvl,mmp-twsi"; | ||
197 | reg = <0xd4011000 0x1000>; | ||
198 | interrupts = <7>; | ||
199 | mrvl,i2c-fast-mode; | ||
200 | status = "disabled"; | ||
201 | }; | ||
202 | |||
203 | twsi2: i2c@d4025000 { | ||
204 | compatible = "mrvl,mmp-twsi"; | ||
205 | reg = <0xd4025000 0x1000>; | ||
206 | interrupts = <58>; | ||
207 | status = "disabled"; | ||
208 | }; | ||
209 | |||
210 | rtc: rtc@d4010000 { | ||
211 | compatible = "mrvl,mmp-rtc"; | ||
212 | reg = <0xd4010000 0x1000>; | ||
213 | interrupts = <1 0>; | ||
214 | interrupt-names = "rtc 1Hz", "rtc alarm"; | ||
215 | interrupt-parent = <&intcmux5>; | ||
216 | status = "disabled"; | ||
217 | }; | ||
218 | }; | ||
219 | }; | ||
220 | }; | ||
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi index d32d5128f225..31a718696080 100644 --- a/arch/arm/boot/dts/pxa168.dtsi +++ b/arch/arm/boot/dts/pxa168.dtsi | |||
@@ -18,13 +18,6 @@ | |||
18 | i2c1 = &twsi2; | 18 | i2c1 = &twsi2; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | intc: intc-interrupt-controller@d4282000 { | ||
22 | compatible = "mrvl,mmp-intc", "mrvl,intc"; | ||
23 | interrupt-controller; | ||
24 | #interrupt-cells = <1>; | ||
25 | reg = <0xd4282000 0x1000>; | ||
26 | }; | ||
27 | |||
28 | soc { | 21 | soc { |
29 | #address-cells = <1>; | 22 | #address-cells = <1>; |
30 | #size-cells = <1>; | 23 | #size-cells = <1>; |
@@ -32,6 +25,23 @@ | |||
32 | interrupt-parent = <&intc>; | 25 | interrupt-parent = <&intc>; |
33 | ranges; | 26 | ranges; |
34 | 27 | ||
28 | axi@d4200000 { /* AXI */ | ||
29 | compatible = "mrvl,axi-bus", "simple-bus"; | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <1>; | ||
32 | reg = <0xd4200000 0x00200000>; | ||
33 | ranges; | ||
34 | |||
35 | intc: interrupt-controller@d4282000 { | ||
36 | compatible = "mrvl,mmp-intc"; | ||
37 | interrupt-controller; | ||
38 | #interrupt-cells = <1>; | ||
39 | reg = <0xd4282000 0x1000>; | ||
40 | mrvl,intc-nr-irqs = <64>; | ||
41 | }; | ||
42 | |||
43 | }; | ||
44 | |||
35 | apb@d4000000 { /* APB */ | 45 | apb@d4000000 { /* APB */ |
36 | compatible = "mrvl,apb-bus", "simple-bus"; | 46 | compatible = "mrvl,apb-bus", "simple-bus"; |
37 | #address-cells = <1>; | 47 | #address-cells = <1>; |
@@ -39,40 +49,65 @@ | |||
39 | reg = <0xd4000000 0x00200000>; | 49 | reg = <0xd4000000 0x00200000>; |
40 | ranges; | 50 | ranges; |
41 | 51 | ||
52 | timer0: timer@d4014000 { | ||
53 | compatible = "mrvl,mmp-timer"; | ||
54 | reg = <0xd4014000 0x100>; | ||
55 | interrupts = <13>; | ||
56 | }; | ||
57 | |||
42 | uart1: uart@d4017000 { | 58 | uart1: uart@d4017000 { |
43 | compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; | 59 | compatible = "mrvl,mmp-uart"; |
44 | reg = <0xd4017000 0x1000>; | 60 | reg = <0xd4017000 0x1000>; |
45 | interrupts = <27>; | 61 | interrupts = <27>; |
46 | status = "disabled"; | 62 | status = "disabled"; |
47 | }; | 63 | }; |
48 | 64 | ||
49 | uart2: uart@d4018000 { | 65 | uart2: uart@d4018000 { |
50 | compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; | 66 | compatible = "mrvl,mmp-uart"; |
51 | reg = <0xd4018000 0x1000>; | 67 | reg = <0xd4018000 0x1000>; |
52 | interrupts = <28>; | 68 | interrupts = <28>; |
53 | status = "disabled"; | 69 | status = "disabled"; |
54 | }; | 70 | }; |
55 | 71 | ||
56 | uart3: uart@d4026000 { | 72 | uart3: uart@d4026000 { |
57 | compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; | 73 | compatible = "mrvl,mmp-uart"; |
58 | reg = <0xd4026000 0x1000>; | 74 | reg = <0xd4026000 0x1000>; |
59 | interrupts = <29>; | 75 | interrupts = <29>; |
60 | status = "disabled"; | 76 | status = "disabled"; |
61 | }; | 77 | }; |
62 | 78 | ||
63 | gpio: gpio@d4019000 { | 79 | gpio@d4019000 { |
64 | compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio"; | 80 | compatible = "mrvl,mmp-gpio"; |
81 | #address-cells = <1>; | ||
82 | #size-cells = <1>; | ||
65 | reg = <0xd4019000 0x1000>; | 83 | reg = <0xd4019000 0x1000>; |
84 | gpio-controller; | ||
85 | #gpio-cells = <2>; | ||
66 | interrupts = <49>; | 86 | interrupts = <49>; |
67 | interrupt-names = "gpio_mux"; | 87 | interrupt-names = "gpio_mux"; |
68 | gpio-controller; | ||
69 | #gpio-cells = <1>; | ||
70 | interrupt-controller; | 88 | interrupt-controller; |
71 | #interrupt-cells = <1>; | 89 | #interrupt-cells = <1>; |
90 | ranges; | ||
91 | |||
92 | gcb0: gpio@d4019000 { | ||
93 | reg = <0xd4019000 0x4>; | ||
94 | }; | ||
95 | |||
96 | gcb1: gpio@d4019004 { | ||
97 | reg = <0xd4019004 0x4>; | ||
98 | }; | ||
99 | |||
100 | gcb2: gpio@d4019008 { | ||
101 | reg = <0xd4019008 0x4>; | ||
102 | }; | ||
103 | |||
104 | gcb3: gpio@d4019100 { | ||
105 | reg = <0xd4019100 0x4>; | ||
106 | }; | ||
72 | }; | 107 | }; |
73 | 108 | ||
74 | twsi1: i2c@d4011000 { | 109 | twsi1: i2c@d4011000 { |
75 | compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c"; | 110 | compatible = "mrvl,mmp-twsi"; |
76 | reg = <0xd4011000 0x1000>; | 111 | reg = <0xd4011000 0x1000>; |
77 | interrupts = <7>; | 112 | interrupts = <7>; |
78 | mrvl,i2c-fast-mode; | 113 | mrvl,i2c-fast-mode; |
@@ -80,7 +115,7 @@ | |||
80 | }; | 115 | }; |
81 | 116 | ||
82 | twsi2: i2c@d4025000 { | 117 | twsi2: i2c@d4025000 { |
83 | compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c"; | 118 | compatible = "mrvl,mmp-twsi"; |
84 | reg = <0xd4025000 0x1000>; | 119 | reg = <0xd4025000 0x1000>; |
85 | interrupts = <58>; | 120 | interrupts = <58>; |
86 | status = "disabled"; | 121 | status = "disabled"; |
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts new file mode 100644 index 000000000000..e92be5a474e7 --- /dev/null +++ b/arch/arm/boot/dts/pxa910-dkb.dts | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Marvell Technology Group Ltd. | ||
3 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * publishhed by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /dts-v1/; | ||
11 | /include/ "pxa910.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "Marvell PXA910 DKB Development Board"; | ||
15 | compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; | ||
16 | |||
17 | chosen { | ||
18 | bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on"; | ||
19 | }; | ||
20 | |||
21 | memory { | ||
22 | reg = <0x00000000 0x10000000>; | ||
23 | }; | ||
24 | |||
25 | soc { | ||
26 | apb@d4000000 { | ||
27 | uart1: uart@d4017000 { | ||
28 | status = "okay"; | ||
29 | }; | ||
30 | twsi1: i2c@d4011000 { | ||
31 | status = "okay"; | ||
32 | }; | ||
33 | rtc: rtc@d4010000 { | ||
34 | status = "okay"; | ||
35 | }; | ||
36 | }; | ||
37 | }; | ||
38 | }; | ||
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi new file mode 100644 index 000000000000..aebf32de73b4 --- /dev/null +++ b/arch/arm/boot/dts/pxa910.dtsi | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Marvell Technology Group Ltd. | ||
3 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * publishhed by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /include/ "skeleton.dtsi" | ||
11 | |||
12 | / { | ||
13 | aliases { | ||
14 | serial0 = &uart1; | ||
15 | serial1 = &uart2; | ||
16 | serial2 = &uart3; | ||
17 | i2c0 = &twsi1; | ||
18 | i2c1 = &twsi2; | ||
19 | }; | ||
20 | |||
21 | soc { | ||
22 | #address-cells = <1>; | ||
23 | #size-cells = <1>; | ||
24 | compatible = "simple-bus"; | ||
25 | interrupt-parent = <&intc>; | ||
26 | ranges; | ||
27 | |||
28 | axi@d4200000 { /* AXI */ | ||
29 | compatible = "mrvl,axi-bus", "simple-bus"; | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <1>; | ||
32 | reg = <0xd4200000 0x00200000>; | ||
33 | ranges; | ||
34 | |||
35 | intc: interrupt-controller@d4282000 { | ||
36 | compatible = "mrvl,mmp-intc"; | ||
37 | interrupt-controller; | ||
38 | #interrupt-cells = <1>; | ||
39 | reg = <0xd4282000 0x1000>; | ||
40 | mrvl,intc-nr-irqs = <64>; | ||
41 | }; | ||
42 | |||
43 | }; | ||
44 | |||
45 | apb@d4000000 { /* APB */ | ||
46 | compatible = "mrvl,apb-bus", "simple-bus"; | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <1>; | ||
49 | reg = <0xd4000000 0x00200000>; | ||
50 | ranges; | ||
51 | |||
52 | timer0: timer@d4014000 { | ||
53 | compatible = "mrvl,mmp-timer"; | ||
54 | reg = <0xd4014000 0x100>; | ||
55 | interrupts = <13>; | ||
56 | }; | ||
57 | |||
58 | timer1: timer@d4016000 { | ||
59 | compatible = "mrvl,mmp-timer"; | ||
60 | reg = <0xd4016000 0x100>; | ||
61 | interrupts = <29>; | ||
62 | status = "disabled"; | ||
63 | }; | ||
64 | |||
65 | uart1: uart@d4017000 { | ||
66 | compatible = "mrvl,mmp-uart"; | ||
67 | reg = <0xd4017000 0x1000>; | ||
68 | interrupts = <27>; | ||
69 | status = "disabled"; | ||
70 | }; | ||
71 | |||
72 | uart2: uart@d4018000 { | ||
73 | compatible = "mrvl,mmp-uart"; | ||
74 | reg = <0xd4018000 0x1000>; | ||
75 | interrupts = <28>; | ||
76 | status = "disabled"; | ||
77 | }; | ||
78 | |||
79 | uart3: uart@d4036000 { | ||
80 | compatible = "mrvl,mmp-uart"; | ||
81 | reg = <0xd4036000 0x1000>; | ||
82 | interrupts = <59>; | ||
83 | status = "disabled"; | ||
84 | }; | ||
85 | |||
86 | gpio@d4019000 { | ||
87 | compatible = "mrvl,mmp-gpio"; | ||
88 | #address-cells = <1>; | ||
89 | #size-cells = <1>; | ||
90 | reg = <0xd4019000 0x1000>; | ||
91 | gpio-controller; | ||
92 | #gpio-cells = <2>; | ||
93 | interrupts = <49>; | ||
94 | interrupt-names = "gpio_mux"; | ||
95 | interrupt-controller; | ||
96 | #interrupt-cells = <1>; | ||
97 | ranges; | ||
98 | |||
99 | gcb0: gpio@d4019000 { | ||
100 | reg = <0xd4019000 0x4>; | ||
101 | }; | ||
102 | |||
103 | gcb1: gpio@d4019004 { | ||
104 | reg = <0xd4019004 0x4>; | ||
105 | }; | ||
106 | |||
107 | gcb2: gpio@d4019008 { | ||
108 | reg = <0xd4019008 0x4>; | ||
109 | }; | ||
110 | |||
111 | gcb3: gpio@d4019100 { | ||
112 | reg = <0xd4019100 0x4>; | ||
113 | }; | ||
114 | }; | ||
115 | |||
116 | twsi1: i2c@d4011000 { | ||
117 | compatible = "mrvl,mmp-twsi"; | ||
118 | reg = <0xd4011000 0x1000>; | ||
119 | interrupts = <7>; | ||
120 | mrvl,i2c-fast-mode; | ||
121 | status = "disabled"; | ||
122 | }; | ||
123 | |||
124 | twsi2: i2c@d4037000 { | ||
125 | compatible = "mrvl,mmp-twsi"; | ||
126 | reg = <0xd4037000 0x1000>; | ||
127 | interrupts = <54>; | ||
128 | status = "disabled"; | ||
129 | }; | ||
130 | |||
131 | rtc: rtc@d4010000 { | ||
132 | compatible = "mrvl,mmp-rtc"; | ||
133 | reg = <0xd4010000 0x1000>; | ||
134 | interrupts = <5 6>; | ||
135 | interrupt-names = "rtc 1Hz", "rtc alarm"; | ||
136 | status = "disabled"; | ||
137 | }; | ||
138 | }; | ||
139 | }; | ||
140 | }; | ||
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 5a90b9a3ab6e..ede721628150 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig | |||
@@ -2,16 +2,6 @@ if ARCH_MMP | |||
2 | 2 | ||
3 | menu "Marvell PXA168/910/MMP2 Implmentations" | 3 | menu "Marvell PXA168/910/MMP2 Implmentations" |
4 | 4 | ||
5 | config MACH_MMP_DT | ||
6 | bool "Support MMP2 platforms from device tree" | ||
7 | select CPU_PXA168 | ||
8 | select CPU_PXA910 | ||
9 | select USE_OF | ||
10 | help | ||
11 | Include support for Marvell MMP2 based platforms using | ||
12 | the device tree. Needn't select any other machine while | ||
13 | MACH_MMP_DT is enabled. | ||
14 | |||
15 | config MACH_ASPENITE | 5 | config MACH_ASPENITE |
16 | bool "Marvell's PXA168 Aspenite Development Board" | 6 | bool "Marvell's PXA168 Aspenite Development Board" |
17 | select CPU_PXA168 | 7 | select CPU_PXA168 |
@@ -94,6 +84,25 @@ config MACH_GPLUGD | |||
94 | Say 'Y' here if you want to support the Marvell PXA168-based | 84 | Say 'Y' here if you want to support the Marvell PXA168-based |
95 | GuruPlug Display (gplugD) Board | 85 | GuruPlug Display (gplugD) Board |
96 | 86 | ||
87 | config MACH_MMP_DT | ||
88 | bool "Support MMP (ARMv5) platforms from device tree" | ||
89 | select CPU_PXA168 | ||
90 | select CPU_PXA910 | ||
91 | select USE_OF | ||
92 | help | ||
93 | Include support for Marvell MMP2 based platforms using | ||
94 | the device tree. Needn't select any other machine while | ||
95 | MACH_MMP_DT is enabled. | ||
96 | |||
97 | config MACH_MMP2_DT | ||
98 | bool "Support MMP2 (ARMv7) platforms from device tree" | ||
99 | depends on !CPU_MOHAWK | ||
100 | select CPU_MMP2 | ||
101 | select USE_OF | ||
102 | help | ||
103 | Include support for Marvell MMP2 based platforms using | ||
104 | the device tree. | ||
105 | |||
97 | endmenu | 106 | endmenu |
98 | 107 | ||
99 | config CPU_PXA168 | 108 | config CPU_PXA168 |
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 4fc0ff5dc96d..b920b9bfbdb6 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile | |||
@@ -2,12 +2,12 @@ | |||
2 | # Makefile for Marvell's PXA168 processors line | 2 | # Makefile for Marvell's PXA168 processors line |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += common.o clock.o devices.o time.o | 5 | obj-y += common.o clock.o devices.o time.o irq.o |
6 | 6 | ||
7 | # SoC support | 7 | # SoC support |
8 | obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o | 8 | obj-$(CONFIG_CPU_PXA168) += pxa168.o |
9 | obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o | 9 | obj-$(CONFIG_CPU_PXA910) += pxa910.o |
10 | obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o | 10 | obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o |
11 | 11 | ||
12 | # board support | 12 | # board support |
13 | obj-$(CONFIG_MACH_ASPENITE) += aspenite.o | 13 | obj-$(CONFIG_MACH_ASPENITE) += aspenite.o |
@@ -19,5 +19,6 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o | |||
19 | obj-$(CONFIG_MACH_FLINT) += flint.o | 19 | obj-$(CONFIG_MACH_FLINT) += flint.o |
20 | obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o | 20 | obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o |
21 | obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o | 21 | obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o |
22 | obj-$(CONFIG_MACH_MMP2_DT) += mmp2-dt.o | ||
22 | obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o | 23 | obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o |
23 | obj-$(CONFIG_MACH_GPLUGD) += gplugd.o | 24 | obj-$(CONFIG_MACH_GPLUGD) += gplugd.o |
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S index 9cff9e7a2b26..bd152e24e6d7 100644 --- a/arch/arm/mach-mmp/include/mach/entry-macro.S +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S | |||
@@ -6,13 +6,15 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <asm/irq.h> | ||
9 | #include <mach/regs-icu.h> | 10 | #include <mach/regs-icu.h> |
10 | 11 | ||
11 | .macro get_irqnr_preamble, base, tmp | 12 | .macro get_irqnr_preamble, base, tmp |
12 | mrc p15, 0, \tmp, c0, c0, 0 @ CPUID | 13 | mrc p15, 0, \tmp, c0, c0, 0 @ CPUID |
13 | and \tmp, \tmp, #0xff00 | 14 | and \tmp, \tmp, #0xff00 |
14 | cmp \tmp, #0x5800 | 15 | cmp \tmp, #0x5800 |
15 | ldr \base, =ICU_VIRT_BASE | 16 | ldr \base, =mmp_icu_base |
17 | ldr \base, [\base, #0] | ||
16 | addne \base, \base, #0x10c @ PJ1 AP INT SEL register | 18 | addne \base, \base, #0x10c @ PJ1 AP INT SEL register |
17 | addeq \base, \base, #0x104 @ PJ4 IRQ SEL register | 19 | addeq \base, \base, #0x104 @ PJ4 IRQ SEL register |
18 | .endm | 20 | .endm |
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index d0e746626a3d..fb492a50a817 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h | |||
@@ -125,7 +125,7 @@ | |||
125 | #define IRQ_MMP2_RTC_MUX 5 | 125 | #define IRQ_MMP2_RTC_MUX 5 |
126 | #define IRQ_MMP2_TWSI1 7 | 126 | #define IRQ_MMP2_TWSI1 7 |
127 | #define IRQ_MMP2_GPU 8 | 127 | #define IRQ_MMP2_GPU 8 |
128 | #define IRQ_MMP2_KEYPAD 9 | 128 | #define IRQ_MMP2_KEYPAD_MUX 9 |
129 | #define IRQ_MMP2_ROTARY 10 | 129 | #define IRQ_MMP2_ROTARY 10 |
130 | #define IRQ_MMP2_TRACKBALL 11 | 130 | #define IRQ_MMP2_TRACKBALL 11 |
131 | #define IRQ_MMP2_ONEWIRE 12 | 131 | #define IRQ_MMP2_ONEWIRE 12 |
@@ -163,11 +163,11 @@ | |||
163 | #define IRQ_MMP2_DMA_FIQ 47 | 163 | #define IRQ_MMP2_DMA_FIQ 47 |
164 | #define IRQ_MMP2_DMA_RIQ 48 | 164 | #define IRQ_MMP2_DMA_RIQ 48 |
165 | #define IRQ_MMP2_GPIO 49 | 165 | #define IRQ_MMP2_GPIO 49 |
166 | #define IRQ_MMP2_SSP_MUX 51 | 166 | #define IRQ_MMP2_MIPI_HSI1_MUX 51 |
167 | #define IRQ_MMP2_MMC2 52 | 167 | #define IRQ_MMP2_MMC2 52 |
168 | #define IRQ_MMP2_MMC3 53 | 168 | #define IRQ_MMP2_MMC3 53 |
169 | #define IRQ_MMP2_MMC4 54 | 169 | #define IRQ_MMP2_MMC4 54 |
170 | #define IRQ_MMP2_MIPI_HSI 55 | 170 | #define IRQ_MMP2_MIPI_HSI0_MUX 55 |
171 | #define IRQ_MMP2_MSP 58 | 171 | #define IRQ_MMP2_MSP 58 |
172 | #define IRQ_MMP2_MIPI_SLIM_DMA 59 | 172 | #define IRQ_MMP2_MIPI_SLIM_DMA 59 |
173 | #define IRQ_MMP2_PJ4_FREQ_CHG 60 | 173 | #define IRQ_MMP2_PJ4_FREQ_CHG 60 |
@@ -186,8 +186,14 @@ | |||
186 | #define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0) | 186 | #define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0) |
187 | #define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1) | 187 | #define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1) |
188 | 188 | ||
189 | /* secondary interrupt of INT #9 */ | ||
190 | #define IRQ_MMP2_KEYPAD_BASE (IRQ_MMP2_RTC_BASE + 2) | ||
191 | #define IRQ_MMP2_KPC (IRQ_MMP2_KEYPAD_BASE + 0) | ||
192 | #define IRQ_MMP2_ROTORY (IRQ_MMP2_KEYPAD_BASE + 1) | ||
193 | #define IRQ_MMP2_TBALL (IRQ_MMP2_KEYPAD_BASE + 2) | ||
194 | |||
189 | /* secondary interrupt of INT #17 */ | 195 | /* secondary interrupt of INT #17 */ |
190 | #define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2) | 196 | #define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_KEYPAD_BASE + 3) |
191 | #define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0) | 197 | #define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0) |
192 | #define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1) | 198 | #define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1) |
193 | #define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2) | 199 | #define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2) |
@@ -212,11 +218,16 @@ | |||
212 | #define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14) | 218 | #define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14) |
213 | 219 | ||
214 | /* secondary interrupt of INT #51 */ | 220 | /* secondary interrupt of INT #51 */ |
215 | #define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15) | 221 | #define IRQ_MMP2_MIPI_HSI1_BASE (IRQ_MMP2_MISC_BASE + 15) |
216 | #define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0) | 222 | #define IRQ_MMP2_HSI1_CAWAKE (IRQ_MMP2_MIPI_HSI1_BASE + 0) |
217 | #define IRQ_MMP2_SSP3_SRDY (IRQ_MMP2_SSP_BASE + 1) | 223 | #define IRQ_MMP2_MIPI_HSI_INT1 (IRQ_MMP2_MIPI_HSI1_BASE + 1) |
224 | |||
225 | /* secondary interrupt of INT #55 */ | ||
226 | #define IRQ_MMP2_MIPI_HSI0_BASE (IRQ_MMP2_MIPI_HSI1_BASE + 2) | ||
227 | #define IRQ_MMP2_HSI0_CAWAKE (IRQ_MMP2_MIPI_HSI0_BASE + 0) | ||
228 | #define IRQ_MMP2_MIPI_HSI_INT0 (IRQ_MMP2_MIPI_HSI0_BASE + 1) | ||
218 | 229 | ||
219 | #define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2) | 230 | #define IRQ_MMP2_MUX_END (IRQ_MMP2_MIPI_HSI0_BASE + 2) |
220 | 231 | ||
221 | #define IRQ_GPIO_START 128 | 232 | #define IRQ_GPIO_START 128 |
222 | #define MMP_NR_BUILTIN_GPIO 192 | 233 | #define MMP_NR_BUILTIN_GPIO 192 |
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c deleted file mode 100644 index 7895d277421e..000000000000 --- a/arch/arm/mach-mmp/irq-mmp2.c +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/irq-mmp2.c | ||
3 | * | ||
4 | * Generic IRQ handling, GPIO IRQ demultiplexing, etc. | ||
5 | * | ||
6 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
7 | * Copyright: Marvell International Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include <mach/irqs.h> | ||
19 | #include <mach/regs-icu.h> | ||
20 | #include <mach/mmp2.h> | ||
21 | |||
22 | #include "common.h" | ||
23 | |||
24 | static void icu_mask_irq(struct irq_data *d) | ||
25 | { | ||
26 | uint32_t r = __raw_readl(ICU_INT_CONF(d->irq)); | ||
27 | |||
28 | r &= ~ICU_INT_ROUTE_PJ4_IRQ; | ||
29 | __raw_writel(r, ICU_INT_CONF(d->irq)); | ||
30 | } | ||
31 | |||
32 | static void icu_unmask_irq(struct irq_data *d) | ||
33 | { | ||
34 | uint32_t r = __raw_readl(ICU_INT_CONF(d->irq)); | ||
35 | |||
36 | r |= ICU_INT_ROUTE_PJ4_IRQ; | ||
37 | __raw_writel(r, ICU_INT_CONF(d->irq)); | ||
38 | } | ||
39 | |||
40 | static struct irq_chip icu_irq_chip = { | ||
41 | .name = "icu_irq", | ||
42 | .irq_mask = icu_mask_irq, | ||
43 | .irq_mask_ack = icu_mask_irq, | ||
44 | .irq_unmask = icu_unmask_irq, | ||
45 | }; | ||
46 | |||
47 | static void pmic_irq_ack(struct irq_data *d) | ||
48 | { | ||
49 | if (d->irq == IRQ_MMP2_PMIC) | ||
50 | mmp2_clear_pmic_int(); | ||
51 | } | ||
52 | |||
53 | #define SECOND_IRQ_MASK(_name_, irq_base, prefix) \ | ||
54 | static void _name_##_mask_irq(struct irq_data *d) \ | ||
55 | { \ | ||
56 | uint32_t r; \ | ||
57 | r = __raw_readl(prefix##_MASK) | (1 << (d->irq - irq_base)); \ | ||
58 | __raw_writel(r, prefix##_MASK); \ | ||
59 | } | ||
60 | |||
61 | #define SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \ | ||
62 | static void _name_##_unmask_irq(struct irq_data *d) \ | ||
63 | { \ | ||
64 | uint32_t r; \ | ||
65 | r = __raw_readl(prefix##_MASK) & ~(1 << (d->irq - irq_base)); \ | ||
66 | __raw_writel(r, prefix##_MASK); \ | ||
67 | } | ||
68 | |||
69 | #define SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \ | ||
70 | static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc) \ | ||
71 | { \ | ||
72 | unsigned long status, mask, n; \ | ||
73 | mask = __raw_readl(prefix##_MASK); \ | ||
74 | while (1) { \ | ||
75 | status = __raw_readl(prefix##_STATUS) & ~mask; \ | ||
76 | if (status == 0) \ | ||
77 | break; \ | ||
78 | n = find_first_bit(&status, BITS_PER_LONG); \ | ||
79 | while (n < BITS_PER_LONG) { \ | ||
80 | generic_handle_irq(irq_base + n); \ | ||
81 | n = find_next_bit(&status, BITS_PER_LONG, n+1); \ | ||
82 | } \ | ||
83 | } \ | ||
84 | } | ||
85 | |||
86 | #define SECOND_IRQ_CHIP(_name_, irq_base, prefix) \ | ||
87 | SECOND_IRQ_MASK(_name_, irq_base, prefix) \ | ||
88 | SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \ | ||
89 | SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \ | ||
90 | static struct irq_chip _name_##_irq_chip = { \ | ||
91 | .name = #_name_, \ | ||
92 | .irq_mask = _name_##_mask_irq, \ | ||
93 | .irq_unmask = _name_##_unmask_irq, \ | ||
94 | } | ||
95 | |||
96 | SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4); | ||
97 | SECOND_IRQ_CHIP(rtc, IRQ_MMP2_RTC_BASE, MMP2_ICU_INT5); | ||
98 | SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17); | ||
99 | SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35); | ||
100 | SECOND_IRQ_CHIP(ssp, IRQ_MMP2_SSP_BASE, MMP2_ICU_INT51); | ||
101 | |||
102 | static void init_mux_irq(struct irq_chip *chip, int start, int num) | ||
103 | { | ||
104 | int irq; | ||
105 | |||
106 | for (irq = start; num > 0; irq++, num--) { | ||
107 | struct irq_data *d = irq_get_irq_data(irq); | ||
108 | |||
109 | /* mask and clear the IRQ */ | ||
110 | chip->irq_mask(d); | ||
111 | if (chip->irq_ack) | ||
112 | chip->irq_ack(d); | ||
113 | |||
114 | irq_set_chip(irq, chip); | ||
115 | set_irq_flags(irq, IRQF_VALID); | ||
116 | irq_set_handler(irq, handle_level_irq); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void __init mmp2_init_icu(void) | ||
121 | { | ||
122 | int irq; | ||
123 | |||
124 | for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) { | ||
125 | icu_mask_irq(irq_get_irq_data(irq)); | ||
126 | irq_set_chip(irq, &icu_irq_chip); | ||
127 | set_irq_flags(irq, IRQF_VALID); | ||
128 | |||
129 | switch (irq) { | ||
130 | case IRQ_MMP2_PMIC_MUX: | ||
131 | case IRQ_MMP2_RTC_MUX: | ||
132 | case IRQ_MMP2_TWSI_MUX: | ||
133 | case IRQ_MMP2_MISC_MUX: | ||
134 | case IRQ_MMP2_SSP_MUX: | ||
135 | break; | ||
136 | default: | ||
137 | irq_set_handler(irq, handle_level_irq); | ||
138 | break; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | /* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register | ||
143 | * to be written to clear the interrupt | ||
144 | */ | ||
145 | pmic_irq_chip.irq_ack = pmic_irq_ack; | ||
146 | |||
147 | init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2); | ||
148 | init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2); | ||
149 | init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5); | ||
150 | init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15); | ||
151 | init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2); | ||
152 | |||
153 | irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux); | ||
154 | irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux); | ||
155 | irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux); | ||
156 | irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux); | ||
157 | irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux); | ||
158 | } | ||
diff --git a/arch/arm/mach-mmp/irq-pxa168.c b/arch/arm/mach-mmp/irq-pxa168.c deleted file mode 100644 index 89706a0d08f1..000000000000 --- a/arch/arm/mach-mmp/irq-pxa168.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/irq.c | ||
3 | * | ||
4 | * Generic IRQ handling, GPIO IRQ demultiplexing, etc. | ||
5 | * | ||
6 | * Author: Bin Yang <bin.yang@marvell.com> | ||
7 | * Created: Sep 30, 2008 | ||
8 | * Copyright: Marvell International Ltd. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/regs-icu.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | |||
23 | #define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ) | ||
24 | |||
25 | #define PRIORITY_DEFAULT 0x1 | ||
26 | #define PRIORITY_NONE 0x0 /* means IRQ disabled */ | ||
27 | |||
28 | static void icu_mask_irq(struct irq_data *d) | ||
29 | { | ||
30 | __raw_writel(PRIORITY_NONE, ICU_INT_CONF(d->irq)); | ||
31 | } | ||
32 | |||
33 | static void icu_unmask_irq(struct irq_data *d) | ||
34 | { | ||
35 | __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(d->irq)); | ||
36 | } | ||
37 | |||
38 | static struct irq_chip icu_irq_chip = { | ||
39 | .name = "icu_irq", | ||
40 | .irq_ack = icu_mask_irq, | ||
41 | .irq_mask = icu_mask_irq, | ||
42 | .irq_unmask = icu_unmask_irq, | ||
43 | }; | ||
44 | |||
45 | void __init icu_init_irq(void) | ||
46 | { | ||
47 | int irq; | ||
48 | |||
49 | for (irq = 0; irq < 64; irq++) { | ||
50 | icu_mask_irq(irq_get_irq_data(irq)); | ||
51 | irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); | ||
52 | set_irq_flags(irq, IRQF_VALID); | ||
53 | } | ||
54 | } | ||
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c new file mode 100644 index 000000000000..3705470c9f1e --- /dev/null +++ b/arch/arm/mach-mmp/irq.c | |||
@@ -0,0 +1,445 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/irq.c | ||
3 | * | ||
4 | * Generic IRQ handling, GPIO IRQ demultiplexing, etc. | ||
5 | * Copyright (C) 2008 - 2012 Marvell Technology Group Ltd. | ||
6 | * | ||
7 | * Author: Bin Yang <bin.yang@marvell.com> | ||
8 | * Haojian Zhuang <haojian.zhuang@gmail.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/irqdomain.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/of_irq.h> | ||
23 | |||
24 | #include <mach/irqs.h> | ||
25 | |||
26 | #include "common.h" | ||
27 | |||
28 | #define MAX_ICU_NR 16 | ||
29 | |||
30 | struct icu_chip_data { | ||
31 | int nr_irqs; | ||
32 | unsigned int virq_base; | ||
33 | unsigned int cascade_irq; | ||
34 | void __iomem *reg_status; | ||
35 | void __iomem *reg_mask; | ||
36 | unsigned int conf_enable; | ||
37 | unsigned int conf_disable; | ||
38 | unsigned int conf_mask; | ||
39 | unsigned int clr_mfp_irq_base; | ||
40 | unsigned int clr_mfp_hwirq; | ||
41 | struct irq_domain *domain; | ||
42 | }; | ||
43 | |||
44 | struct mmp_intc_conf { | ||
45 | unsigned int conf_enable; | ||
46 | unsigned int conf_disable; | ||
47 | unsigned int conf_mask; | ||
48 | }; | ||
49 | |||
50 | void __iomem *mmp_icu_base; | ||
51 | static struct icu_chip_data icu_data[MAX_ICU_NR]; | ||
52 | static int max_icu_nr; | ||
53 | |||
54 | extern void mmp2_clear_pmic_int(void); | ||
55 | |||
56 | static void icu_mask_ack_irq(struct irq_data *d) | ||
57 | { | ||
58 | struct irq_domain *domain = d->domain; | ||
59 | struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data; | ||
60 | int hwirq; | ||
61 | u32 r; | ||
62 | |||
63 | hwirq = d->irq - data->virq_base; | ||
64 | if (data == &icu_data[0]) { | ||
65 | r = readl_relaxed(mmp_icu_base + (hwirq << 2)); | ||
66 | r &= ~data->conf_mask; | ||
67 | r |= data->conf_disable; | ||
68 | writel_relaxed(r, mmp_icu_base + (hwirq << 2)); | ||
69 | } else { | ||
70 | #ifdef CONFIG_CPU_MMP2 | ||
71 | if ((data->virq_base == data->clr_mfp_irq_base) | ||
72 | && (hwirq == data->clr_mfp_hwirq)) | ||
73 | mmp2_clear_pmic_int(); | ||
74 | #endif | ||
75 | r = readl_relaxed(data->reg_mask) | (1 << hwirq); | ||
76 | writel_relaxed(r, data->reg_mask); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | static void icu_mask_irq(struct irq_data *d) | ||
81 | { | ||
82 | struct irq_domain *domain = d->domain; | ||
83 | struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data; | ||
84 | int hwirq; | ||
85 | u32 r; | ||
86 | |||
87 | hwirq = d->irq - data->virq_base; | ||
88 | if (data == &icu_data[0]) { | ||
89 | r = readl_relaxed(mmp_icu_base + (hwirq << 2)); | ||
90 | r &= ~data->conf_mask; | ||
91 | r |= data->conf_disable; | ||
92 | writel_relaxed(r, mmp_icu_base + (hwirq << 2)); | ||
93 | } else { | ||
94 | r = readl_relaxed(data->reg_mask) | (1 << hwirq); | ||
95 | writel_relaxed(r, data->reg_mask); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static void icu_unmask_irq(struct irq_data *d) | ||
100 | { | ||
101 | struct irq_domain *domain = d->domain; | ||
102 | struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data; | ||
103 | int hwirq; | ||
104 | u32 r; | ||
105 | |||
106 | hwirq = d->irq - data->virq_base; | ||
107 | if (data == &icu_data[0]) { | ||
108 | r = readl_relaxed(mmp_icu_base + (hwirq << 2)); | ||
109 | r &= ~data->conf_mask; | ||
110 | r |= data->conf_enable; | ||
111 | writel_relaxed(r, mmp_icu_base + (hwirq << 2)); | ||
112 | } else { | ||
113 | r = readl_relaxed(data->reg_mask) & ~(1 << hwirq); | ||
114 | writel_relaxed(r, data->reg_mask); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static struct irq_chip icu_irq_chip = { | ||
119 | .name = "icu_irq", | ||
120 | .irq_mask = icu_mask_irq, | ||
121 | .irq_mask_ack = icu_mask_ack_irq, | ||
122 | .irq_unmask = icu_unmask_irq, | ||
123 | }; | ||
124 | |||
125 | static void icu_mux_irq_demux(unsigned int irq, struct irq_desc *desc) | ||
126 | { | ||
127 | struct irq_domain *domain; | ||
128 | struct icu_chip_data *data; | ||
129 | int i; | ||
130 | unsigned long mask, status, n; | ||
131 | |||
132 | for (i = 1; i < max_icu_nr; i++) { | ||
133 | if (irq == icu_data[i].cascade_irq) { | ||
134 | domain = icu_data[i].domain; | ||
135 | data = (struct icu_chip_data *)domain->host_data; | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | if (i >= max_icu_nr) { | ||
140 | pr_err("Spurious irq %d in MMP INTC\n", irq); | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | mask = readl_relaxed(data->reg_mask); | ||
145 | while (1) { | ||
146 | status = readl_relaxed(data->reg_status) & ~mask; | ||
147 | if (status == 0) | ||
148 | break; | ||
149 | n = find_first_bit(&status, BITS_PER_LONG); | ||
150 | while (n < BITS_PER_LONG) { | ||
151 | generic_handle_irq(icu_data[i].virq_base + n); | ||
152 | n = find_next_bit(&status, BITS_PER_LONG, n + 1); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
158 | irq_hw_number_t hw) | ||
159 | { | ||
160 | irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); | ||
161 | set_irq_flags(irq, IRQF_VALID); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int mmp_irq_domain_xlate(struct irq_domain *d, struct device_node *node, | ||
166 | const u32 *intspec, unsigned int intsize, | ||
167 | unsigned long *out_hwirq, | ||
168 | unsigned int *out_type) | ||
169 | { | ||
170 | *out_hwirq = intspec[0]; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | const struct irq_domain_ops mmp_irq_domain_ops = { | ||
175 | .map = mmp_irq_domain_map, | ||
176 | .xlate = mmp_irq_domain_xlate, | ||
177 | }; | ||
178 | |||
179 | static struct mmp_intc_conf mmp_conf = { | ||
180 | .conf_enable = 0x51, | ||
181 | .conf_disable = 0x0, | ||
182 | .conf_mask = 0x7f, | ||
183 | }; | ||
184 | |||
185 | static struct mmp_intc_conf mmp2_conf = { | ||
186 | .conf_enable = 0x20, | ||
187 | .conf_disable = 0x0, | ||
188 | .conf_mask = 0x7f, | ||
189 | }; | ||
190 | |||
191 | /* MMP (ARMv5) */ | ||
192 | void __init icu_init_irq(void) | ||
193 | { | ||
194 | int irq; | ||
195 | |||
196 | max_icu_nr = 1; | ||
197 | mmp_icu_base = ioremap(0xd4282000, 0x1000); | ||
198 | icu_data[0].conf_enable = mmp_conf.conf_enable; | ||
199 | icu_data[0].conf_disable = mmp_conf.conf_disable; | ||
200 | icu_data[0].conf_mask = mmp_conf.conf_mask; | ||
201 | icu_data[0].nr_irqs = 64; | ||
202 | icu_data[0].virq_base = 0; | ||
203 | icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0, | ||
204 | &irq_domain_simple_ops, | ||
205 | &icu_data[0]); | ||
206 | for (irq = 0; irq < 64; irq++) { | ||
207 | icu_mask_irq(irq_get_irq_data(irq)); | ||
208 | irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); | ||
209 | set_irq_flags(irq, IRQF_VALID); | ||
210 | } | ||
211 | irq_set_default_host(icu_data[0].domain); | ||
212 | } | ||
213 | |||
214 | /* MMP2 (ARMv7) */ | ||
215 | void __init mmp2_init_icu(void) | ||
216 | { | ||
217 | int irq; | ||
218 | |||
219 | max_icu_nr = 8; | ||
220 | mmp_icu_base = ioremap(0xd4282000, 0x1000); | ||
221 | icu_data[0].conf_enable = mmp2_conf.conf_enable; | ||
222 | icu_data[0].conf_disable = mmp2_conf.conf_disable; | ||
223 | icu_data[0].conf_mask = mmp2_conf.conf_mask; | ||
224 | icu_data[0].nr_irqs = 64; | ||
225 | icu_data[0].virq_base = 0; | ||
226 | icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0, | ||
227 | &irq_domain_simple_ops, | ||
228 | &icu_data[0]); | ||
229 | icu_data[1].reg_status = mmp_icu_base + 0x150; | ||
230 | icu_data[1].reg_mask = mmp_icu_base + 0x168; | ||
231 | icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; | ||
232 | icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; | ||
233 | icu_data[1].nr_irqs = 2; | ||
234 | icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; | ||
235 | icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, | ||
236 | icu_data[1].virq_base, 0, | ||
237 | &irq_domain_simple_ops, | ||
238 | &icu_data[1]); | ||
239 | icu_data[2].reg_status = mmp_icu_base + 0x154; | ||
240 | icu_data[2].reg_mask = mmp_icu_base + 0x16c; | ||
241 | icu_data[2].nr_irqs = 2; | ||
242 | icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; | ||
243 | icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, | ||
244 | icu_data[2].virq_base, 0, | ||
245 | &irq_domain_simple_ops, | ||
246 | &icu_data[2]); | ||
247 | icu_data[3].reg_status = mmp_icu_base + 0x180; | ||
248 | icu_data[3].reg_mask = mmp_icu_base + 0x17c; | ||
249 | icu_data[3].nr_irqs = 3; | ||
250 | icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; | ||
251 | icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, | ||
252 | icu_data[3].virq_base, 0, | ||
253 | &irq_domain_simple_ops, | ||
254 | &icu_data[3]); | ||
255 | icu_data[4].reg_status = mmp_icu_base + 0x158; | ||
256 | icu_data[4].reg_mask = mmp_icu_base + 0x170; | ||
257 | icu_data[4].nr_irqs = 5; | ||
258 | icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; | ||
259 | icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, | ||
260 | icu_data[4].virq_base, 0, | ||
261 | &irq_domain_simple_ops, | ||
262 | &icu_data[4]); | ||
263 | icu_data[5].reg_status = mmp_icu_base + 0x15c; | ||
264 | icu_data[5].reg_mask = mmp_icu_base + 0x174; | ||
265 | icu_data[5].nr_irqs = 15; | ||
266 | icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; | ||
267 | icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, | ||
268 | icu_data[5].virq_base, 0, | ||
269 | &irq_domain_simple_ops, | ||
270 | &icu_data[5]); | ||
271 | icu_data[6].reg_status = mmp_icu_base + 0x160; | ||
272 | icu_data[6].reg_mask = mmp_icu_base + 0x178; | ||
273 | icu_data[6].nr_irqs = 2; | ||
274 | icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; | ||
275 | icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, | ||
276 | icu_data[6].virq_base, 0, | ||
277 | &irq_domain_simple_ops, | ||
278 | &icu_data[6]); | ||
279 | icu_data[7].reg_status = mmp_icu_base + 0x188; | ||
280 | icu_data[7].reg_mask = mmp_icu_base + 0x184; | ||
281 | icu_data[7].nr_irqs = 2; | ||
282 | icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; | ||
283 | icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, | ||
284 | icu_data[7].virq_base, 0, | ||
285 | &irq_domain_simple_ops, | ||
286 | &icu_data[7]); | ||
287 | for (irq = 0; irq < IRQ_MMP2_MUX_END; irq++) { | ||
288 | icu_mask_irq(irq_get_irq_data(irq)); | ||
289 | switch (irq) { | ||
290 | case IRQ_MMP2_PMIC_MUX: | ||
291 | case IRQ_MMP2_RTC_MUX: | ||
292 | case IRQ_MMP2_KEYPAD_MUX: | ||
293 | case IRQ_MMP2_TWSI_MUX: | ||
294 | case IRQ_MMP2_MISC_MUX: | ||
295 | case IRQ_MMP2_MIPI_HSI1_MUX: | ||
296 | case IRQ_MMP2_MIPI_HSI0_MUX: | ||
297 | irq_set_chip(irq, &icu_irq_chip); | ||
298 | irq_set_chained_handler(irq, icu_mux_irq_demux); | ||
299 | break; | ||
300 | default: | ||
301 | irq_set_chip_and_handler(irq, &icu_irq_chip, | ||
302 | handle_level_irq); | ||
303 | break; | ||
304 | } | ||
305 | set_irq_flags(irq, IRQF_VALID); | ||
306 | } | ||
307 | irq_set_default_host(icu_data[0].domain); | ||
308 | } | ||
309 | |||
310 | #ifdef CONFIG_OF | ||
311 | static const struct of_device_id intc_ids[] __initconst = { | ||
312 | { .compatible = "mrvl,mmp-intc", .data = &mmp_conf }, | ||
313 | { .compatible = "mrvl,mmp2-intc", .data = &mmp2_conf }, | ||
314 | {} | ||
315 | }; | ||
316 | |||
317 | static const struct of_device_id mmp_mux_irq_match[] __initconst = { | ||
318 | { .compatible = "mrvl,mmp2-mux-intc" }, | ||
319 | {} | ||
320 | }; | ||
321 | |||
322 | int __init mmp2_mux_init(struct device_node *parent) | ||
323 | { | ||
324 | struct device_node *node; | ||
325 | const struct of_device_id *of_id; | ||
326 | struct resource res; | ||
327 | int i, irq_base, ret, irq; | ||
328 | u32 nr_irqs, mfp_irq; | ||
329 | |||
330 | node = parent; | ||
331 | max_icu_nr = 1; | ||
332 | for (i = 1; i < MAX_ICU_NR; i++) { | ||
333 | node = of_find_matching_node(node, mmp_mux_irq_match); | ||
334 | if (!node) | ||
335 | break; | ||
336 | of_id = of_match_node(&mmp_mux_irq_match[0], node); | ||
337 | ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", | ||
338 | &nr_irqs); | ||
339 | if (ret) { | ||
340 | pr_err("Not found mrvl,intc-nr-irqs property\n"); | ||
341 | ret = -EINVAL; | ||
342 | goto err; | ||
343 | } | ||
344 | ret = of_address_to_resource(node, 0, &res); | ||
345 | if (ret < 0) { | ||
346 | pr_err("Not found reg property\n"); | ||
347 | ret = -EINVAL; | ||
348 | goto err; | ||
349 | } | ||
350 | icu_data[i].reg_status = mmp_icu_base + res.start; | ||
351 | ret = of_address_to_resource(node, 1, &res); | ||
352 | if (ret < 0) { | ||
353 | pr_err("Not found reg property\n"); | ||
354 | ret = -EINVAL; | ||
355 | goto err; | ||
356 | } | ||
357 | icu_data[i].reg_mask = mmp_icu_base + res.start; | ||
358 | icu_data[i].cascade_irq = irq_of_parse_and_map(node, 0); | ||
359 | if (!icu_data[i].cascade_irq) { | ||
360 | ret = -EINVAL; | ||
361 | goto err; | ||
362 | } | ||
363 | |||
364 | irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); | ||
365 | if (irq_base < 0) { | ||
366 | pr_err("Failed to allocate IRQ numbers for mux intc\n"); | ||
367 | ret = irq_base; | ||
368 | goto err; | ||
369 | } | ||
370 | if (!of_property_read_u32(node, "mrvl,clr-mfp-irq", | ||
371 | &mfp_irq)) { | ||
372 | icu_data[i].clr_mfp_irq_base = irq_base; | ||
373 | icu_data[i].clr_mfp_hwirq = mfp_irq; | ||
374 | } | ||
375 | irq_set_chained_handler(icu_data[i].cascade_irq, | ||
376 | icu_mux_irq_demux); | ||
377 | icu_data[i].nr_irqs = nr_irqs; | ||
378 | icu_data[i].virq_base = irq_base; | ||
379 | icu_data[i].domain = irq_domain_add_legacy(node, nr_irqs, | ||
380 | irq_base, 0, | ||
381 | &mmp_irq_domain_ops, | ||
382 | &icu_data[i]); | ||
383 | for (irq = irq_base; irq < irq_base + nr_irqs; irq++) | ||
384 | icu_mask_irq(irq_get_irq_data(irq)); | ||
385 | } | ||
386 | max_icu_nr = i; | ||
387 | return 0; | ||
388 | err: | ||
389 | of_node_put(node); | ||
390 | max_icu_nr = i; | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | void __init mmp_dt_irq_init(void) | ||
395 | { | ||
396 | struct device_node *node; | ||
397 | const struct of_device_id *of_id; | ||
398 | struct mmp_intc_conf *conf; | ||
399 | int nr_irqs, irq_base, ret, irq; | ||
400 | |||
401 | node = of_find_matching_node(NULL, intc_ids); | ||
402 | if (!node) { | ||
403 | pr_err("Failed to find interrupt controller in arch-mmp\n"); | ||
404 | return; | ||
405 | } | ||
406 | of_id = of_match_node(intc_ids, node); | ||
407 | conf = of_id->data; | ||
408 | |||
409 | ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs); | ||
410 | if (ret) { | ||
411 | pr_err("Not found mrvl,intc-nr-irqs property\n"); | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | mmp_icu_base = of_iomap(node, 0); | ||
416 | if (!mmp_icu_base) { | ||
417 | pr_err("Failed to get interrupt controller register\n"); | ||
418 | return; | ||
419 | } | ||
420 | |||
421 | irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY, 0); | ||
422 | if (irq_base < 0) { | ||
423 | pr_err("Failed to allocate IRQ numbers\n"); | ||
424 | goto err; | ||
425 | } else if (irq_base != NR_IRQS_LEGACY) { | ||
426 | pr_err("ICU's irqbase should be started from 0\n"); | ||
427 | goto err; | ||
428 | } | ||
429 | icu_data[0].conf_enable = conf->conf_enable; | ||
430 | icu_data[0].conf_disable = conf->conf_disable; | ||
431 | icu_data[0].conf_mask = conf->conf_mask; | ||
432 | icu_data[0].nr_irqs = nr_irqs; | ||
433 | icu_data[0].virq_base = 0; | ||
434 | icu_data[0].domain = irq_domain_add_legacy(node, nr_irqs, 0, 0, | ||
435 | &mmp_irq_domain_ops, | ||
436 | &icu_data[0]); | ||
437 | irq_set_default_host(icu_data[0].domain); | ||
438 | for (irq = 0; irq < nr_irqs; irq++) | ||
439 | icu_mask_irq(irq_get_irq_data(irq)); | ||
440 | mmp2_mux_init(node); | ||
441 | return; | ||
442 | err: | ||
443 | iounmap(mmp_icu_base); | ||
444 | } | ||
445 | #endif | ||
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c index 67075395e400..033cc31b3c72 100644 --- a/arch/arm/mach-mmp/mmp-dt.c +++ b/arch/arm/mach-mmp/mmp-dt.c | |||
@@ -14,14 +14,19 @@ | |||
14 | #include <linux/of_irq.h> | 14 | #include <linux/of_irq.h> |
15 | #include <linux/of_platform.h> | 15 | #include <linux/of_platform.h> |
16 | #include <asm/mach/arch.h> | 16 | #include <asm/mach/arch.h> |
17 | #include <asm/mach/time.h> | ||
17 | #include <mach/irqs.h> | 18 | #include <mach/irqs.h> |
18 | 19 | ||
19 | #include "common.h" | 20 | #include "common.h" |
20 | 21 | ||
21 | extern struct sys_timer pxa168_timer; | 22 | extern void __init mmp_dt_irq_init(void); |
22 | extern void __init icu_init_irq(void); | 23 | extern void __init mmp_dt_init_timer(void); |
23 | 24 | ||
24 | static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { | 25 | static struct sys_timer mmp_dt_timer = { |
26 | .init = mmp_dt_init_timer, | ||
27 | }; | ||
28 | |||
29 | static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = { | ||
25 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), | 30 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), |
26 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), | 31 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), |
27 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), | 32 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), |
@@ -32,44 +37,47 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { | |||
32 | {} | 37 | {} |
33 | }; | 38 | }; |
34 | 39 | ||
35 | static int __init mmp_intc_add_irq_domain(struct device_node *np, | 40 | static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = { |
36 | struct device_node *parent) | 41 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), |
37 | { | 42 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), |
38 | irq_domain_add_simple(np, 0); | 43 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL), |
39 | return 0; | 44 | OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), |
40 | } | 45 | OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL), |
41 | 46 | OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), | |
42 | static int __init mmp_gpio_add_irq_domain(struct device_node *np, | 47 | OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), |
43 | struct device_node *parent) | ||
44 | { | ||
45 | irq_domain_add_simple(np, IRQ_GPIO_START); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static const struct of_device_id mmp_irq_match[] __initconst = { | ||
50 | { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, }, | ||
51 | { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, }, | ||
52 | {} | 48 | {} |
53 | }; | 49 | }; |
54 | 50 | ||
55 | static void __init mmp_dt_init(void) | 51 | static void __init pxa168_dt_init(void) |
56 | { | 52 | { |
53 | of_platform_populate(NULL, of_default_bus_match_table, | ||
54 | pxa168_auxdata_lookup, NULL); | ||
55 | } | ||
57 | 56 | ||
58 | of_irq_init(mmp_irq_match); | 57 | static void __init pxa910_dt_init(void) |
59 | 58 | { | |
60 | of_platform_populate(NULL, of_default_bus_match_table, | 59 | of_platform_populate(NULL, of_default_bus_match_table, |
61 | mmp_auxdata_lookup, NULL); | 60 | pxa910_auxdata_lookup, NULL); |
62 | } | 61 | } |
63 | 62 | ||
64 | static const char *pxa168_dt_board_compat[] __initdata = { | 63 | static const char *mmp_dt_board_compat[] __initdata = { |
65 | "mrvl,pxa168-aspenite", | 64 | "mrvl,pxa168-aspenite", |
65 | "mrvl,pxa910-dkb", | ||
66 | NULL, | 66 | NULL, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") | 69 | DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") |
70 | .map_io = mmp_map_io, | 70 | .map_io = mmp_map_io, |
71 | .init_irq = icu_init_irq, | 71 | .init_irq = mmp_dt_irq_init, |
72 | .timer = &pxa168_timer, | 72 | .timer = &mmp_dt_timer, |
73 | .init_machine = mmp_dt_init, | 73 | .init_machine = pxa168_dt_init, |
74 | .dt_compat = pxa168_dt_board_compat, | 74 | .dt_compat = mmp_dt_board_compat, |
75 | MACHINE_END | ||
76 | |||
77 | DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)") | ||
78 | .map_io = mmp_map_io, | ||
79 | .init_irq = mmp_dt_irq_init, | ||
80 | .timer = &mmp_dt_timer, | ||
81 | .init_machine = pxa910_dt_init, | ||
82 | .dt_compat = mmp_dt_board_compat, | ||
75 | MACHINE_END | 83 | MACHINE_END |
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c new file mode 100644 index 000000000000..535a5ed5977b --- /dev/null +++ b/arch/arm/mach-mmp/mmp2-dt.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/mmp2-dt.c | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell Technology Group Ltd. | ||
5 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * publishhed by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/io.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/irqdomain.h> | ||
15 | #include <linux/of_irq.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | #include <asm/mach/arch.h> | ||
18 | #include <asm/mach/time.h> | ||
19 | #include <mach/irqs.h> | ||
20 | #include <mach/regs-apbc.h> | ||
21 | |||
22 | #include "common.h" | ||
23 | |||
24 | extern void __init mmp_dt_irq_init(void); | ||
25 | extern void __init mmp_dt_init_timer(void); | ||
26 | |||
27 | static struct sys_timer mmp_dt_timer = { | ||
28 | .init = mmp_dt_init_timer, | ||
29 | }; | ||
30 | |||
31 | static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = { | ||
32 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL), | ||
33 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL), | ||
34 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL), | ||
35 | OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL), | ||
36 | OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), | ||
37 | OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), | ||
38 | OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), | ||
39 | OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), | ||
40 | {} | ||
41 | }; | ||
42 | |||
43 | static void __init mmp2_dt_init(void) | ||
44 | { | ||
45 | of_platform_populate(NULL, of_default_bus_match_table, | ||
46 | mmp2_auxdata_lookup, NULL); | ||
47 | } | ||
48 | |||
49 | static const char *mmp2_dt_board_compat[] __initdata = { | ||
50 | "mrvl,mmp2-brownstone", | ||
51 | NULL, | ||
52 | }; | ||
53 | |||
54 | DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)") | ||
55 | .map_io = mmp_map_io, | ||
56 | .init_irq = mmp_dt_irq_init, | ||
57 | .timer = &mmp_dt_timer, | ||
58 | .init_machine = mmp2_dt_init, | ||
59 | .dt_compat = mmp2_dt_board_compat, | ||
60 | MACHINE_END | ||
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 71fc4ee4602c..936447c70977 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c | |||
@@ -25,6 +25,9 @@ | |||
25 | 25 | ||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/of_irq.h> | ||
28 | 31 | ||
29 | #include <asm/sched_clock.h> | 32 | #include <asm/sched_clock.h> |
30 | #include <mach/addr-map.h> | 33 | #include <mach/addr-map.h> |
@@ -41,6 +44,8 @@ | |||
41 | #define MAX_DELTA (0xfffffffe) | 44 | #define MAX_DELTA (0xfffffffe) |
42 | #define MIN_DELTA (16) | 45 | #define MIN_DELTA (16) |
43 | 46 | ||
47 | static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; | ||
48 | |||
44 | /* | 49 | /* |
45 | * FIXME: the timer needs some delay to stablize the counter capture | 50 | * FIXME: the timer needs some delay to stablize the counter capture |
46 | */ | 51 | */ |
@@ -48,12 +53,12 @@ static inline uint32_t timer_read(void) | |||
48 | { | 53 | { |
49 | int delay = 100; | 54 | int delay = 100; |
50 | 55 | ||
51 | __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1)); | 56 | __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); |
52 | 57 | ||
53 | while (delay--) | 58 | while (delay--) |
54 | cpu_relax(); | 59 | cpu_relax(); |
55 | 60 | ||
56 | return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); | 61 | return __raw_readl(mmp_timer_base + TMR_CVWR(1)); |
57 | } | 62 | } |
58 | 63 | ||
59 | static u32 notrace mmp_read_sched_clock(void) | 64 | static u32 notrace mmp_read_sched_clock(void) |
@@ -68,12 +73,12 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
68 | /* | 73 | /* |
69 | * Clear pending interrupt status. | 74 | * Clear pending interrupt status. |
70 | */ | 75 | */ |
71 | __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); | 76 | __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); |
72 | 77 | ||
73 | /* | 78 | /* |
74 | * Disable timer 0. | 79 | * Disable timer 0. |
75 | */ | 80 | */ |
76 | __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); | 81 | __raw_writel(0x02, mmp_timer_base + TMR_CER); |
77 | 82 | ||
78 | c->event_handler(c); | 83 | c->event_handler(c); |
79 | 84 | ||
@@ -90,23 +95,23 @@ static int timer_set_next_event(unsigned long delta, | |||
90 | /* | 95 | /* |
91 | * Disable timer 0. | 96 | * Disable timer 0. |
92 | */ | 97 | */ |
93 | __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); | 98 | __raw_writel(0x02, mmp_timer_base + TMR_CER); |
94 | 99 | ||
95 | /* | 100 | /* |
96 | * Clear and enable timer match 0 interrupt. | 101 | * Clear and enable timer match 0 interrupt. |
97 | */ | 102 | */ |
98 | __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); | 103 | __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); |
99 | __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); | 104 | __raw_writel(0x01, mmp_timer_base + TMR_IER(0)); |
100 | 105 | ||
101 | /* | 106 | /* |
102 | * Setup new clockevent timer value. | 107 | * Setup new clockevent timer value. |
103 | */ | 108 | */ |
104 | __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); | 109 | __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0)); |
105 | 110 | ||
106 | /* | 111 | /* |
107 | * Enable timer 0. | 112 | * Enable timer 0. |
108 | */ | 113 | */ |
109 | __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER); | 114 | __raw_writel(0x03, mmp_timer_base + TMR_CER); |
110 | 115 | ||
111 | local_irq_restore(flags); | 116 | local_irq_restore(flags); |
112 | 117 | ||
@@ -124,7 +129,7 @@ static void timer_set_mode(enum clock_event_mode mode, | |||
124 | case CLOCK_EVT_MODE_UNUSED: | 129 | case CLOCK_EVT_MODE_UNUSED: |
125 | case CLOCK_EVT_MODE_SHUTDOWN: | 130 | case CLOCK_EVT_MODE_SHUTDOWN: |
126 | /* disable the matching interrupt */ | 131 | /* disable the matching interrupt */ |
127 | __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0)); | 132 | __raw_writel(0x00, mmp_timer_base + TMR_IER(0)); |
128 | break; | 133 | break; |
129 | case CLOCK_EVT_MODE_RESUME: | 134 | case CLOCK_EVT_MODE_RESUME: |
130 | case CLOCK_EVT_MODE_PERIODIC: | 135 | case CLOCK_EVT_MODE_PERIODIC: |
@@ -157,27 +162,27 @@ static struct clocksource cksrc = { | |||
157 | 162 | ||
158 | static void __init timer_config(void) | 163 | static void __init timer_config(void) |
159 | { | 164 | { |
160 | uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); | 165 | uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR); |
161 | 166 | ||
162 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */ | 167 | __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */ |
163 | 168 | ||
164 | ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : | 169 | ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : |
165 | (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); | 170 | (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); |
166 | __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); | 171 | __raw_writel(ccr, mmp_timer_base + TMR_CCR); |
167 | 172 | ||
168 | /* set timer 0 to periodic mode, and timer 1 to free-running mode */ | 173 | /* set timer 0 to periodic mode, and timer 1 to free-running mode */ |
169 | __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR); | 174 | __raw_writel(0x2, mmp_timer_base + TMR_CMR); |
170 | 175 | ||
171 | __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */ | 176 | __raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */ |
172 | __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ | 177 | __raw_writel(0x7, mmp_timer_base + TMR_ICR(0)); /* clear status */ |
173 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); | 178 | __raw_writel(0x0, mmp_timer_base + TMR_IER(0)); |
174 | 179 | ||
175 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */ | 180 | __raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */ |
176 | __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ | 181 | __raw_writel(0x7, mmp_timer_base + TMR_ICR(1)); /* clear status */ |
177 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); | 182 | __raw_writel(0x0, mmp_timer_base + TMR_IER(1)); |
178 | 183 | ||
179 | /* enable timer 1 counter */ | 184 | /* enable timer 1 counter */ |
180 | __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER); | 185 | __raw_writel(0x2, mmp_timer_base + TMR_CER); |
181 | } | 186 | } |
182 | 187 | ||
183 | static struct irqaction timer_irq = { | 188 | static struct irqaction timer_irq = { |
@@ -203,3 +208,37 @@ void __init timer_init(int irq) | |||
203 | clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); | 208 | clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); |
204 | clockevents_register_device(&ckevt); | 209 | clockevents_register_device(&ckevt); |
205 | } | 210 | } |
211 | |||
212 | #ifdef CONFIG_OF | ||
213 | static struct of_device_id mmp_timer_dt_ids[] = { | ||
214 | { .compatible = "mrvl,mmp-timer", }, | ||
215 | {} | ||
216 | }; | ||
217 | |||
218 | void __init mmp_dt_init_timer(void) | ||
219 | { | ||
220 | struct device_node *np; | ||
221 | int irq, ret; | ||
222 | |||
223 | np = of_find_matching_node(NULL, mmp_timer_dt_ids); | ||
224 | if (!np) { | ||
225 | ret = -ENODEV; | ||
226 | goto out; | ||
227 | } | ||
228 | |||
229 | irq = irq_of_parse_and_map(np, 0); | ||
230 | if (!irq) { | ||
231 | ret = -EINVAL; | ||
232 | goto out; | ||
233 | } | ||
234 | mmp_timer_base = of_iomap(np, 0); | ||
235 | if (!mmp_timer_base) { | ||
236 | ret = -ENOMEM; | ||
237 | goto out; | ||
238 | } | ||
239 | timer_init(irq); | ||
240 | return; | ||
241 | out: | ||
242 | pr_err("Failed to get timer from device tree with error:%d\n", ret); | ||
243 | } | ||
244 | #endif | ||