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 /arch/arm/mach-lpc32xx | |
| 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>
Diffstat (limited to 'arch/arm/mach-lpc32xx')
| -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 |
4 files changed, 111 insertions, 311 deletions
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c index 6f255600fc9..0a41e1ec0c3 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 68e45e8c948..afeac3b1fae 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 d080cb1123d..5b1cc35e6fb 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 7f7401ec748..483846ff829 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 |
