Commit 4672cddff21f6edde857aa4b523bbc1bfc741cf8
Committed by
Russell King
1 parent
4980f9bc2c
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ARM: 7518/1: integrator: convert AMBA devices to device tree
This converts the AMBA (PrimeCell) devices on the Integrator/AP and Integrator/CP over to probing from the Device Tree if the kernel is compiled for Device Tree support. We continue to #ifdef out all non-DT code and vice versa on respective boot type to get a clean cut. We need to add a bunch of auxdata (compare to the Versatile) to handle bus names and callbacks alike. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 7 changed files with 269 additions and 53 deletions Side-by-side Diff
arch/arm/boot/dts/integrator.dtsi
... | ... | @@ -30,5 +30,43 @@ |
30 | 30 | reg = <0x14000000 0x100>; |
31 | 31 | clear-mask = <0xffffffff>; |
32 | 32 | }; |
33 | + | |
34 | + fpga { | |
35 | + compatible = "arm,amba-bus", "simple-bus"; | |
36 | + #address-cells = <1>; | |
37 | + #size-cells = <1>; | |
38 | + ranges; | |
39 | + interrupt-parent = <&pic>; | |
40 | + | |
41 | + /* | |
42 | + * These PrimeCells are in the same locations and using the | |
43 | + * same interrupts in all Integrators, however the silicon | |
44 | + * version deployed is different. | |
45 | + */ | |
46 | + rtc@15000000 { | |
47 | + reg = <0x15000000 0x1000>; | |
48 | + interrupts = <8>; | |
49 | + }; | |
50 | + | |
51 | + uart@16000000 { | |
52 | + reg = <0x16000000 0x1000>; | |
53 | + interrupts = <1>; | |
54 | + }; | |
55 | + | |
56 | + uart@17000000 { | |
57 | + reg = <0x17000000 0x1000>; | |
58 | + interrupts = <2>; | |
59 | + }; | |
60 | + | |
61 | + kmi@18000000 { | |
62 | + reg = <0x18000000 0x1000>; | |
63 | + interrupts = <3>; | |
64 | + }; | |
65 | + | |
66 | + kmi@19000000 { | |
67 | + reg = <0x19000000 0x1000>; | |
68 | + interrupts = <4>; | |
69 | + }; | |
70 | + }; | |
33 | 71 | }; |
arch/arm/boot/dts/integratorap.dts
... | ... | @@ -33,5 +33,37 @@ |
33 | 33 | pic: pic@14000000 { |
34 | 34 | valid-mask = <0x003fffff>; |
35 | 35 | }; |
36 | + | |
37 | + fpga { | |
38 | + /* | |
39 | + * The Integator/AP predates the idea to have magic numbers | |
40 | + * identifying the PrimeCell in hardware, thus we have to | |
41 | + * supply these from the device tree. | |
42 | + */ | |
43 | + rtc: rtc@15000000 { | |
44 | + compatible = "arm,pl030", "arm,primecell"; | |
45 | + arm,primecell-periphid = <0x00041030>; | |
46 | + }; | |
47 | + | |
48 | + uart0: uart@16000000 { | |
49 | + compatible = "arm,pl010", "arm,primecell"; | |
50 | + arm,primecell-periphid = <0x00041010>; | |
51 | + }; | |
52 | + | |
53 | + uart1: uart@17000000 { | |
54 | + compatible = "arm,pl010", "arm,primecell"; | |
55 | + arm,primecell-periphid = <0x00041010>; | |
56 | + }; | |
57 | + | |
58 | + kmi0: kmi@18000000 { | |
59 | + compatible = "arm,pl050", "arm,primecell"; | |
60 | + arm,primecell-periphid = <0x00041050>; | |
61 | + }; | |
62 | + | |
63 | + kmi1: kmi@19000000 { | |
64 | + compatible = "arm,pl050", "arm,primecell"; | |
65 | + arm,primecell-periphid = <0x00041050>; | |
66 | + }; | |
67 | + }; | |
36 | 68 | }; |
arch/arm/boot/dts/integratorcp.dts
... | ... | @@ -51,5 +51,54 @@ |
51 | 51 | clear-mask = <0x00000fff>; |
52 | 52 | valid-mask = <0x00000fff>; |
53 | 53 | }; |
54 | + | |
55 | + fpga { | |
56 | + /* | |
57 | + * These PrimeCells are at the same location and using | |
58 | + * the same interrupts in all Integrators, but in the CP | |
59 | + * slightly newer versions are deployed. | |
60 | + */ | |
61 | + rtc@15000000 { | |
62 | + compatible = "arm,pl031", "arm,primecell"; | |
63 | + }; | |
64 | + | |
65 | + uart@16000000 { | |
66 | + compatible = "arm,pl011", "arm,primecell"; | |
67 | + }; | |
68 | + | |
69 | + uart@17000000 { | |
70 | + compatible = "arm,pl011", "arm,primecell"; | |
71 | + }; | |
72 | + | |
73 | + kmi@18000000 { | |
74 | + compatible = "arm,pl050", "arm,primecell"; | |
75 | + }; | |
76 | + | |
77 | + kmi@19000000 { | |
78 | + compatible = "arm,pl050", "arm,primecell"; | |
79 | + }; | |
80 | + | |
81 | + /* | |
82 | + * These PrimeCells are only available on the Integrator/CP | |
83 | + */ | |
84 | + mmc@1c000000 { | |
85 | + compatible = "arm,pl180", "arm,primecell"; | |
86 | + reg = <0x1c000000 0x1000>; | |
87 | + interrupts = <23 24>; | |
88 | + max-frequency = <515633>; | |
89 | + }; | |
90 | + | |
91 | + aaci@1d000000 { | |
92 | + compatible = "arm,pl041", "arm,primecell"; | |
93 | + reg = <0x1d000000 0x1000>; | |
94 | + interrupts = <25>; | |
95 | + }; | |
96 | + | |
97 | + clcd@c0000000 { | |
98 | + compatible = "arm,pl110", "arm,primecell"; | |
99 | + reg = <0xC0000000 0x1000>; | |
100 | + interrupts = <22>; | |
101 | + }; | |
102 | + }; | |
54 | 103 | }; |
arch/arm/mach-integrator/common.h
arch/arm/mach-integrator/core.c
... | ... | @@ -33,8 +33,10 @@ |
33 | 33 | #include <asm/mach/time.h> |
34 | 34 | #include <asm/pgtable.h> |
35 | 35 | |
36 | -static struct amba_pl010_data integrator_uart_data; | |
36 | +#include "common.h" | |
37 | 37 | |
38 | +#ifdef CONFIG_ATAGS | |
39 | + | |
38 | 40 | #define INTEGRATOR_RTC_IRQ { IRQ_RTCINT } |
39 | 41 | #define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 } |
40 | 42 | #define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 } |
... | ... | @@ -86,6 +88,8 @@ |
86 | 88 | return 0; |
87 | 89 | } |
88 | 90 | |
91 | +#endif | |
92 | + | |
89 | 93 | /* |
90 | 94 | * On the Integrator platform, the port RTS and DTR are provided by |
91 | 95 | * bits in the following SC_CTRLS register bits: |
... | ... | @@ -125,7 +129,7 @@ |
125 | 129 | __raw_writel(ctrlc, SC_CTRLC); |
126 | 130 | } |
127 | 131 | |
128 | -static struct amba_pl010_data integrator_uart_data = { | |
132 | +struct amba_pl010_data integrator_uart_data = { | |
129 | 133 | .set_mctrl = integrator_uart_set_mctrl, |
130 | 134 | }; |
131 | 135 |
arch/arm/mach-integrator/integrator_ap.c
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | #include <linux/platform_data/clk-integrator.h> |
37 | 37 | #include <linux/of_irq.h> |
38 | 38 | #include <linux/of_address.h> |
39 | +#include <linux/of_platform.h> | |
39 | 40 | #include <video/vga.h> |
40 | 41 | |
41 | 42 | #include <mach/hardware.h> |
... | ... | @@ -271,36 +272,6 @@ |
271 | 272 | .resource = &cfi_flash_resource, |
272 | 273 | }; |
273 | 274 | |
274 | -static void __init ap_init(void) | |
275 | -{ | |
276 | - unsigned long sc_dec; | |
277 | - int i; | |
278 | - | |
279 | - platform_device_register(&cfi_flash_device); | |
280 | - | |
281 | - sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); | |
282 | - for (i = 0; i < 4; i++) { | |
283 | - struct lm_device *lmdev; | |
284 | - | |
285 | - if ((sc_dec & (16 << i)) == 0) | |
286 | - continue; | |
287 | - | |
288 | - lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); | |
289 | - if (!lmdev) | |
290 | - continue; | |
291 | - | |
292 | - lmdev->resource.start = 0xc0000000 + 0x10000000 * i; | |
293 | - lmdev->resource.end = lmdev->resource.start + 0x0fffffff; | |
294 | - lmdev->resource.flags = IORESOURCE_MEM; | |
295 | - lmdev->irq = IRQ_AP_EXPINT0 + i; | |
296 | - lmdev->id = i; | |
297 | - | |
298 | - lm_device_register(lmdev); | |
299 | - } | |
300 | - | |
301 | - integrator_init(false); | |
302 | -} | |
303 | - | |
304 | 275 | /* |
305 | 276 | * Where is the timer (VA)? |
306 | 277 | */ |
... | ... | @@ -493,6 +464,52 @@ |
493 | 464 | integrator_clk_init(false); |
494 | 465 | } |
495 | 466 | |
467 | +/* For the Device Tree, add in the UART callbacks as AUXDATA */ | |
468 | +static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = { | |
469 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, | |
470 | + "rtc", NULL), | |
471 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, | |
472 | + "uart0", &integrator_uart_data), | |
473 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, | |
474 | + "uart1", &integrator_uart_data), | |
475 | + OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, | |
476 | + "kmi0", NULL), | |
477 | + OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, | |
478 | + "kmi1", NULL), | |
479 | + { /* sentinel */ }, | |
480 | +}; | |
481 | + | |
482 | +static void __init ap_init_of(void) | |
483 | +{ | |
484 | + unsigned long sc_dec; | |
485 | + int i; | |
486 | + | |
487 | + of_platform_populate(NULL, of_default_bus_match_table, | |
488 | + ap_auxdata_lookup, NULL); | |
489 | + | |
490 | + platform_device_register(&cfi_flash_device); | |
491 | + | |
492 | + sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); | |
493 | + for (i = 0; i < 4; i++) { | |
494 | + struct lm_device *lmdev; | |
495 | + | |
496 | + if ((sc_dec & (16 << i)) == 0) | |
497 | + continue; | |
498 | + | |
499 | + lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); | |
500 | + if (!lmdev) | |
501 | + continue; | |
502 | + | |
503 | + lmdev->resource.start = 0xc0000000 + 0x10000000 * i; | |
504 | + lmdev->resource.end = lmdev->resource.start + 0x0fffffff; | |
505 | + lmdev->resource.flags = IORESOURCE_MEM; | |
506 | + lmdev->irq = IRQ_AP_EXPINT0 + i; | |
507 | + lmdev->id = i; | |
508 | + | |
509 | + lm_device_register(lmdev); | |
510 | + } | |
511 | +} | |
512 | + | |
496 | 513 | static const char * ap_dt_board_compat[] = { |
497 | 514 | "arm,integrator-ap", |
498 | 515 | NULL, |
... | ... | @@ -506,7 +523,7 @@ |
506 | 523 | .init_irq = ap_init_irq_of, |
507 | 524 | .handle_irq = fpga_handle_irq, |
508 | 525 | .timer = &ap_of_timer, |
509 | - .init_machine = ap_init, | |
526 | + .init_machine = ap_init_of, | |
510 | 527 | .restart = integrator_restart, |
511 | 528 | .dt_compat = ap_dt_board_compat, |
512 | 529 | MACHINE_END |
... | ... | @@ -558,6 +575,36 @@ |
558 | 575 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, |
559 | 576 | -1, INTEGRATOR_SC_VALID_INT, NULL); |
560 | 577 | integrator_clk_init(false); |
578 | +} | |
579 | + | |
580 | +static void __init ap_init(void) | |
581 | +{ | |
582 | + unsigned long sc_dec; | |
583 | + int i; | |
584 | + | |
585 | + platform_device_register(&cfi_flash_device); | |
586 | + | |
587 | + sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); | |
588 | + for (i = 0; i < 4; i++) { | |
589 | + struct lm_device *lmdev; | |
590 | + | |
591 | + if ((sc_dec & (16 << i)) == 0) | |
592 | + continue; | |
593 | + | |
594 | + lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); | |
595 | + if (!lmdev) | |
596 | + continue; | |
597 | + | |
598 | + lmdev->resource.start = 0xc0000000 + 0x10000000 * i; | |
599 | + lmdev->resource.end = lmdev->resource.start + 0x0fffffff; | |
600 | + lmdev->resource.flags = IORESOURCE_MEM; | |
601 | + lmdev->irq = IRQ_AP_EXPINT0 + i; | |
602 | + lmdev->id = i; | |
603 | + | |
604 | + lm_device_register(lmdev); | |
605 | + } | |
606 | + | |
607 | + integrator_init(false); | |
561 | 608 | } |
562 | 609 | |
563 | 610 | MACHINE_START(INTEGRATOR, "ARM-Integrator") |
arch/arm/mach-integrator/integrator_cp.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <linux/platform_data/clk-integrator.h> |
26 | 26 | #include <linux/of_irq.h> |
27 | 27 | #include <linux/of_address.h> |
28 | +#include <linux/of_platform.h> | |
28 | 29 | |
29 | 30 | #include <mach/hardware.h> |
30 | 31 | #include <mach/platform.h> |
... | ... | @@ -245,16 +246,6 @@ |
245 | 246 | .gpio_cd = -1, |
246 | 247 | }; |
247 | 248 | |
248 | -#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } | |
249 | -#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } | |
250 | - | |
251 | -static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, | |
252 | - INTEGRATOR_CP_MMC_IRQS, &mmc_data); | |
253 | - | |
254 | -static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, | |
255 | - INTEGRATOR_CP_AACI_IRQS, NULL); | |
256 | - | |
257 | - | |
258 | 249 | /* |
259 | 250 | * CLCD support |
260 | 251 | */ |
... | ... | @@ -305,15 +296,6 @@ |
305 | 296 | .remove = versatile_clcd_remove_dma, |
306 | 297 | }; |
307 | 298 | |
308 | -static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, | |
309 | - { IRQ_CP_CLCDCINT }, &clcd_data); | |
310 | - | |
311 | -static struct amba_device *amba_devs[] __initdata = { | |
312 | - &mmc_device, | |
313 | - &aaci_device, | |
314 | - &clcd_device, | |
315 | -}; | |
316 | - | |
317 | 299 | #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28) |
318 | 300 | |
319 | 301 | static void __init intcp_init_early(void) |
... | ... | @@ -372,6 +354,37 @@ |
372 | 354 | integrator_clk_init(true); |
373 | 355 | } |
374 | 356 | |
357 | +/* | |
358 | + * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA | |
359 | + * and enforce the bus names since these are used for clock lookups. | |
360 | + */ | |
361 | +static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { | |
362 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, | |
363 | + "rtc", NULL), | |
364 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, | |
365 | + "uart0", &integrator_uart_data), | |
366 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, | |
367 | + "uart1", &integrator_uart_data), | |
368 | + OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, | |
369 | + "kmi0", NULL), | |
370 | + OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, | |
371 | + "kmi1", NULL), | |
372 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE, | |
373 | + "mmci", &mmc_data), | |
374 | + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_AACI_BASE, | |
375 | + "aaci", &mmc_data), | |
376 | + OF_DEV_AUXDATA("arm,primecell", INTCP_PA_CLCD_BASE, | |
377 | + "clcd", &clcd_data), | |
378 | + { /* sentinel */ }, | |
379 | +}; | |
380 | + | |
381 | +static void __init intcp_init_of(void) | |
382 | +{ | |
383 | + of_platform_populate(NULL, of_default_bus_match_table, | |
384 | + intcp_auxdata_lookup, NULL); | |
385 | + platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | |
386 | +} | |
387 | + | |
375 | 388 | static const char * intcp_dt_board_compat[] = { |
376 | 389 | "arm,integrator-cp", |
377 | 390 | NULL, |
... | ... | @@ -385,7 +398,7 @@ |
385 | 398 | .init_irq = intcp_init_irq_of, |
386 | 399 | .handle_irq = fpga_handle_irq, |
387 | 400 | .timer = &cp_of_timer, |
388 | - .init_machine = intcp_init, | |
401 | + .init_machine = intcp_init_of, | |
389 | 402 | .restart = integrator_restart, |
390 | 403 | .dt_compat = intcp_dt_board_compat, |
391 | 404 | MACHINE_END |
... | ... | @@ -452,6 +465,37 @@ |
452 | 465 | static struct sys_timer cp_timer = { |
453 | 466 | .init = intcp_timer_init, |
454 | 467 | }; |
468 | + | |
469 | +#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } | |
470 | +#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } | |
471 | + | |
472 | +static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, | |
473 | + INTEGRATOR_CP_MMC_IRQS, &mmc_data); | |
474 | + | |
475 | +static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, | |
476 | + INTEGRATOR_CP_AACI_IRQS, NULL); | |
477 | + | |
478 | +static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, | |
479 | + { IRQ_CP_CLCDCINT }, &clcd_data); | |
480 | + | |
481 | +static struct amba_device *amba_devs[] __initdata = { | |
482 | + &mmc_device, | |
483 | + &aaci_device, | |
484 | + &clcd_device, | |
485 | +}; | |
486 | + | |
487 | +static void __init intcp_init(void) | |
488 | +{ | |
489 | + int i; | |
490 | + | |
491 | + platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | |
492 | + | |
493 | + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | |
494 | + struct amba_device *d = amba_devs[i]; | |
495 | + amba_device_register(d, &iomem_resource); | |
496 | + } | |
497 | + integrator_init(true); | |
498 | +} | |
455 | 499 | |
456 | 500 | MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") |
457 | 501 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |