diff options
author | Olof Johansson <olof@lixom.net> | 2014-03-09 01:53:27 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2014-03-09 01:53:27 -0500 |
commit | ba0e1fa928e6e7a47d54008b1a701b02a858d0e4 (patch) | |
tree | 1678c0ca4697b7e698a0a162481eca28272758a1 | |
parent | cfbf8d4857c26a8a307fb7cd258074c9dcd8c691 (diff) | |
parent | 29525484cd2524a31ee0924831ab43b46ea6ebe1 (diff) |
Merge branch 'integrator/multiplatform-base' into next/cleanup2
* integrator/multiplatform-base:
ARM: integrator: select GPIO block
ARM: integrator: register the IM-PD1 VIC
ARM: integrator: use managed resources for the IM-PD1
irqchip: support cascaded VICs
irqchip: vic: update the base IRQ member correctly
clk: versatile: respect parent rate in ICST clock
clk: versatile: pass a parent to the ICST clock
ARM: integrator: switch to fetch clocks from device tree
ARM: SP804: make Integrator/CP timer pick clock from DT
ARM: integrator: define clocks in the device trees
-rw-r--r-- | Documentation/devicetree/bindings/clock/arm-integrator.txt | 34 | ||||
-rw-r--r-- | arch/arm/boot/dts/integratorap.dts | 35 | ||||
-rw-r--r-- | arch/arm/boot/dts/integratorcp.dts | 102 | ||||
-rw-r--r-- | arch/arm/common/timer-sp.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-integrator/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/mach-integrator/impd1.c | 81 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-versatile/core.c | 2 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-icst.c | 21 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-icst.h | 1 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-impd1.c | 6 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-integrator.c | 83 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-realview.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-vic.c | 59 | ||||
-rw-r--r-- | include/linux/irqchip/arm-vic.h | 6 | ||||
-rw-r--r-- | include/linux/platform_data/clk-integrator.h | 1 |
17 files changed, 353 insertions, 118 deletions
diff --git a/Documentation/devicetree/bindings/clock/arm-integrator.txt b/Documentation/devicetree/bindings/clock/arm-integrator.txt new file mode 100644 index 000000000000..652914b17b95 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/arm-integrator.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | Clock bindings for ARM Integrator Core Module clocks | ||
2 | |||
3 | Auxilary Oscillator Clock | ||
4 | |||
5 | This is a configurable clock fed from a 24 MHz chrystal, | ||
6 | used for generating e.g. video clocks. It is located on the | ||
7 | core module and there is only one of these. | ||
8 | |||
9 | This clock node *must* be a subnode of the core module, since | ||
10 | it obtains the base address for it's address range from its | ||
11 | parent node. | ||
12 | |||
13 | |||
14 | Required properties: | ||
15 | - compatible: must be "arm,integrator-cm-auxosc" | ||
16 | - #clock-cells: must be <0> | ||
17 | |||
18 | Optional properties: | ||
19 | - clocks: parent clock(s) | ||
20 | |||
21 | Example: | ||
22 | |||
23 | core-module@10000000 { | ||
24 | xtal24mhz: xtal24mhz@24M { | ||
25 | #clock-cells = <0>; | ||
26 | compatible = "fixed-clock"; | ||
27 | clock-frequency = <24000000>; | ||
28 | }; | ||
29 | auxosc: cm_aux_osc@25M { | ||
30 | #clock-cells = <0>; | ||
31 | compatible = "arm,integrator-cm-auxosc"; | ||
32 | clocks = <&xtal24mhz>; | ||
33 | }; | ||
34 | }; | ||
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index e6be9315ff0a..b10e6351da53 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts | |||
@@ -18,6 +18,28 @@ | |||
18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; | 18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | /* 24 MHz chrystal on the core module */ | ||
22 | xtal24mhz: xtal24mhz@24M { | ||
23 | #clock-cells = <0>; | ||
24 | compatible = "fixed-clock"; | ||
25 | clock-frequency = <24000000>; | ||
26 | }; | ||
27 | |||
28 | pclk: pclk@0 { | ||
29 | #clock-cells = <0>; | ||
30 | compatible = "fixed-factor-clock"; | ||
31 | clock-div = <1>; | ||
32 | clock-mult = <1>; | ||
33 | clocks = <&xtal24mhz>; | ||
34 | }; | ||
35 | |||
36 | /* The UART clock is 14.74 MHz divided by an ICS525 */ | ||
37 | uartclk: uartclk@14.74M { | ||
38 | #clock-cells = <0>; | ||
39 | compatible = "fixed-clock"; | ||
40 | clock-frequency = <14745600>; | ||
41 | }; | ||
42 | |||
21 | syscon { | 43 | syscon { |
22 | compatible = "arm,integrator-ap-syscon"; | 44 | compatible = "arm,integrator-ap-syscon"; |
23 | reg = <0x11000000 0x100>; | 45 | reg = <0x11000000 0x100>; |
@@ -28,14 +50,17 @@ | |||
28 | 50 | ||
29 | timer0: timer@13000000 { | 51 | timer0: timer@13000000 { |
30 | compatible = "arm,integrator-timer"; | 52 | compatible = "arm,integrator-timer"; |
53 | clocks = <&xtal24mhz>; | ||
31 | }; | 54 | }; |
32 | 55 | ||
33 | timer1: timer@13000100 { | 56 | timer1: timer@13000100 { |
34 | compatible = "arm,integrator-timer"; | 57 | compatible = "arm,integrator-timer"; |
58 | clocks = <&xtal24mhz>; | ||
35 | }; | 59 | }; |
36 | 60 | ||
37 | timer2: timer@13000200 { | 61 | timer2: timer@13000200 { |
38 | compatible = "arm,integrator-timer"; | 62 | compatible = "arm,integrator-timer"; |
63 | clocks = <&xtal24mhz>; | ||
39 | }; | 64 | }; |
40 | 65 | ||
41 | pic: pic@14000000 { | 66 | pic: pic@14000000 { |
@@ -92,26 +117,36 @@ | |||
92 | rtc: rtc@15000000 { | 117 | rtc: rtc@15000000 { |
93 | compatible = "arm,pl030", "arm,primecell"; | 118 | compatible = "arm,pl030", "arm,primecell"; |
94 | arm,primecell-periphid = <0x00041030>; | 119 | arm,primecell-periphid = <0x00041030>; |
120 | clocks = <&pclk>; | ||
121 | clock-names = "apb_pclk"; | ||
95 | }; | 122 | }; |
96 | 123 | ||
97 | uart0: uart@16000000 { | 124 | uart0: uart@16000000 { |
98 | compatible = "arm,pl010", "arm,primecell"; | 125 | compatible = "arm,pl010", "arm,primecell"; |
99 | arm,primecell-periphid = <0x00041010>; | 126 | arm,primecell-periphid = <0x00041010>; |
127 | clocks = <&uartclk>, <&pclk>; | ||
128 | clock-names = "uartclk", "apb_pclk"; | ||
100 | }; | 129 | }; |
101 | 130 | ||
102 | uart1: uart@17000000 { | 131 | uart1: uart@17000000 { |
103 | compatible = "arm,pl010", "arm,primecell"; | 132 | compatible = "arm,pl010", "arm,primecell"; |
104 | arm,primecell-periphid = <0x00041010>; | 133 | arm,primecell-periphid = <0x00041010>; |
134 | clocks = <&uartclk>, <&pclk>; | ||
135 | clock-names = "uartclk", "apb_pclk"; | ||
105 | }; | 136 | }; |
106 | 137 | ||
107 | kmi0: kmi@18000000 { | 138 | kmi0: kmi@18000000 { |
108 | compatible = "arm,pl050", "arm,primecell"; | 139 | compatible = "arm,pl050", "arm,primecell"; |
109 | arm,primecell-periphid = <0x00041050>; | 140 | arm,primecell-periphid = <0x00041050>; |
141 | clocks = <&xtal24mhz>, <&pclk>; | ||
142 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
110 | }; | 143 | }; |
111 | 144 | ||
112 | kmi1: kmi@19000000 { | 145 | kmi1: kmi@19000000 { |
113 | compatible = "arm,pl050", "arm,primecell"; | 146 | compatible = "arm,pl050", "arm,primecell"; |
114 | arm,primecell-periphid = <0x00041050>; | 147 | arm,primecell-periphid = <0x00041050>; |
148 | clocks = <&xtal24mhz>, <&pclk>; | ||
149 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
115 | }; | 150 | }; |
116 | }; | 151 | }; |
117 | }; | 152 | }; |
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index a21c17de9a5e..d43f15b4f79a 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts | |||
@@ -13,25 +13,107 @@ | |||
13 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; | 13 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | /* | ||
17 | * The Integrator/CP overall clocking architecture can be found in | ||
18 | * ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which | ||
19 | * appear to illustrate the layout used in most configurations. | ||
20 | */ | ||
21 | |||
22 | /* The codec chrystal operates at 24.576 MHz */ | ||
23 | xtal_codec: xtal24.576@24.576M { | ||
24 | #clock-cells = <0>; | ||
25 | compatible = "fixed-clock"; | ||
26 | clock-frequency = <24576000>; | ||
27 | }; | ||
28 | |||
29 | /* The chrystal is divided by 2 by the codec for the AACI bit clock */ | ||
30 | aaci_bitclk: aaci_bitclk@12.288M { | ||
31 | #clock-cells = <0>; | ||
32 | compatible = "fixed-factor-clock"; | ||
33 | clock-div = <2>; | ||
34 | clock-mult = <1>; | ||
35 | clocks = <&xtal_codec>; | ||
36 | }; | ||
37 | |||
38 | /* This is a 25MHz chrystal on the base board */ | ||
39 | xtal25mhz: xtal25mhz@25M { | ||
40 | #clock-cells = <0>; | ||
41 | compatible = "fixed-clock"; | ||
42 | clock-frequency = <25000000>; | ||
43 | }; | ||
44 | |||
45 | /* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */ | ||
46 | uartclk: uartclk@14.74M { | ||
47 | #clock-cells = <0>; | ||
48 | compatible = "fixed-clock"; | ||
49 | clock-frequency = <14745600>; | ||
50 | }; | ||
51 | |||
52 | /* Actually sysclk I think */ | ||
53 | pclk: pclk@0 { | ||
54 | #clock-cells = <0>; | ||
55 | compatible = "fixed-clock"; | ||
56 | clock-frequency = <0>; | ||
57 | }; | ||
58 | |||
59 | core-module@10000000 { | ||
60 | /* 24 MHz chrystal on the core module */ | ||
61 | xtal24mhz: xtal24mhz@24M { | ||
62 | #clock-cells = <0>; | ||
63 | compatible = "fixed-clock"; | ||
64 | clock-frequency = <24000000>; | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * External oscillator on the core module, usually used | ||
69 | * to drive video circuitry. Driven from the 24MHz clock. | ||
70 | */ | ||
71 | auxosc: cm_aux_osc@25M { | ||
72 | #clock-cells = <0>; | ||
73 | compatible = "arm,integrator-cm-auxosc"; | ||
74 | clocks = <&xtal24mhz>; | ||
75 | }; | ||
76 | |||
77 | /* The KMI clock is the 24 MHz oscillator divided to 8MHz */ | ||
78 | kmiclk: kmiclk@1M { | ||
79 | #clock-cells = <0>; | ||
80 | compatible = "fixed-factor-clock"; | ||
81 | clock-div = <3>; | ||
82 | clock-mult = <1>; | ||
83 | clocks = <&xtal24mhz>; | ||
84 | }; | ||
85 | |||
86 | /* The timer clock is the 24 MHz oscillator divided to 1MHz */ | ||
87 | timclk: timclk@1M { | ||
88 | #clock-cells = <0>; | ||
89 | compatible = "fixed-factor-clock"; | ||
90 | clock-div = <24>; | ||
91 | clock-mult = <1>; | ||
92 | clocks = <&xtal24mhz>; | ||
93 | }; | ||
94 | }; | ||
95 | |||
16 | syscon { | 96 | syscon { |
17 | compatible = "arm,integrator-cp-syscon"; | 97 | compatible = "arm,integrator-cp-syscon"; |
18 | reg = <0xcb000000 0x100>; | 98 | reg = <0xcb000000 0x100>; |
19 | }; | 99 | }; |
20 | 100 | ||
21 | timer0: timer@13000000 { | 101 | timer0: timer@13000000 { |
22 | /* TIMER0 runs @ 25MHz */ | 102 | /* TIMER0 runs directly on the 25MHz chrystal */ |
23 | compatible = "arm,integrator-cp-timer"; | 103 | compatible = "arm,integrator-cp-timer"; |
24 | status = "disabled"; | 104 | clocks = <&xtal25mhz>; |
25 | }; | 105 | }; |
26 | 106 | ||
27 | timer1: timer@13000100 { | 107 | timer1: timer@13000100 { |
28 | /* TIMER1 runs @ 1MHz */ | 108 | /* TIMER1 runs @ 1MHz */ |
29 | compatible = "arm,integrator-cp-timer"; | 109 | compatible = "arm,integrator-cp-timer"; |
110 | clocks = <&timclk>; | ||
30 | }; | 111 | }; |
31 | 112 | ||
32 | timer2: timer@13000200 { | 113 | timer2: timer@13000200 { |
33 | /* TIMER2 runs @ 1MHz */ | 114 | /* TIMER2 runs @ 1MHz */ |
34 | compatible = "arm,integrator-cp-timer"; | 115 | compatible = "arm,integrator-cp-timer"; |
116 | clocks = <&timclk>; | ||
35 | }; | 117 | }; |
36 | 118 | ||
37 | pic: pic@14000000 { | 119 | pic: pic@14000000 { |
@@ -74,22 +156,32 @@ | |||
74 | */ | 156 | */ |
75 | rtc@15000000 { | 157 | rtc@15000000 { |
76 | compatible = "arm,pl031", "arm,primecell"; | 158 | compatible = "arm,pl031", "arm,primecell"; |
159 | clocks = <&pclk>; | ||
160 | clock-names = "apb_pclk"; | ||
77 | }; | 161 | }; |
78 | 162 | ||
79 | uart@16000000 { | 163 | uart@16000000 { |
80 | compatible = "arm,pl011", "arm,primecell"; | 164 | compatible = "arm,pl011", "arm,primecell"; |
165 | clocks = <&uartclk>, <&pclk>; | ||
166 | clock-names = "uartclk", "apb_pclk"; | ||
81 | }; | 167 | }; |
82 | 168 | ||
83 | uart@17000000 { | 169 | uart@17000000 { |
84 | compatible = "arm,pl011", "arm,primecell"; | 170 | compatible = "arm,pl011", "arm,primecell"; |
171 | clocks = <&uartclk>, <&pclk>; | ||
172 | clock-names = "uartclk", "apb_pclk"; | ||
85 | }; | 173 | }; |
86 | 174 | ||
87 | kmi@18000000 { | 175 | kmi@18000000 { |
88 | compatible = "arm,pl050", "arm,primecell"; | 176 | compatible = "arm,pl050", "arm,primecell"; |
177 | clocks = <&kmiclk>, <&pclk>; | ||
178 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
89 | }; | 179 | }; |
90 | 180 | ||
91 | kmi@19000000 { | 181 | kmi@19000000 { |
92 | compatible = "arm,pl050", "arm,primecell"; | 182 | compatible = "arm,pl050", "arm,primecell"; |
183 | clocks = <&kmiclk>, <&pclk>; | ||
184 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
93 | }; | 185 | }; |
94 | 186 | ||
95 | /* | 187 | /* |
@@ -100,18 +192,24 @@ | |||
100 | reg = <0x1c000000 0x1000>; | 192 | reg = <0x1c000000 0x1000>; |
101 | interrupts = <23 24>; | 193 | interrupts = <23 24>; |
102 | max-frequency = <515633>; | 194 | max-frequency = <515633>; |
195 | clocks = <&uartclk>, <&pclk>; | ||
196 | clock-names = "mclk", "apb_pclk"; | ||
103 | }; | 197 | }; |
104 | 198 | ||
105 | aaci@1d000000 { | 199 | aaci@1d000000 { |
106 | compatible = "arm,pl041", "arm,primecell"; | 200 | compatible = "arm,pl041", "arm,primecell"; |
107 | reg = <0x1d000000 0x1000>; | 201 | reg = <0x1d000000 0x1000>; |
108 | interrupts = <25>; | 202 | interrupts = <25>; |
203 | clocks = <&pclk>; | ||
204 | clock-names = "apb_pclk"; | ||
109 | }; | 205 | }; |
110 | 206 | ||
111 | clcd@c0000000 { | 207 | clcd@c0000000 { |
112 | compatible = "arm,pl110", "arm,primecell"; | 208 | compatible = "arm,pl110", "arm,primecell"; |
113 | reg = <0xC0000000 0x1000>; | 209 | reg = <0xC0000000 0x1000>; |
114 | interrupts = <22>; | 210 | interrupts = <22>; |
211 | clocks = <&auxosc>, <&pclk>; | ||
212 | clock-names = "clcd", "apb_pclk"; | ||
115 | }; | 213 | }; |
116 | }; | 214 | }; |
117 | }; | 215 | }; |
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index 53c6a26b633d..fd6bff0c5b96 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c | |||
@@ -271,10 +271,14 @@ static void __init integrator_cp_of_init(struct device_node *np) | |||
271 | void __iomem *base; | 271 | void __iomem *base; |
272 | int irq; | 272 | int irq; |
273 | const char *name = of_get_property(np, "compatible", NULL); | 273 | const char *name = of_get_property(np, "compatible", NULL); |
274 | struct clk *clk; | ||
274 | 275 | ||
275 | base = of_iomap(np, 0); | 276 | base = of_iomap(np, 0); |
276 | if (WARN_ON(!base)) | 277 | if (WARN_ON(!base)) |
277 | return; | 278 | return; |
279 | clk = of_clk_get(np, 0); | ||
280 | if (WARN_ON(IS_ERR(clk))) | ||
281 | return; | ||
278 | 282 | ||
279 | /* Ensure timer is disabled */ | 283 | /* Ensure timer is disabled */ |
280 | writel(0, base + TIMER_CTRL); | 284 | writel(0, base + TIMER_CTRL); |
@@ -283,13 +287,13 @@ static void __init integrator_cp_of_init(struct device_node *np) | |||
283 | goto err; | 287 | goto err; |
284 | 288 | ||
285 | if (!init_count) | 289 | if (!init_count) |
286 | sp804_clocksource_init(base, name); | 290 | __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); |
287 | else { | 291 | else { |
288 | irq = irq_of_parse_and_map(np, 0); | 292 | irq = irq_of_parse_and_map(np, 0); |
289 | if (irq <= 0) | 293 | if (irq <= 0) |
290 | goto err; | 294 | goto err; |
291 | 295 | ||
292 | sp804_clockevents_init(base, irq, name); | 296 | __sp804_clockevents_init(base, irq, clk, name); |
293 | } | 297 | } |
294 | 298 | ||
295 | init_count++; | 299 | init_count++; |
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index abeff25532ab..6e8b0e10b420 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig | |||
@@ -30,6 +30,9 @@ config ARCH_CINTEGRATOR | |||
30 | config INTEGRATOR_IMPD1 | 30 | config INTEGRATOR_IMPD1 |
31 | tristate "Include support for Integrator/IM-PD1" | 31 | tristate "Include support for Integrator/IM-PD1" |
32 | depends on ARCH_INTEGRATOR_AP | 32 | depends on ARCH_INTEGRATOR_AP |
33 | select ARCH_REQUIRE_GPIOLIB | ||
34 | select ARM_VIC | ||
35 | select GPIO_PL061 if GPIOLIB | ||
33 | help | 36 | help |
34 | The IM-PD1 is an add-on logic module for the Integrator which | 37 | The IM-PD1 is an add-on logic module for the Integrator which |
35 | allows ARM(R) Ltd PrimeCells to be developed and evaluated. | 38 | allows ARM(R) Ltd PrimeCells to be developed and evaluated. |
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 9f82f9dcbb98..d9b784824808 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/platform_data/clk-integrator.h> | 24 | #include <linux/platform_data/clk-integrator.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/irqchip/arm-vic.h> | ||
26 | 27 | ||
27 | #include <mach/lm.h> | 28 | #include <mach/lm.h> |
28 | #include <mach/impd1.h> | 29 | #include <mach/impd1.h> |
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); | |||
35 | 36 | ||
36 | struct impd1_module { | 37 | struct impd1_module { |
37 | void __iomem *base; | 38 | void __iomem *base; |
39 | void __iomem *vic_base; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) | 42 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) |
@@ -262,9 +264,6 @@ struct impd1_device { | |||
262 | 264 | ||
263 | static struct impd1_device impd1_devs[] = { | 265 | static struct impd1_device impd1_devs[] = { |
264 | { | 266 | { |
265 | .offset = 0x03000000, | ||
266 | .id = 0x00041190, | ||
267 | }, { | ||
268 | .offset = 0x00100000, | 267 | .offset = 0x00100000, |
269 | .irq = { 1 }, | 268 | .irq = { 1 }, |
270 | .id = 0x00141011, | 269 | .id = 0x00141011, |
@@ -304,46 +303,72 @@ static struct impd1_device impd1_devs[] = { | |||
304 | } | 303 | } |
305 | }; | 304 | }; |
306 | 305 | ||
307 | static int impd1_probe(struct lm_device *dev) | 306 | /* |
307 | * Valid IRQs: 0 thru 9 and 11, 10 unused. | ||
308 | */ | ||
309 | #define IMPD1_VALID_IRQS 0x00000bffU | ||
310 | |||
311 | static int __init impd1_probe(struct lm_device *dev) | ||
308 | { | 312 | { |
309 | struct impd1_module *impd1; | 313 | struct impd1_module *impd1; |
310 | int i, ret; | 314 | int irq_base; |
315 | int i; | ||
311 | 316 | ||
312 | if (dev->id != module_id) | 317 | if (dev->id != module_id) |
313 | return -EINVAL; | 318 | return -EINVAL; |
314 | 319 | ||
315 | if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers")) | 320 | if (!devm_request_mem_region(&dev->dev, dev->resource.start, |
321 | SZ_4K, "LM registers")) | ||
316 | return -EBUSY; | 322 | return -EBUSY; |
317 | 323 | ||
318 | impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL); | 324 | impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module), |
319 | if (!impd1) { | 325 | GFP_KERNEL); |
320 | ret = -ENOMEM; | 326 | if (!impd1) |
321 | goto release_lm; | 327 | return -ENOMEM; |
322 | } | ||
323 | 328 | ||
324 | impd1->base = ioremap(dev->resource.start, SZ_4K); | 329 | impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K); |
325 | if (!impd1->base) { | 330 | if (!impd1->base) |
326 | ret = -ENOMEM; | 331 | return -ENOMEM; |
327 | goto free_impd1; | ||
328 | } | ||
329 | 332 | ||
330 | lm_set_drvdata(dev, impd1); | 333 | integrator_impd1_clk_init(impd1->base, dev->id); |
331 | 334 | ||
332 | printk("IM-PD1 found at 0x%08lx\n", | 335 | if (!devm_request_mem_region(&dev->dev, |
333 | (unsigned long)dev->resource.start); | 336 | dev->resource.start + 0x03000000, |
337 | SZ_4K, "VIC")) | ||
338 | return -EBUSY; | ||
334 | 339 | ||
335 | integrator_impd1_clk_init(impd1->base, dev->id); | 340 | impd1->vic_base = devm_ioremap(&dev->dev, |
341 | dev->resource.start + 0x03000000, | ||
342 | SZ_4K); | ||
343 | if (!impd1->vic_base) | ||
344 | return -ENOMEM; | ||
345 | |||
346 | irq_base = vic_init_cascaded(impd1->vic_base, dev->irq, | ||
347 | IMPD1_VALID_IRQS, 0); | ||
348 | |||
349 | lm_set_drvdata(dev, impd1); | ||
350 | |||
351 | dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n", | ||
352 | (unsigned long)dev->resource.start); | ||
336 | 353 | ||
337 | for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { | 354 | for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { |
338 | struct impd1_device *idev = impd1_devs + i; | 355 | struct impd1_device *idev = impd1_devs + i; |
339 | struct amba_device *d; | 356 | struct amba_device *d; |
340 | unsigned long pc_base; | 357 | unsigned long pc_base; |
341 | char devname[32]; | 358 | char devname[32]; |
359 | int irq1 = idev->irq[0]; | ||
360 | int irq2 = idev->irq[1]; | ||
361 | |||
362 | /* Translate IRQs to IM-PD1 local numberspace */ | ||
363 | if (irq1) | ||
364 | irq1 += irq_base; | ||
365 | if (irq2) | ||
366 | irq2 += irq_base; | ||
342 | 367 | ||
343 | pc_base = dev->resource.start + idev->offset; | 368 | pc_base = dev->resource.start + idev->offset; |
344 | snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); | 369 | snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); |
345 | d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, | 370 | d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, |
346 | dev->irq, dev->irq, | 371 | irq1, irq2, |
347 | idev->platform_data, idev->id, | 372 | idev->platform_data, idev->id, |
348 | &dev->resource); | 373 | &dev->resource); |
349 | if (IS_ERR(d)) { | 374 | if (IS_ERR(d)) { |
@@ -353,14 +378,6 @@ static int impd1_probe(struct lm_device *dev) | |||
353 | } | 378 | } |
354 | 379 | ||
355 | return 0; | 380 | return 0; |
356 | |||
357 | free_impd1: | ||
358 | if (impd1 && impd1->base) | ||
359 | iounmap(impd1->base); | ||
360 | kfree(impd1); | ||
361 | release_lm: | ||
362 | release_mem_region(dev->resource.start, SZ_4K); | ||
363 | return ret; | ||
364 | } | 381 | } |
365 | 382 | ||
366 | static int impd1_remove_one(struct device *dev, void *data) | 383 | static int impd1_remove_one(struct device *dev, void *data) |
@@ -371,16 +388,10 @@ static int impd1_remove_one(struct device *dev, void *data) | |||
371 | 388 | ||
372 | static void impd1_remove(struct lm_device *dev) | 389 | static void impd1_remove(struct lm_device *dev) |
373 | { | 390 | { |
374 | struct impd1_module *impd1 = lm_get_drvdata(dev); | ||
375 | |||
376 | device_for_each_child(&dev->dev, NULL, impd1_remove_one); | 391 | device_for_each_child(&dev->dev, NULL, impd1_remove_one); |
377 | integrator_impd1_clk_exit(dev->id); | 392 | integrator_impd1_clk_exit(dev->id); |
378 | 393 | ||
379 | lm_set_drvdata(dev, NULL); | 394 | lm_set_drvdata(dev, NULL); |
380 | |||
381 | iounmap(impd1->base); | ||
382 | kfree(impd1); | ||
383 | release_mem_region(dev->resource.start, SZ_4K); | ||
384 | } | 395 | } |
385 | 396 | ||
386 | static struct lm_driver impd1_driver = { | 397 | static struct lm_driver impd1_driver = { |
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 17c0fe627435..fedcd2fab094 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/sys_soc.h> | 42 | #include <linux/sys_soc.h> |
43 | #include <linux/termios.h> | 43 | #include <linux/termios.h> |
44 | #include <linux/sched_clock.h> | 44 | #include <linux/sched_clock.h> |
45 | #include <linux/clk-provider.h> | ||
45 | 46 | ||
46 | #include <mach/hardware.h> | 47 | #include <mach/hardware.h> |
47 | #include <mach/platform.h> | 48 | #include <mach/platform.h> |
@@ -402,10 +403,7 @@ static void __init ap_of_timer_init(void) | |||
402 | struct clk *clk; | 403 | struct clk *clk; |
403 | unsigned long rate; | 404 | unsigned long rate; |
404 | 405 | ||
405 | clk = clk_get_sys("ap_timer", NULL); | 406 | of_clk_init(NULL); |
406 | BUG_ON(IS_ERR(clk)); | ||
407 | clk_prepare_enable(clk); | ||
408 | rate = clk_get_rate(clk); | ||
409 | 407 | ||
410 | err = of_property_read_string(of_aliases, | 408 | err = of_property_read_string(of_aliases, |
411 | "arm,timer-primary", &path); | 409 | "arm,timer-primary", &path); |
@@ -415,6 +413,12 @@ static void __init ap_of_timer_init(void) | |||
415 | base = of_iomap(node, 0); | 413 | base = of_iomap(node, 0); |
416 | if (WARN_ON(!base)) | 414 | if (WARN_ON(!base)) |
417 | return; | 415 | return; |
416 | |||
417 | clk = of_clk_get(node, 0); | ||
418 | BUG_ON(IS_ERR(clk)); | ||
419 | clk_prepare_enable(clk); | ||
420 | rate = clk_get_rate(clk); | ||
421 | |||
418 | writel(0, base + TIMER_CTRL); | 422 | writel(0, base + TIMER_CTRL); |
419 | integrator_clocksource_init(rate, base); | 423 | integrator_clocksource_init(rate, base); |
420 | 424 | ||
@@ -427,6 +431,12 @@ static void __init ap_of_timer_init(void) | |||
427 | if (WARN_ON(!base)) | 431 | if (WARN_ON(!base)) |
428 | return; | 432 | return; |
429 | irq = irq_of_parse_and_map(node, 0); | 433 | irq = irq_of_parse_and_map(node, 0); |
434 | |||
435 | clk = of_clk_get(node, 0); | ||
436 | BUG_ON(IS_ERR(clk)); | ||
437 | clk_prepare_enable(clk); | ||
438 | rate = clk_get_rate(clk); | ||
439 | |||
430 | writel(0, base + TIMER_CTRL); | 440 | writel(0, base + TIMER_CTRL); |
431 | integrator_clockevent_init(rate, base, irq); | 441 | integrator_clockevent_init(rate, base, irq); |
432 | } | 442 | } |
@@ -440,7 +450,6 @@ static void __init ap_init_irq_of(void) | |||
440 | { | 450 | { |
441 | cm_init(); | 451 | cm_init(); |
442 | of_irq_init(fpga_irq_of_match); | 452 | of_irq_init(fpga_irq_of_match); |
443 | integrator_clk_init(false); | ||
444 | } | 453 | } |
445 | 454 | ||
446 | /* For the Device Tree, add in the UART callbacks as AUXDATA */ | 455 | /* For the Device Tree, add in the UART callbacks as AUXDATA */ |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a3ef961e4a93..0ad5f60598c8 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/irqchip/versatile-fpga.h> | 23 | #include <linux/irqchip/versatile-fpga.h> |
24 | #include <linux/gfp.h> | 24 | #include <linux/gfp.h> |
25 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
26 | #include <linux/platform_data/clk-integrator.h> | ||
27 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
28 | #include <linux/of_address.h> | 27 | #include <linux/of_address.h> |
29 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
@@ -33,8 +32,6 @@ | |||
33 | #include <mach/platform.h> | 32 | #include <mach/platform.h> |
34 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
35 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
36 | #include <asm/hardware/arm_timer.h> | ||
37 | #include <asm/hardware/icst.h> | ||
38 | 35 | ||
39 | #include <mach/lm.h> | 36 | #include <mach/lm.h> |
40 | 37 | ||
@@ -43,8 +40,6 @@ | |||
43 | #include <asm/mach/map.h> | 40 | #include <asm/mach/map.h> |
44 | #include <asm/mach/time.h> | 41 | #include <asm/mach/time.h> |
45 | 42 | ||
46 | #include <asm/hardware/timer-sp.h> | ||
47 | |||
48 | #include <plat/clcd.h> | 43 | #include <plat/clcd.h> |
49 | #include <plat/sched_clock.h> | 44 | #include <plat/sched_clock.h> |
50 | 45 | ||
@@ -250,7 +245,6 @@ static void __init intcp_init_irq_of(void) | |||
250 | { | 245 | { |
251 | cm_init(); | 246 | cm_init(); |
252 | of_irq_init(fpga_irq_of_match); | 247 | of_irq_init(fpga_irq_of_match); |
253 | integrator_clk_init(true); | ||
254 | } | 248 | } |
255 | 249 | ||
256 | /* | 250 | /* |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a335126ae18f..f2c89fb8fca9 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -108,7 +108,7 @@ void __init versatile_init_irq(void) | |||
108 | 108 | ||
109 | np = of_find_matching_node_by_address(NULL, vic_of_match, | 109 | np = of_find_matching_node_by_address(NULL, vic_of_match, |
110 | VERSATILE_VIC_BASE); | 110 | VERSATILE_VIC_BASE); |
111 | __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np); | 111 | __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np); |
112 | 112 | ||
113 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); | 113 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); |
114 | 114 | ||
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 8cbfcf88fae3..a820b0cfcf57 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c | |||
@@ -33,7 +33,7 @@ struct clk_icst { | |||
33 | struct clk_hw hw; | 33 | struct clk_hw hw; |
34 | void __iomem *vcoreg; | 34 | void __iomem *vcoreg; |
35 | void __iomem *lockreg; | 35 | void __iomem *lockreg; |
36 | const struct icst_params *params; | 36 | struct icst_params *params; |
37 | unsigned long rate; | 37 | unsigned long rate; |
38 | }; | 38 | }; |
39 | 39 | ||
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw, | |||
84 | struct clk_icst *icst = to_icst(hw); | 84 | struct clk_icst *icst = to_icst(hw); |
85 | struct icst_vco vco; | 85 | struct icst_vco vco; |
86 | 86 | ||
87 | if (parent_rate) | ||
88 | icst->params->ref = parent_rate; | ||
87 | vco = vco_get(icst->vcoreg); | 89 | vco = vco_get(icst->vcoreg); |
88 | icst->rate = icst_hz(icst->params, vco); | 90 | icst->rate = icst_hz(icst->params, vco); |
89 | return icst->rate; | 91 | return icst->rate; |
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, | |||
105 | struct clk_icst *icst = to_icst(hw); | 107 | struct clk_icst *icst = to_icst(hw); |
106 | struct icst_vco vco; | 108 | struct icst_vco vco; |
107 | 109 | ||
110 | if (parent_rate) | ||
111 | icst->params->ref = parent_rate; | ||
108 | vco = icst_hz_to_vco(icst->params, rate); | 112 | vco = icst_hz_to_vco(icst->params, rate); |
109 | icst->rate = icst_hz(icst->params, vco); | 113 | icst->rate = icst_hz(icst->params, vco); |
110 | vco_set(icst->lockreg, icst->vcoreg, vco); | 114 | vco_set(icst->lockreg, icst->vcoreg, vco); |
@@ -120,24 +124,33 @@ static const struct clk_ops icst_ops = { | |||
120 | struct clk *icst_clk_register(struct device *dev, | 124 | struct clk *icst_clk_register(struct device *dev, |
121 | const struct clk_icst_desc *desc, | 125 | const struct clk_icst_desc *desc, |
122 | const char *name, | 126 | const char *name, |
127 | const char *parent_name, | ||
123 | void __iomem *base) | 128 | void __iomem *base) |
124 | { | 129 | { |
125 | struct clk *clk; | 130 | struct clk *clk; |
126 | struct clk_icst *icst; | 131 | struct clk_icst *icst; |
127 | struct clk_init_data init; | 132 | struct clk_init_data init; |
133 | struct icst_params *pclone; | ||
128 | 134 | ||
129 | icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); | 135 | icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); |
130 | if (!icst) { | 136 | if (!icst) { |
131 | pr_err("could not allocate ICST clock!\n"); | 137 | pr_err("could not allocate ICST clock!\n"); |
132 | return ERR_PTR(-ENOMEM); | 138 | return ERR_PTR(-ENOMEM); |
133 | } | 139 | } |
140 | |||
141 | pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL); | ||
142 | if (!pclone) { | ||
143 | pr_err("could not clone ICST params\n"); | ||
144 | return ERR_PTR(-ENOMEM); | ||
145 | } | ||
146 | |||
134 | init.name = name; | 147 | init.name = name; |
135 | init.ops = &icst_ops; | 148 | init.ops = &icst_ops; |
136 | init.flags = CLK_IS_ROOT; | 149 | init.flags = CLK_IS_ROOT; |
137 | init.parent_names = NULL; | 150 | init.parent_names = (parent_name ? &parent_name : NULL); |
138 | init.num_parents = 0; | 151 | init.num_parents = (parent_name ? 1 : 0); |
139 | icst->hw.init = &init; | 152 | icst->hw.init = &init; |
140 | icst->params = desc->params; | 153 | icst->params = pclone; |
141 | icst->vcoreg = base + desc->vco_offset; | 154 | icst->vcoreg = base + desc->vco_offset; |
142 | icst->lockreg = base + desc->lock_offset; | 155 | icst->lockreg = base + desc->lock_offset; |
143 | 156 | ||
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h index be99dd0da785..04e6f0aef588 100644 --- a/drivers/clk/versatile/clk-icst.h +++ b/drivers/clk/versatile/clk-icst.h | |||
@@ -16,4 +16,5 @@ struct clk_icst_desc { | |||
16 | struct clk *icst_clk_register(struct device *dev, | 16 | struct clk *icst_clk_register(struct device *dev, |
17 | const struct clk_icst_desc *desc, | 17 | const struct clk_icst_desc *desc, |
18 | const char *name, | 18 | const char *name, |
19 | const char *parent_name, | ||
19 | void __iomem *base); | 20 | void __iomem *base); |
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 844f8d711a12..6d8b8e1a080a 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c | |||
@@ -93,13 +93,15 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id) | |||
93 | imc = &impd1_clks[id]; | 93 | imc = &impd1_clks[id]; |
94 | 94 | ||
95 | imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); | 95 | imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); |
96 | clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base); | 96 | clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL, |
97 | base); | ||
97 | imc->vco1clk = clk; | 98 | imc->vco1clk = clk; |
98 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); | 99 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); |
99 | 100 | ||
100 | /* VCO2 is also called "CLK2" */ | 101 | /* VCO2 is also called "CLK2" */ |
101 | imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); | 102 | imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); |
102 | clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base); | 103 | clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL, |
104 | base); | ||
103 | imc->vco2clk = clk; | 105 | imc->vco2clk = clk; |
104 | 106 | ||
105 | /* MMCI uses CLK2 right off */ | 107 | /* MMCI uses CLK2 right off */ |
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index bda8967e09c2..734c4b8fe6ab 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c | |||
@@ -10,21 +10,17 @@ | |||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/clkdev.h> | 11 | #include <linux/clkdev.h> |
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/platform_data/clk-integrator.h> | 13 | #include <linux/of.h> |
14 | 14 | #include <linux/of_address.h> | |
15 | #include <mach/hardware.h> | ||
16 | #include <mach/platform.h> | ||
17 | 15 | ||
18 | #include "clk-icst.h" | 16 | #include "clk-icst.h" |
19 | 17 | ||
20 | /* | 18 | #define INTEGRATOR_HDR_LOCK_OFFSET 0x14 |
21 | * Implementation of the ARM Integrator/AP and Integrator/CP clock tree. | ||
22 | * Inspired by portions of: | ||
23 | * plat-versatile/clock.c and plat-versatile/include/plat/clock.h | ||
24 | */ | ||
25 | 19 | ||
26 | static const struct icst_params cp_auxvco_params = { | 20 | /* Base offset for the core module */ |
27 | .ref = 24000000, | 21 | static void __iomem *cm_base; |
22 | |||
23 | static const struct icst_params cp_auxosc_params = { | ||
28 | .vco_max = ICST525_VCO_MAX_5V, | 24 | .vco_max = ICST525_VCO_MAX_5V, |
29 | .vco_min = ICST525_VCO_MIN, | 25 | .vco_min = ICST525_VCO_MIN, |
30 | .vd_min = 8, | 26 | .vd_min = 8, |
@@ -35,50 +31,39 @@ static const struct icst_params cp_auxvco_params = { | |||
35 | .idx2s = icst525_idx2s, | 31 | .idx2s = icst525_idx2s, |
36 | }; | 32 | }; |
37 | 33 | ||
38 | static const struct clk_icst_desc __initdata cp_icst_desc = { | 34 | static const struct clk_icst_desc __initdata cm_auxosc_desc = { |
39 | .params = &cp_auxvco_params, | 35 | .params = &cp_auxosc_params, |
40 | .vco_offset = 0x1c, | 36 | .vco_offset = 0x1c, |
41 | .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, | 37 | .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, |
42 | }; | 38 | }; |
43 | 39 | ||
44 | /* | 40 | static void __init of_integrator_cm_osc_setup(struct device_node *np) |
45 | * integrator_clk_init() - set up the integrator clock tree | ||
46 | * @is_cp: pass true if it's the Integrator/CP else AP is assumed | ||
47 | */ | ||
48 | void __init integrator_clk_init(bool is_cp) | ||
49 | { | 41 | { |
50 | struct clk *clk; | 42 | struct clk *clk = ERR_PTR(-EINVAL); |
51 | 43 | const char *clk_name = np->name; | |
52 | /* APB clock dummy */ | 44 | const struct clk_icst_desc *desc = &cm_auxosc_desc; |
53 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); | 45 | const char *parent_name; |
54 | clk_register_clkdev(clk, "apb_pclk", NULL); | ||
55 | |||
56 | /* UART reference clock */ | ||
57 | clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, | ||
58 | 14745600); | ||
59 | clk_register_clkdev(clk, NULL, "uart0"); | ||
60 | clk_register_clkdev(clk, NULL, "uart1"); | ||
61 | if (is_cp) | ||
62 | clk_register_clkdev(clk, NULL, "mmci"); | ||
63 | |||
64 | /* 24 MHz clock */ | ||
65 | clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, | ||
66 | 24000000); | ||
67 | clk_register_clkdev(clk, NULL, "kmi0"); | ||
68 | clk_register_clkdev(clk, NULL, "kmi1"); | ||
69 | if (!is_cp) | ||
70 | clk_register_clkdev(clk, NULL, "ap_timer"); | ||
71 | 46 | ||
72 | if (!is_cp) | 47 | if (!cm_base) { |
73 | return; | 48 | /* Remap the core module base if not done yet */ |
49 | struct device_node *parent; | ||
74 | 50 | ||
75 | /* 1 MHz clock */ | 51 | parent = of_get_parent(np); |
76 | clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, | 52 | if (!np) { |
77 | 1000000); | 53 | pr_err("no parent on core module clock\n"); |
78 | clk_register_clkdev(clk, NULL, "sp804"); | 54 | return; |
55 | } | ||
56 | cm_base = of_iomap(parent, 0); | ||
57 | if (!cm_base) { | ||
58 | pr_err("could not remap core module base\n"); | ||
59 | return; | ||
60 | } | ||
61 | } | ||
79 | 62 | ||
80 | /* ICST VCO clock used on the Integrator/CP CLCD */ | 63 | parent_name = of_clk_get_parent_name(np, 0); |
81 | clk = icst_clk_register(NULL, &cp_icst_desc, "icst", | 64 | clk = icst_clk_register(NULL, desc, clk_name, parent_name, cm_base); |
82 | __io_address(INTEGRATOR_HDR_BASE)); | 65 | if (!IS_ERR(clk)) |
83 | clk_register_clkdev(clk, NULL, "clcd"); | 66 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
84 | } | 67 | } |
68 | CLK_OF_DECLARE(integrator_cm_auxosc_clk, | ||
69 | "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup); | ||
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index 747e7b31117c..c8b523117fb7 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c | |||
@@ -85,10 +85,10 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) | |||
85 | /* ICST VCO clock */ | 85 | /* ICST VCO clock */ |
86 | if (is_pb1176) | 86 | if (is_pb1176) |
87 | clk = icst_clk_register(NULL, &realview_osc0_desc, | 87 | clk = icst_clk_register(NULL, &realview_osc0_desc, |
88 | "osc0", sysbase); | 88 | "osc0", NULL, sysbase); |
89 | else | 89 | else |
90 | clk = icst_clk_register(NULL, &realview_osc4_desc, | 90 | clk = icst_clk_register(NULL, &realview_osc4_desc, |
91 | "osc4", sysbase); | 91 | "osc4", NULL, sysbase); |
92 | 92 | ||
93 | clk_register_clkdev(clk, NULL, "dev:clcd"); | 93 | clk_register_clkdev(clk, NULL, "dev:clcd"); |
94 | clk_register_clkdev(clk, NULL, "issp:clcd"); | 94 | clk_register_clkdev(clk, NULL, "issp:clcd"); |
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 8e21ae0bab46..6002942a231c 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | /** | 58 | /** |
59 | * struct vic_device - VIC PM device | 59 | * struct vic_device - VIC PM device |
60 | * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0. | ||
60 | * @irq: The IRQ number for the base of the VIC. | 61 | * @irq: The IRQ number for the base of the VIC. |
61 | * @base: The register base for the VIC. | 62 | * @base: The register base for the VIC. |
62 | * @valid_sources: A bitmask of valid interrupts | 63 | * @valid_sources: A bitmask of valid interrupts |
@@ -224,6 +225,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | |||
224 | return handled; | 225 | return handled; |
225 | } | 226 | } |
226 | 227 | ||
228 | static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc) | ||
229 | { | ||
230 | u32 stat, hwirq; | ||
231 | struct vic_device *vic = irq_desc_get_handler_data(desc); | ||
232 | |||
233 | while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { | ||
234 | hwirq = ffs(stat) - 1; | ||
235 | generic_handle_irq(irq_find_mapping(vic->domain, hwirq)); | ||
236 | } | ||
237 | } | ||
238 | |||
227 | /* | 239 | /* |
228 | * Keep iterating over all registered VIC's until there are no pending | 240 | * Keep iterating over all registered VIC's until there are no pending |
229 | * interrupts. | 241 | * interrupts. |
@@ -246,6 +258,7 @@ static struct irq_domain_ops vic_irqdomain_ops = { | |||
246 | /** | 258 | /** |
247 | * vic_register() - Register a VIC. | 259 | * vic_register() - Register a VIC. |
248 | * @base: The base address of the VIC. | 260 | * @base: The base address of the VIC. |
261 | * @parent_irq: The parent IRQ if cascaded, else 0. | ||
249 | * @irq: The base IRQ for the VIC. | 262 | * @irq: The base IRQ for the VIC. |
250 | * @valid_sources: bitmask of valid interrupts | 263 | * @valid_sources: bitmask of valid interrupts |
251 | * @resume_sources: bitmask of interrupts allowed for resume sources. | 264 | * @resume_sources: bitmask of interrupts allowed for resume sources. |
@@ -257,7 +270,8 @@ static struct irq_domain_ops vic_irqdomain_ops = { | |||
257 | * | 270 | * |
258 | * This also configures the IRQ domain for the VIC. | 271 | * This also configures the IRQ domain for the VIC. |
259 | */ | 272 | */ |
260 | static void __init vic_register(void __iomem *base, unsigned int irq, | 273 | static void __init vic_register(void __iomem *base, unsigned int parent_irq, |
274 | unsigned int irq, | ||
261 | u32 valid_sources, u32 resume_sources, | 275 | u32 valid_sources, u32 resume_sources, |
262 | struct device_node *node) | 276 | struct device_node *node) |
263 | { | 277 | { |
@@ -273,15 +287,25 @@ static void __init vic_register(void __iomem *base, unsigned int irq, | |||
273 | v->base = base; | 287 | v->base = base; |
274 | v->valid_sources = valid_sources; | 288 | v->valid_sources = valid_sources; |
275 | v->resume_sources = resume_sources; | 289 | v->resume_sources = resume_sources; |
276 | v->irq = irq; | ||
277 | set_handle_irq(vic_handle_irq); | 290 | set_handle_irq(vic_handle_irq); |
278 | vic_id++; | 291 | vic_id++; |
292 | |||
293 | if (parent_irq) { | ||
294 | irq_set_handler_data(parent_irq, v); | ||
295 | irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); | ||
296 | } | ||
297 | |||
279 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, | 298 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, |
280 | &vic_irqdomain_ops, v); | 299 | &vic_irqdomain_ops, v); |
281 | /* create an IRQ mapping for each valid IRQ */ | 300 | /* create an IRQ mapping for each valid IRQ */ |
282 | for (i = 0; i < fls(valid_sources); i++) | 301 | for (i = 0; i < fls(valid_sources); i++) |
283 | if (valid_sources & (1 << i)) | 302 | if (valid_sources & (1 << i)) |
284 | irq_create_mapping(v->domain, i); | 303 | irq_create_mapping(v->domain, i); |
304 | /* If no base IRQ was passed, figure out our allocated base */ | ||
305 | if (irq) | ||
306 | v->irq = irq; | ||
307 | else | ||
308 | v->irq = irq_find_mapping(v->domain, 0); | ||
285 | } | 309 | } |
286 | 310 | ||
287 | static void vic_ack_irq(struct irq_data *d) | 311 | static void vic_ack_irq(struct irq_data *d) |
@@ -409,10 +433,10 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, | |||
409 | writel(32, base + VIC_PL190_DEF_VECT_ADDR); | 433 | writel(32, base + VIC_PL190_DEF_VECT_ADDR); |
410 | } | 434 | } |
411 | 435 | ||
412 | vic_register(base, irq_start, vic_sources, 0, node); | 436 | vic_register(base, 0, irq_start, vic_sources, 0, node); |
413 | } | 437 | } |
414 | 438 | ||
415 | void __init __vic_init(void __iomem *base, int irq_start, | 439 | void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, |
416 | u32 vic_sources, u32 resume_sources, | 440 | u32 vic_sources, u32 resume_sources, |
417 | struct device_node *node) | 441 | struct device_node *node) |
418 | { | 442 | { |
@@ -449,7 +473,7 @@ void __init __vic_init(void __iomem *base, int irq_start, | |||
449 | 473 | ||
450 | vic_init2(base); | 474 | vic_init2(base); |
451 | 475 | ||
452 | vic_register(base, irq_start, vic_sources, resume_sources, node); | 476 | vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, node); |
453 | } | 477 | } |
454 | 478 | ||
455 | /** | 479 | /** |
@@ -462,7 +486,28 @@ void __init __vic_init(void __iomem *base, int irq_start, | |||
462 | void __init vic_init(void __iomem *base, unsigned int irq_start, | 486 | void __init vic_init(void __iomem *base, unsigned int irq_start, |
463 | u32 vic_sources, u32 resume_sources) | 487 | u32 vic_sources, u32 resume_sources) |
464 | { | 488 | { |
465 | __vic_init(base, irq_start, vic_sources, resume_sources, NULL); | 489 | __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); |
490 | } | ||
491 | |||
492 | /** | ||
493 | * vic_init_cascaded() - initialise a cascaded vectored interrupt controller | ||
494 | * @base: iomem base address | ||
495 | * @parent_irq: the parent IRQ we're cascaded off | ||
496 | * @irq_start: starting interrupt number, must be muliple of 32 | ||
497 | * @vic_sources: bitmask of interrupt sources to allow | ||
498 | * @resume_sources: bitmask of interrupt sources to allow for resume | ||
499 | * | ||
500 | * This returns the base for the new interrupts or negative on error. | ||
501 | */ | ||
502 | int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq, | ||
503 | u32 vic_sources, u32 resume_sources) | ||
504 | { | ||
505 | struct vic_device *v; | ||
506 | |||
507 | v = &vic_devices[vic_id]; | ||
508 | __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL); | ||
509 | /* Return out acquired base */ | ||
510 | return v->irq; | ||
466 | } | 511 | } |
467 | 512 | ||
468 | #ifdef CONFIG_OF | 513 | #ifdef CONFIG_OF |
@@ -485,7 +530,7 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) | |||
485 | /* | 530 | /* |
486 | * Passing 0 as first IRQ makes the simple domain allocate descriptors | 531 | * Passing 0 as first IRQ makes the simple domain allocate descriptors |
487 | */ | 532 | */ |
488 | __vic_init(regs, 0, interrupt_mask, wakeup_mask, node); | 533 | __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node); |
489 | 534 | ||
490 | return 0; | 535 | return 0; |
491 | } | 536 | } |
diff --git a/include/linux/irqchip/arm-vic.h b/include/linux/irqchip/arm-vic.h index e3c82dc95756..ba46c794b4e5 100644 --- a/include/linux/irqchip/arm-vic.h +++ b/include/linux/irqchip/arm-vic.h | |||
@@ -29,8 +29,10 @@ | |||
29 | struct device_node; | 29 | struct device_node; |
30 | struct pt_regs; | 30 | struct pt_regs; |
31 | 31 | ||
32 | void __vic_init(void __iomem *base, int irq_start, u32 vic_sources, | 32 | void __vic_init(void __iomem *base, int parent_irq, int irq_start, |
33 | u32 resume_sources, struct device_node *node); | 33 | u32 vic_sources, u32 resume_sources, struct device_node *node); |
34 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); | 34 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); |
35 | int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, | ||
36 | u32 vic_sources, u32 resume_sources); | ||
35 | 37 | ||
36 | #endif | 38 | #endif |
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h index 280edac9d0a5..addd48cac625 100644 --- a/include/linux/platform_data/clk-integrator.h +++ b/include/linux/platform_data/clk-integrator.h | |||
@@ -1,3 +1,2 @@ | |||
1 | void integrator_clk_init(bool is_cp); | ||
2 | void integrator_impd1_clk_init(void __iomem *base, unsigned int id); | 1 | void integrator_impd1_clk_init(void __iomem *base, unsigned int id); |
3 | void integrator_impd1_clk_exit(unsigned int id); | 2 | void integrator_impd1_clk_exit(unsigned int id); |