diff options
author | Roland Stigge <stigge@antcom.de> | 2012-04-22 06:01:19 -0400 |
---|---|---|
committer | Roland Stigge <stigge@antcom.de> | 2012-04-22 06:01:19 -0400 |
commit | f5c422713308e492eddc44a12134f9f249ddfbdb (patch) | |
tree | f5f3f115b40aada230e8d413429000a0a7741991 | |
parent | e04920d9efcb3517cabc61a55a3ce4bce51518bc (diff) |
ARM: LPC32xx: Device tree support
This patch does the actual device tree switch for the LPC32xx SoC.
Signed-off-by: Roland Stigge <stigge@antcom.de>
-rw-r--r-- | Documentation/devicetree/bindings/arm/lpc32xx-mic.txt | 38 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/arm/lpc32xx.txt | 8 | ||||
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-lpc32xx/common.c | 192 | ||||
-rw-r--r-- | arch/arm/mach-lpc32xx/common.h | 14 | ||||
-rw-r--r-- | arch/arm/mach-lpc32xx/irq.c | 78 | ||||
-rw-r--r-- | arch/arm/mach-lpc32xx/phy3250.c | 138 |
7 files changed, 158 insertions, 311 deletions
diff --git a/Documentation/devicetree/bindings/arm/lpc32xx-mic.txt b/Documentation/devicetree/bindings/arm/lpc32xx-mic.txt new file mode 100644 index 000000000000..539adca19e8f --- /dev/null +++ b/Documentation/devicetree/bindings/arm/lpc32xx-mic.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | * NXP LPC32xx Main Interrupt Controller | ||
2 | (MIC, including SIC1 and SIC2 secondary controllers) | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: Should be "nxp,lpc3220-mic" | ||
6 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
7 | - interrupt-parent: Empty for the interrupt controller itself | ||
8 | - #interrupt-cells: The number of cells to define the interrupts. Should be 2. | ||
9 | The first cell is the IRQ number | ||
10 | The second cell is used to specify mode: | ||
11 | 1 = low-to-high edge triggered | ||
12 | 2 = high-to-low edge triggered | ||
13 | 4 = active high level-sensitive | ||
14 | 8 = active low level-sensitive | ||
15 | Default for internal sources should be set to 4 (active high). | ||
16 | - reg: Should contain MIC registers location and length | ||
17 | |||
18 | Examples: | ||
19 | /* | ||
20 | * MIC | ||
21 | */ | ||
22 | mic: interrupt-controller@40008000 { | ||
23 | compatible = "nxp,lpc3220-mic"; | ||
24 | interrupt-controller; | ||
25 | interrupt-parent; | ||
26 | #interrupt-cells = <2>; | ||
27 | reg = <0x40008000 0xC000>; | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * ADC | ||
32 | */ | ||
33 | adc@40048000 { | ||
34 | compatible = "nxp,lpc3220-adc"; | ||
35 | reg = <0x40048000 0x1000>; | ||
36 | interrupt-parent = <&mic>; | ||
37 | interrupts = <39 4>; | ||
38 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/lpc32xx.txt b/Documentation/devicetree/bindings/arm/lpc32xx.txt new file mode 100644 index 000000000000..56ec8ddc4a3b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/lpc32xx.txt | |||
@@ -0,0 +1,8 @@ | |||
1 | NXP LPC32xx Platforms Device Tree Bindings | ||
2 | ------------------------------------------ | ||
3 | |||
4 | Boards with the NXP LPC32xx SoC shall have the following properties: | ||
5 | |||
6 | Required root node property: | ||
7 | |||
8 | compatible: must be "nxp,lpc3220", "nxp,lpc3230", "nxp,lpc3240" or "nxp,lpc3250" | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cf006d40342c..6e51ddde908a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -597,6 +597,7 @@ config ARCH_LPC32XX | |||
597 | select USB_ARCH_HAS_OHCI | 597 | select USB_ARCH_HAS_OHCI |
598 | select CLKDEV_LOOKUP | 598 | select CLKDEV_LOOKUP |
599 | select GENERIC_CLOCKEVENTS | 599 | select GENERIC_CLOCKEVENTS |
600 | select USE_OF | ||
600 | help | 601 | help |
601 | Support for the NXP LPC32XX family of processors | 602 | Support for the NXP LPC32XX family of processors |
602 | 603 | ||
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c index 6f255600fc97..0a41e1ec0c3a 100644 --- a/arch/arm/mach-lpc32xx/common.c +++ b/arch/arm/mach-lpc32xx/common.c | |||
@@ -32,198 +32,6 @@ | |||
32 | #include "common.h" | 32 | #include "common.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Watchdog timer | ||
36 | */ | ||
37 | static struct resource watchdog_resources[] = { | ||
38 | [0] = { | ||
39 | .start = LPC32XX_WDTIM_BASE, | ||
40 | .end = LPC32XX_WDTIM_BASE + SZ_4K - 1, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | }; | ||
44 | |||
45 | struct platform_device lpc32xx_watchdog_device = { | ||
46 | .name = "pnx4008-watchdog", | ||
47 | .id = -1, | ||
48 | .num_resources = ARRAY_SIZE(watchdog_resources), | ||
49 | .resource = watchdog_resources, | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * I2C busses | ||
54 | */ | ||
55 | static struct resource i2c0_resources[] = { | ||
56 | [0] = { | ||
57 | .start = LPC32XX_I2C1_BASE, | ||
58 | .end = LPC32XX_I2C1_BASE + 0x100 - 1, | ||
59 | .flags = IORESOURCE_MEM, | ||
60 | }, | ||
61 | [1] = { | ||
62 | .start = IRQ_LPC32XX_I2C_1, | ||
63 | .end = IRQ_LPC32XX_I2C_1, | ||
64 | .flags = IORESOURCE_IRQ, | ||
65 | }, | ||
66 | }; | ||
67 | |||
68 | static struct resource i2c1_resources[] = { | ||
69 | [0] = { | ||
70 | .start = LPC32XX_I2C2_BASE, | ||
71 | .end = LPC32XX_I2C2_BASE + 0x100 - 1, | ||
72 | .flags = IORESOURCE_MEM, | ||
73 | }, | ||
74 | [1] = { | ||
75 | .start = IRQ_LPC32XX_I2C_2, | ||
76 | .end = IRQ_LPC32XX_I2C_2, | ||
77 | .flags = IORESOURCE_IRQ, | ||
78 | }, | ||
79 | }; | ||
80 | |||
81 | static struct resource i2c2_resources[] = { | ||
82 | [0] = { | ||
83 | .start = LPC32XX_OTG_I2C_BASE, | ||
84 | .end = LPC32XX_OTG_I2C_BASE + 0x100 - 1, | ||
85 | .flags = IORESOURCE_MEM, | ||
86 | }, | ||
87 | [1] = { | ||
88 | .start = IRQ_LPC32XX_USB_I2C, | ||
89 | .end = IRQ_LPC32XX_USB_I2C, | ||
90 | .flags = IORESOURCE_IRQ, | ||
91 | }, | ||
92 | }; | ||
93 | |||
94 | struct platform_device lpc32xx_i2c0_device = { | ||
95 | .name = "pnx-i2c.0", | ||
96 | .id = 0, | ||
97 | .num_resources = ARRAY_SIZE(i2c0_resources), | ||
98 | .resource = i2c0_resources, | ||
99 | }; | ||
100 | |||
101 | struct platform_device lpc32xx_i2c1_device = { | ||
102 | .name = "pnx-i2c.1", | ||
103 | .id = 1, | ||
104 | .num_resources = ARRAY_SIZE(i2c1_resources), | ||
105 | .resource = i2c1_resources, | ||
106 | }; | ||
107 | |||
108 | struct platform_device lpc32xx_i2c2_device = { | ||
109 | .name = "pnx-i2c.2", | ||
110 | .id = 2, | ||
111 | .num_resources = ARRAY_SIZE(i2c2_resources), | ||
112 | .resource = i2c2_resources, | ||
113 | }; | ||
114 | |||
115 | /* TSC (Touch Screen Controller) */ | ||
116 | |||
117 | static struct resource lpc32xx_tsc_resources[] = { | ||
118 | { | ||
119 | .start = LPC32XX_ADC_BASE, | ||
120 | .end = LPC32XX_ADC_BASE + SZ_4K - 1, | ||
121 | .flags = IORESOURCE_MEM, | ||
122 | }, { | ||
123 | .start = IRQ_LPC32XX_TS_IRQ, | ||
124 | .end = IRQ_LPC32XX_TS_IRQ, | ||
125 | .flags = IORESOURCE_IRQ, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | struct platform_device lpc32xx_tsc_device = { | ||
130 | .name = "ts-lpc32xx", | ||
131 | .id = -1, | ||
132 | .num_resources = ARRAY_SIZE(lpc32xx_tsc_resources), | ||
133 | .resource = lpc32xx_tsc_resources, | ||
134 | }; | ||
135 | |||
136 | /* RTC */ | ||
137 | |||
138 | static struct resource lpc32xx_rtc_resources[] = { | ||
139 | { | ||
140 | .start = LPC32XX_RTC_BASE, | ||
141 | .end = LPC32XX_RTC_BASE + SZ_4K - 1, | ||
142 | .flags = IORESOURCE_MEM, | ||
143 | },{ | ||
144 | .start = IRQ_LPC32XX_RTC, | ||
145 | .end = IRQ_LPC32XX_RTC, | ||
146 | .flags = IORESOURCE_IRQ, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | struct platform_device lpc32xx_rtc_device = { | ||
151 | .name = "rtc-lpc32xx", | ||
152 | .id = -1, | ||
153 | .num_resources = ARRAY_SIZE(lpc32xx_rtc_resources), | ||
154 | .resource = lpc32xx_rtc_resources, | ||
155 | }; | ||
156 | |||
157 | /* | ||
158 | * ADC support | ||
159 | */ | ||
160 | static struct resource adc_resources[] = { | ||
161 | { | ||
162 | .start = LPC32XX_ADC_BASE, | ||
163 | .end = LPC32XX_ADC_BASE + SZ_4K - 1, | ||
164 | .flags = IORESOURCE_MEM, | ||
165 | }, { | ||
166 | .start = IRQ_LPC32XX_TS_IRQ, | ||
167 | .end = IRQ_LPC32XX_TS_IRQ, | ||
168 | .flags = IORESOURCE_IRQ, | ||
169 | }, | ||
170 | }; | ||
171 | |||
172 | struct platform_device lpc32xx_adc_device = { | ||
173 | .name = "lpc32xx-adc", | ||
174 | .id = -1, | ||
175 | .num_resources = ARRAY_SIZE(adc_resources), | ||
176 | .resource = adc_resources, | ||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * USB support | ||
181 | */ | ||
182 | /* The dmamask must be set for OHCI to work */ | ||
183 | static u64 ohci_dmamask = ~(u32) 0; | ||
184 | static struct resource ohci_resources[] = { | ||
185 | { | ||
186 | .start = IO_ADDRESS(LPC32XX_USB_BASE), | ||
187 | .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1), | ||
188 | .flags = IORESOURCE_MEM, | ||
189 | }, { | ||
190 | .start = IRQ_LPC32XX_USB_HOST, | ||
191 | .flags = IORESOURCE_IRQ, | ||
192 | }, | ||
193 | }; | ||
194 | struct platform_device lpc32xx_ohci_device = { | ||
195 | .name = "usb-ohci", | ||
196 | .id = -1, | ||
197 | .dev = { | ||
198 | .dma_mask = &ohci_dmamask, | ||
199 | .coherent_dma_mask = 0xFFFFFFFF, | ||
200 | }, | ||
201 | .num_resources = ARRAY_SIZE(ohci_resources), | ||
202 | .resource = ohci_resources, | ||
203 | }; | ||
204 | |||
205 | /* | ||
206 | * Network Support | ||
207 | */ | ||
208 | static struct resource net_resources[] = { | ||
209 | [0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K), | ||
210 | [1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K), | ||
211 | [2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET), | ||
212 | }; | ||
213 | |||
214 | static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; | ||
215 | struct platform_device lpc32xx_net_device = { | ||
216 | .name = "lpc-eth", | ||
217 | .id = 0, | ||
218 | .dev = { | ||
219 | .dma_mask = &lpc32xx_mac_dma_mask, | ||
220 | .coherent_dma_mask = 0xffffffffUL, | ||
221 | }, | ||
222 | .num_resources = ARRAY_SIZE(net_resources), | ||
223 | .resource = net_resources, | ||
224 | }; | ||
225 | |||
226 | /* | ||
227 | * Returns the unique ID for the device | 35 | * Returns the unique ID for the device |
228 | */ | 36 | */ |
229 | void lpc32xx_get_uid(u32 devid[4]) | 37 | void lpc32xx_get_uid(u32 devid[4]) |
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h index 68e45e8c9486..afeac3b1fae6 100644 --- a/arch/arm/mach-lpc32xx/common.h +++ b/arch/arm/mach-lpc32xx/common.h | |||
@@ -23,26 +23,12 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Arch specific platform device structures | ||
27 | */ | ||
28 | extern struct platform_device lpc32xx_watchdog_device; | ||
29 | extern struct platform_device lpc32xx_i2c0_device; | ||
30 | extern struct platform_device lpc32xx_i2c1_device; | ||
31 | extern struct platform_device lpc32xx_i2c2_device; | ||
32 | extern struct platform_device lpc32xx_tsc_device; | ||
33 | extern struct platform_device lpc32xx_adc_device; | ||
34 | extern struct platform_device lpc32xx_rtc_device; | ||
35 | extern struct platform_device lpc32xx_ohci_device; | ||
36 | extern struct platform_device lpc32xx_net_device; | ||
37 | |||
38 | /* | ||
39 | * Other arch specific structures and functions | 26 | * Other arch specific structures and functions |
40 | */ | 27 | */ |
41 | extern struct sys_timer lpc32xx_timer; | 28 | extern struct sys_timer lpc32xx_timer; |
42 | extern void __init lpc32xx_init_irq(void); | 29 | extern void __init lpc32xx_init_irq(void); |
43 | extern void __init lpc32xx_map_io(void); | 30 | extern void __init lpc32xx_map_io(void); |
44 | extern void __init lpc32xx_serial_init(void); | 31 | extern void __init lpc32xx_serial_init(void); |
45 | extern void __init lpc32xx_gpio_init(void); | ||
46 | extern void lpc23xx_restart(char, const char *); | 32 | extern void lpc23xx_restart(char, const char *); |
47 | 33 | ||
48 | 34 | ||
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c index d080cb1123dd..5b1cc35e6fba 100644 --- a/arch/arm/mach-lpc32xx/irq.c +++ b/arch/arm/mach-lpc32xx/irq.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_address.h> | ||
27 | #include <linux/of_irq.h> | ||
28 | #include <linux/irqdomain.h> | ||
29 | #include <linux/module.h> | ||
25 | 30 | ||
26 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
27 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
@@ -44,6 +49,9 @@ | |||
44 | #define SIC1_ATR_DEFAULT 0x00026000 | 49 | #define SIC1_ATR_DEFAULT 0x00026000 |
45 | #define SIC2_ATR_DEFAULT 0x00000000 | 50 | #define SIC2_ATR_DEFAULT 0x00000000 |
46 | 51 | ||
52 | static struct irq_domain *lpc32xx_mic_domain; | ||
53 | static struct device_node *lpc32xx_mic_np; | ||
54 | |||
47 | struct lpc32xx_event_group_regs { | 55 | struct lpc32xx_event_group_regs { |
48 | void __iomem *enab_reg; | 56 | void __iomem *enab_reg; |
49 | void __iomem *edge_reg; | 57 | void __iomem *edge_reg; |
@@ -203,7 +211,7 @@ static void lpc32xx_mask_irq(struct irq_data *d) | |||
203 | { | 211 | { |
204 | unsigned int reg, ctrl, mask; | 212 | unsigned int reg, ctrl, mask; |
205 | 213 | ||
206 | get_controller(d->irq, &ctrl, &mask); | 214 | get_controller(d->hwirq, &ctrl, &mask); |
207 | 215 | ||
208 | reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; | 216 | reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; |
209 | __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | 217 | __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); |
@@ -213,7 +221,7 @@ static void lpc32xx_unmask_irq(struct irq_data *d) | |||
213 | { | 221 | { |
214 | unsigned int reg, ctrl, mask; | 222 | unsigned int reg, ctrl, mask; |
215 | 223 | ||
216 | get_controller(d->irq, &ctrl, &mask); | 224 | get_controller(d->hwirq, &ctrl, &mask); |
217 | 225 | ||
218 | reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; | 226 | reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; |
219 | __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | 227 | __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); |
@@ -223,14 +231,14 @@ static void lpc32xx_ack_irq(struct irq_data *d) | |||
223 | { | 231 | { |
224 | unsigned int ctrl, mask; | 232 | unsigned int ctrl, mask; |
225 | 233 | ||
226 | get_controller(d->irq, &ctrl, &mask); | 234 | get_controller(d->hwirq, &ctrl, &mask); |
227 | 235 | ||
228 | __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); | 236 | __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); |
229 | 237 | ||
230 | /* Also need to clear pending wake event */ | 238 | /* Also need to clear pending wake event */ |
231 | if (lpc32xx_events[d->irq].mask != 0) | 239 | if (lpc32xx_events[d->hwirq].mask != 0) |
232 | __raw_writel(lpc32xx_events[d->irq].mask, | 240 | __raw_writel(lpc32xx_events[d->hwirq].mask, |
233 | lpc32xx_events[d->irq].event_group->rawstat_reg); | 241 | lpc32xx_events[d->hwirq].event_group->rawstat_reg); |
234 | } | 242 | } |
235 | 243 | ||
236 | static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, | 244 | static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, |
@@ -274,22 +282,22 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) | |||
274 | switch (type) { | 282 | switch (type) { |
275 | case IRQ_TYPE_EDGE_RISING: | 283 | case IRQ_TYPE_EDGE_RISING: |
276 | /* Rising edge sensitive */ | 284 | /* Rising edge sensitive */ |
277 | __lpc32xx_set_irq_type(d->irq, 1, 1); | 285 | __lpc32xx_set_irq_type(d->hwirq, 1, 1); |
278 | break; | 286 | break; |
279 | 287 | ||
280 | case IRQ_TYPE_EDGE_FALLING: | 288 | case IRQ_TYPE_EDGE_FALLING: |
281 | /* Falling edge sensitive */ | 289 | /* Falling edge sensitive */ |
282 | __lpc32xx_set_irq_type(d->irq, 0, 1); | 290 | __lpc32xx_set_irq_type(d->hwirq, 0, 1); |
283 | break; | 291 | break; |
284 | 292 | ||
285 | case IRQ_TYPE_LEVEL_LOW: | 293 | case IRQ_TYPE_LEVEL_LOW: |
286 | /* Low level sensitive */ | 294 | /* Low level sensitive */ |
287 | __lpc32xx_set_irq_type(d->irq, 0, 0); | 295 | __lpc32xx_set_irq_type(d->hwirq, 0, 0); |
288 | break; | 296 | break; |
289 | 297 | ||
290 | case IRQ_TYPE_LEVEL_HIGH: | 298 | case IRQ_TYPE_LEVEL_HIGH: |
291 | /* High level sensitive */ | 299 | /* High level sensitive */ |
292 | __lpc32xx_set_irq_type(d->irq, 1, 0); | 300 | __lpc32xx_set_irq_type(d->hwirq, 1, 0); |
293 | break; | 301 | break; |
294 | 302 | ||
295 | /* Other modes are not supported */ | 303 | /* Other modes are not supported */ |
@@ -298,7 +306,7 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) | |||
298 | } | 306 | } |
299 | 307 | ||
300 | /* Ok to use the level handler for all types */ | 308 | /* Ok to use the level handler for all types */ |
301 | irq_set_handler(d->irq, handle_level_irq); | 309 | irq_set_handler(d->hwirq, handle_level_irq); |
302 | 310 | ||
303 | return 0; | 311 | return 0; |
304 | } | 312 | } |
@@ -307,33 +315,33 @@ static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state) | |||
307 | { | 315 | { |
308 | unsigned long eventreg; | 316 | unsigned long eventreg; |
309 | 317 | ||
310 | if (lpc32xx_events[d->irq].mask != 0) { | 318 | if (lpc32xx_events[d->hwirq].mask != 0) { |
311 | eventreg = __raw_readl(lpc32xx_events[d->irq]. | 319 | eventreg = __raw_readl(lpc32xx_events[d->hwirq]. |
312 | event_group->enab_reg); | 320 | event_group->enab_reg); |
313 | 321 | ||
314 | if (state) | 322 | if (state) |
315 | eventreg |= lpc32xx_events[d->irq].mask; | 323 | eventreg |= lpc32xx_events[d->hwirq].mask; |
316 | else { | 324 | else { |
317 | eventreg &= ~lpc32xx_events[d->irq].mask; | 325 | eventreg &= ~lpc32xx_events[d->hwirq].mask; |
318 | 326 | ||
319 | /* | 327 | /* |
320 | * When disabling the wakeup, clear the latched | 328 | * When disabling the wakeup, clear the latched |
321 | * event | 329 | * event |
322 | */ | 330 | */ |
323 | __raw_writel(lpc32xx_events[d->irq].mask, | 331 | __raw_writel(lpc32xx_events[d->hwirq].mask, |
324 | lpc32xx_events[d->irq]. | 332 | lpc32xx_events[d->hwirq]. |
325 | event_group->rawstat_reg); | 333 | event_group->rawstat_reg); |
326 | } | 334 | } |
327 | 335 | ||
328 | __raw_writel(eventreg, | 336 | __raw_writel(eventreg, |
329 | lpc32xx_events[d->irq].event_group->enab_reg); | 337 | lpc32xx_events[d->hwirq].event_group->enab_reg); |
330 | 338 | ||
331 | return 0; | 339 | return 0; |
332 | } | 340 | } |
333 | 341 | ||
334 | /* Clear event */ | 342 | /* Clear event */ |
335 | __raw_writel(lpc32xx_events[d->irq].mask, | 343 | __raw_writel(lpc32xx_events[d->hwirq].mask, |
336 | lpc32xx_events[d->irq].event_group->rawstat_reg); | 344 | lpc32xx_events[d->hwirq].event_group->rawstat_reg); |
337 | 345 | ||
338 | return -ENODEV; | 346 | return -ENODEV; |
339 | } | 347 | } |
@@ -353,6 +361,7 @@ static void __init lpc32xx_set_default_mappings(unsigned int apr, | |||
353 | } | 361 | } |
354 | 362 | ||
355 | static struct irq_chip lpc32xx_irq_chip = { | 363 | static struct irq_chip lpc32xx_irq_chip = { |
364 | .name = "MIC", | ||
356 | .irq_ack = lpc32xx_ack_irq, | 365 | .irq_ack = lpc32xx_ack_irq, |
357 | .irq_mask = lpc32xx_mask_irq, | 366 | .irq_mask = lpc32xx_mask_irq, |
358 | .irq_unmask = lpc32xx_unmask_irq, | 367 | .irq_unmask = lpc32xx_unmask_irq, |
@@ -386,9 +395,23 @@ static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc) | |||
386 | } | 395 | } |
387 | } | 396 | } |
388 | 397 | ||
398 | static int __init __lpc32xx_mic_of_init(struct device_node *node, | ||
399 | struct device_node *parent) | ||
400 | { | ||
401 | lpc32xx_mic_np = node; | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static const struct of_device_id mic_of_match[] __initconst = { | ||
407 | { .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init }, | ||
408 | { } | ||
409 | }; | ||
410 | |||
389 | void __init lpc32xx_init_irq(void) | 411 | void __init lpc32xx_init_irq(void) |
390 | { | 412 | { |
391 | unsigned int i; | 413 | unsigned int i; |
414 | int irq_base; | ||
392 | 415 | ||
393 | /* Setup MIC */ | 416 | /* Setup MIC */ |
394 | __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); | 417 | __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); |
@@ -448,4 +471,19 @@ void __init lpc32xx_init_irq(void) | |||
448 | LPC32XX_CLKPWR_PIN_RS); | 471 | LPC32XX_CLKPWR_PIN_RS); |
449 | __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), | 472 | __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), |
450 | LPC32XX_CLKPWR_INT_RS); | 473 | LPC32XX_CLKPWR_INT_RS); |
474 | |||
475 | of_irq_init(mic_of_match); | ||
476 | |||
477 | irq_base = irq_alloc_descs(-1, 0, NR_IRQS, 0); | ||
478 | if (irq_base < 0) { | ||
479 | pr_warn("Cannot allocate irq_descs, assuming pre-allocated\n"); | ||
480 | irq_base = 0; | ||
481 | } | ||
482 | |||
483 | lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS, | ||
484 | irq_base, 0, | ||
485 | &irq_domain_simple_ops, | ||
486 | NULL); | ||
487 | if (!lpc32xx_mic_domain) | ||
488 | panic("Unable to add MIC irq domain\n"); | ||
451 | } | 489 | } |
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 7f7401ec7487..483846ff8293 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-lpc32xx/phy3250.c | 2 | * Platform support for LPC32xx SoC |
3 | * | 3 | * |
4 | * Author: Kevin Wells <kevin.wells@nxp.com> | 4 | * Author: Kevin Wells <kevin.wells@nxp.com> |
5 | * | 5 | * |
6 | * Copyright (C) 2012 Roland Stigge <stigge@antcom.de> | ||
6 | * Copyright (C) 2010 NXP Semiconductors | 7 | * Copyright (C) 2010 NXP Semiconductors |
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -25,11 +26,16 @@ | |||
25 | #include <linux/device.h> | 26 | #include <linux/device.h> |
26 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/eeprom.h> | 28 | #include <linux/spi/eeprom.h> |
28 | #include <linux/leds.h> | ||
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/amba/bus.h> | 30 | #include <linux/amba/bus.h> |
31 | #include <linux/amba/clcd.h> | 31 | #include <linux/amba/clcd.h> |
32 | #include <linux/amba/pl022.h> | 32 | #include <linux/amba/pl022.h> |
33 | #include <linux/of.h> | ||
34 | #include <linux/of_address.h> | ||
35 | #include <linux/of_irq.h> | ||
36 | #include <linux/of_platform.h> | ||
37 | #include <linux/clk.h> | ||
38 | #include <linux/amba/pl08x.h> | ||
33 | 39 | ||
34 | #include <asm/setup.h> | 40 | #include <asm/setup.h> |
35 | #include <asm/mach-types.h> | 41 | #include <asm/mach-types.h> |
@@ -47,7 +53,6 @@ | |||
47 | #define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) | 53 | #define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) |
48 | #define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) | 54 | #define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) |
49 | #define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) | 55 | #define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) |
50 | #define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1) | ||
51 | 56 | ||
52 | /* | 57 | /* |
53 | * AMBA LCD controller | 58 | * AMBA LCD controller |
@@ -150,9 +155,6 @@ static struct clcd_board lpc32xx_clcd_data = { | |||
150 | .remove = lpc32xx_clcd_remove, | 155 | .remove = lpc32xx_clcd_remove, |
151 | }; | 156 | }; |
152 | 157 | ||
153 | static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0, | ||
154 | LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data); | ||
155 | |||
156 | /* | 158 | /* |
157 | * AMBA SSP (SPI) | 159 | * AMBA SSP (SPI) |
158 | */ | 160 | */ |
@@ -180,8 +182,11 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = { | |||
180 | .enable_dma = 0, | 182 | .enable_dma = 0, |
181 | }; | 183 | }; |
182 | 184 | ||
183 | static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0, | 185 | static struct pl022_ssp_controller lpc32xx_ssp1_data = { |
184 | LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data); | 186 | .bus_id = 1, |
187 | .num_chipselect = 1, | ||
188 | .enable_dma = 0, | ||
189 | }; | ||
185 | 190 | ||
186 | /* AT25 driver registration */ | 191 | /* AT25 driver registration */ |
187 | static int __init phy3250_spi_board_register(void) | 192 | static int __init phy3250_spi_board_register(void) |
@@ -221,73 +226,20 @@ static int __init phy3250_spi_board_register(void) | |||
221 | } | 226 | } |
222 | arch_initcall(phy3250_spi_board_register); | 227 | arch_initcall(phy3250_spi_board_register); |
223 | 228 | ||
224 | static struct i2c_board_info __initdata phy3250_i2c_board_info[] = { | 229 | static struct pl08x_platform_data pl08x_pd = { |
225 | { | ||
226 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
227 | }, | ||
228 | }; | 230 | }; |
229 | 231 | ||
230 | static struct gpio_led phy_leds[] = { | 232 | static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { |
231 | { | 233 | OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data), |
232 | .name = "led0", | 234 | OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data), |
233 | .gpio = LED_GPIO, | 235 | OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data), |
234 | .active_low = 1, | 236 | OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd), |
235 | .default_trigger = "heartbeat", | 237 | { } |
236 | }, | ||
237 | }; | 238 | }; |
238 | 239 | ||
239 | static struct gpio_led_platform_data led_data = { | 240 | static void __init lpc3250_machine_init(void) |
240 | .leds = phy_leds, | ||
241 | .num_leds = ARRAY_SIZE(phy_leds), | ||
242 | }; | ||
243 | |||
244 | static struct platform_device lpc32xx_gpio_led_device = { | ||
245 | .name = "leds-gpio", | ||
246 | .id = -1, | ||
247 | .dev.platform_data = &led_data, | ||
248 | }; | ||
249 | |||
250 | static struct platform_device *phy3250_devs[] __initdata = { | ||
251 | &lpc32xx_rtc_device, | ||
252 | &lpc32xx_tsc_device, | ||
253 | &lpc32xx_i2c0_device, | ||
254 | &lpc32xx_i2c1_device, | ||
255 | &lpc32xx_i2c2_device, | ||
256 | &lpc32xx_watchdog_device, | ||
257 | &lpc32xx_gpio_led_device, | ||
258 | &lpc32xx_adc_device, | ||
259 | &lpc32xx_ohci_device, | ||
260 | &lpc32xx_net_device, | ||
261 | }; | ||
262 | |||
263 | static struct amba_device *amba_devs[] __initdata = { | ||
264 | &lpc32xx_clcd_device, | ||
265 | &lpc32xx_ssp0_device, | ||
266 | }; | ||
267 | |||
268 | /* | ||
269 | * Board specific functions | ||
270 | */ | ||
271 | static void __init phy3250_board_init(void) | ||
272 | { | 241 | { |
273 | u32 tmp; | 242 | u32 tmp; |
274 | int i; | ||
275 | |||
276 | lpc32xx_gpio_init(); | ||
277 | |||
278 | /* Register GPIOs used on this board */ | ||
279 | if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) | ||
280 | printk(KERN_ERR "Error requesting gpio %u", | ||
281 | SPI0_CS_GPIO); | ||
282 | else if (gpio_direction_output(SPI0_CS_GPIO, 1)) | ||
283 | printk(KERN_ERR "Error setting gpio %u to output", | ||
284 | SPI0_CS_GPIO); | ||
285 | |||
286 | /* Setup network interface for RMII mode */ | ||
287 | tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); | ||
288 | tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; | ||
289 | tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; | ||
290 | __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); | ||
291 | 243 | ||
292 | /* Setup SLC NAND controller muxing */ | 244 | /* Setup SLC NAND controller muxing */ |
293 | __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, | 245 | __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, |
@@ -300,6 +252,12 @@ static void __init phy3250_board_init(void) | |||
300 | tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; | 252 | tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; |
301 | __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); | 253 | __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); |
302 | 254 | ||
255 | /* Set up USB power */ | ||
256 | tmp = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); | ||
257 | tmp |= LPC32XX_CLKPWR_USBCTRL_HCLK_EN | | ||
258 | LPC32XX_CLKPWR_USBCTRL_USBI2C_EN; | ||
259 | __raw_writel(tmp, LPC32XX_CLKPWR_USB_CTRL); | ||
260 | |||
303 | /* Set up I2C pull levels */ | 261 | /* Set up I2C pull levels */ |
304 | tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); | 262 | tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); |
305 | tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | | 263 | tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | |
@@ -321,33 +279,35 @@ static void __init phy3250_board_init(void) | |||
321 | /* | 279 | /* |
322 | * AMBA peripheral clocks need to be enabled prior to AMBA device | 280 | * AMBA peripheral clocks need to be enabled prior to AMBA device |
323 | * detection or a data fault will occur, so enable the clocks | 281 | * detection or a data fault will occur, so enable the clocks |
324 | * here. However, we don't want to enable them if the peripheral | 282 | * here. |
325 | * isn't included in the image | ||
326 | */ | 283 | */ |
327 | #ifdef CONFIG_FB_ARMCLCD | ||
328 | tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); | 284 | tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); |
329 | __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), | 285 | __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), |
330 | LPC32XX_CLKPWR_LCDCLK_CTRL); | 286 | LPC32XX_CLKPWR_LCDCLK_CTRL); |
331 | #endif | 287 | |
332 | #ifdef CONFIG_SPI_PL022 | ||
333 | tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); | 288 | tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); |
334 | __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), | 289 | __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), |
335 | LPC32XX_CLKPWR_SSP_CLK_CTRL); | 290 | LPC32XX_CLKPWR_SSP_CLK_CTRL); |
336 | #endif | ||
337 | 291 | ||
338 | platform_add_devices(phy3250_devs, ARRAY_SIZE(phy3250_devs)); | 292 | tmp = __raw_readl(LPC32XX_CLKPWR_DMA_CLK_CTRL); |
339 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 293 | __raw_writel((tmp | LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN), |
340 | struct amba_device *d = amba_devs[i]; | 294 | LPC32XX_CLKPWR_DMA_CLK_CTRL); |
341 | amba_device_register(d, &iomem_resource); | ||
342 | } | ||
343 | 295 | ||
344 | /* Test clock needed for UDA1380 initial init */ | 296 | /* Test clock needed for UDA1380 initial init */ |
345 | __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | | 297 | __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | |
346 | LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, | 298 | LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, |
347 | LPC32XX_CLKPWR_TEST_CLK_SEL); | 299 | LPC32XX_CLKPWR_TEST_CLK_SEL); |
348 | 300 | ||
349 | i2c_register_board_info(0, phy3250_i2c_board_info, | 301 | of_platform_populate(NULL, of_default_bus_match_table, |
350 | ARRAY_SIZE(phy3250_i2c_board_info)); | 302 | lpc32xx_auxdata_lookup, NULL); |
303 | |||
304 | /* Register GPIOs used on this board */ | ||
305 | if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) | ||
306 | printk(KERN_ERR "Error requesting gpio %u", | ||
307 | SPI0_CS_GPIO); | ||
308 | else if (gpio_direction_output(SPI0_CS_GPIO, 1)) | ||
309 | printk(KERN_ERR "Error setting gpio %u to output", | ||
310 | SPI0_CS_GPIO); | ||
351 | } | 311 | } |
352 | 312 | ||
353 | static int __init lpc32xx_display_uid(void) | 313 | static int __init lpc32xx_display_uid(void) |
@@ -363,12 +323,20 @@ static int __init lpc32xx_display_uid(void) | |||
363 | } | 323 | } |
364 | arch_initcall(lpc32xx_display_uid); | 324 | arch_initcall(lpc32xx_display_uid); |
365 | 325 | ||
366 | MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller") | 326 | static char const *lpc32xx_dt_compat[] __initdata = { |
367 | /* Maintainer: Kevin Wells, NXP Semiconductors */ | 327 | "nxp,lpc3220", |
328 | "nxp,lpc3230", | ||
329 | "nxp,lpc3240", | ||
330 | "nxp,lpc3250", | ||
331 | NULL | ||
332 | }; | ||
333 | |||
334 | DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)") | ||
368 | .atag_offset = 0x100, | 335 | .atag_offset = 0x100, |
369 | .map_io = lpc32xx_map_io, | 336 | .map_io = lpc32xx_map_io, |
370 | .init_irq = lpc32xx_init_irq, | 337 | .init_irq = lpc32xx_init_irq, |
371 | .timer = &lpc32xx_timer, | 338 | .timer = &lpc32xx_timer, |
372 | .init_machine = phy3250_board_init, | 339 | .init_machine = lpc3250_machine_init, |
340 | .dt_compat = lpc32xx_dt_compat, | ||
373 | .restart = lpc23xx_restart, | 341 | .restart = lpc23xx_restart, |
374 | MACHINE_END | 342 | MACHINE_END |