diff options
| -rw-r--r-- | Documentation/devicetree/bindings/arm/arm-boards | 12 | ||||
| -rw-r--r-- | arch/arm/boot/dts/integrator.dtsi | 33 | ||||
| -rw-r--r-- | arch/arm/boot/dts/integratorap.dts | 36 | ||||
| -rw-r--r-- | arch/arm/boot/dts/integratorcp.dts | 54 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 139 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 154 |
6 files changed, 360 insertions, 68 deletions
diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 91f26148af79..fc81a7d6b0f1 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | ARM Integrator/AP (Application Platform) and Integrator/CP (Compact Platform) | ||
| 2 | ----------------------------------------------------------------------------- | ||
| 3 | ARM's oldest Linux-supported platform with connectors for different core | ||
| 4 | tiles of ARMv4, ARMv5 and ARMv6 type. | ||
| 5 | |||
| 6 | Required properties (in root node): | ||
| 7 | compatible = "arm,integrator-ap"; /* Application Platform */ | ||
| 8 | compatible = "arm,integrator-cp"; /* Compact Platform */ | ||
| 9 | |||
| 10 | FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. | ||
| 11 | |||
| 12 | |||
| 1 | ARM Versatile Application and Platform Baseboards | 13 | ARM Versatile Application and Platform Baseboards |
| 2 | ------------------------------------------------- | 14 | ------------------------------------------------- |
| 3 | ARM's development hardware platform with connectors for customizable | 15 | ARM's development hardware platform with connectors for customizable |
diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi new file mode 100644 index 000000000000..b464abadd10b --- /dev/null +++ b/arch/arm/boot/dts/integrator.dtsi | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * SoC core Device Tree for the ARM Integrator platforms | ||
| 3 | */ | ||
| 4 | |||
| 5 | /include/ "skeleton.dtsi" | ||
| 6 | |||
| 7 | / { | ||
| 8 | timer@13000000 { | ||
| 9 | reg = <0x13000000 0x100>; | ||
| 10 | interrupt-parent = <&pic>; | ||
| 11 | interrupts = <5>; | ||
| 12 | }; | ||
| 13 | |||
| 14 | timer@13000100 { | ||
| 15 | reg = <0x13000100 0x100>; | ||
| 16 | interrupt-parent = <&pic>; | ||
| 17 | interrupts = <6>; | ||
| 18 | }; | ||
| 19 | |||
| 20 | timer@13000200 { | ||
| 21 | reg = <0x13000200 0x100>; | ||
| 22 | interrupt-parent = <&pic>; | ||
| 23 | interrupts = <7>; | ||
| 24 | }; | ||
| 25 | |||
| 26 | pic@14000000 { | ||
| 27 | compatible = "arm,versatile-fpga-irq"; | ||
| 28 | #interrupt-cells = <1>; | ||
| 29 | interrupt-controller; | ||
| 30 | reg = <0x14000000 0x100>; | ||
| 31 | clear-mask = <0xffffffff>; | ||
| 32 | }; | ||
| 33 | }; | ||
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts new file mode 100644 index 000000000000..083ff395de0f --- /dev/null +++ b/arch/arm/boot/dts/integratorap.dts | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree for the ARM Integrator/AP platform | ||
| 3 | */ | ||
| 4 | |||
| 5 | /dts-v1/; | ||
| 6 | /include/ "integrator.dtsi" | ||
| 7 | |||
| 8 | / { | ||
| 9 | model = "ARM Integrator/AP"; | ||
| 10 | compatible = "arm,integrator-ap"; | ||
| 11 | |||
| 12 | aliases { | ||
| 13 | arm,timer-primary = &timer2; | ||
| 14 | arm,timer-secondary = &timer1; | ||
| 15 | }; | ||
| 16 | |||
| 17 | chosen { | ||
| 18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; | ||
| 19 | }; | ||
| 20 | |||
| 21 | timer0: timer@13000000 { | ||
| 22 | compatible = "arm,integrator-timer"; | ||
| 23 | }; | ||
| 24 | |||
| 25 | timer1: timer@13000100 { | ||
| 26 | compatible = "arm,integrator-timer"; | ||
| 27 | }; | ||
| 28 | |||
| 29 | timer2: timer@13000200 { | ||
| 30 | compatible = "arm,integrator-timer"; | ||
| 31 | }; | ||
| 32 | |||
| 33 | pic: pic@14000000 { | ||
| 34 | valid-mask = <0x003fffff>; | ||
| 35 | }; | ||
| 36 | }; | ||
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts new file mode 100644 index 000000000000..63033144442a --- /dev/null +++ b/arch/arm/boot/dts/integratorcp.dts | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree for the ARM Integrator/CP platform | ||
| 3 | */ | ||
| 4 | |||
| 5 | /dts-v1/; | ||
| 6 | /include/ "integrator.dtsi" | ||
| 7 | |||
| 8 | / { | ||
| 9 | model = "ARM Integrator/CP"; | ||
| 10 | compatible = "arm,integrator-cp"; | ||
| 11 | |||
| 12 | aliases { | ||
| 13 | arm,timer-primary = &timer2; | ||
| 14 | arm,timer-secondary = &timer1; | ||
| 15 | }; | ||
| 16 | |||
| 17 | chosen { | ||
| 18 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; | ||
| 19 | }; | ||
| 20 | |||
| 21 | timer0: timer@13000000 { | ||
| 22 | compatible = "arm,sp804", "arm,primecell"; | ||
| 23 | }; | ||
| 24 | |||
| 25 | timer1: timer@13000100 { | ||
| 26 | compatible = "arm,sp804", "arm,primecell"; | ||
| 27 | }; | ||
| 28 | |||
| 29 | timer2: timer@13000200 { | ||
| 30 | compatible = "arm,sp804", "arm,primecell"; | ||
| 31 | }; | ||
| 32 | |||
| 33 | pic: pic@14000000 { | ||
| 34 | valid-mask = <0x1fc003ff>; | ||
| 35 | }; | ||
| 36 | |||
| 37 | cic: cic@10000040 { | ||
| 38 | compatible = "arm,versatile-fpga-irq"; | ||
| 39 | #interrupt-cells = <1>; | ||
| 40 | interrupt-controller; | ||
| 41 | reg = <0x10000040 0x100>; | ||
| 42 | clear-mask = <0xffffffff>; | ||
| 43 | valid-mask = <0x00000007>; | ||
| 44 | }; | ||
| 45 | |||
| 46 | sic: sic@ca000000 { | ||
| 47 | compatible = "arm,versatile-fpga-irq"; | ||
| 48 | #interrupt-cells = <1>; | ||
| 49 | interrupt-controller; | ||
| 50 | reg = <0xca000000 0x100>; | ||
| 51 | clear-mask = <0x00000fff>; | ||
| 52 | valid-mask = <0x00000fff>; | ||
| 53 | }; | ||
| 54 | }; | ||
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index ff966d83281c..57add86c4a69 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #include <linux/mtd/physmap.h> | 34 | #include <linux/mtd/physmap.h> |
| 35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
| 36 | #include <linux/platform_data/clk-integrator.h> | 36 | #include <linux/platform_data/clk-integrator.h> |
| 37 | #include <linux/of_irq.h> | ||
| 38 | #include <linux/of_address.h> | ||
| 37 | #include <video/vga.h> | 39 | #include <video/vga.h> |
| 38 | 40 | ||
| 39 | #include <mach/hardware.h> | 41 | #include <mach/hardware.h> |
| @@ -161,23 +163,6 @@ static void __init ap_map_io(void) | |||
| 161 | vga_base = PCI_MEMORY_VADDR; | 163 | vga_base = PCI_MEMORY_VADDR; |
| 162 | } | 164 | } |
| 163 | 165 | ||
| 164 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | ||
| 165 | |||
| 166 | static void __init ap_init_irq(void) | ||
| 167 | { | ||
| 168 | /* Disable all interrupts initially. */ | ||
| 169 | /* Do the core module ones */ | ||
| 170 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 171 | |||
| 172 | /* do the header card stuff next */ | ||
| 173 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
| 174 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
| 175 | |||
| 176 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, | ||
| 177 | -1, INTEGRATOR_SC_VALID_INT, NULL); | ||
| 178 | integrator_clk_init(false); | ||
| 179 | } | ||
| 180 | |||
| 181 | #ifdef CONFIG_PM | 166 | #ifdef CONFIG_PM |
| 182 | static unsigned long ic_irq_enable; | 167 | static unsigned long ic_irq_enable; |
| 183 | 168 | ||
| @@ -330,9 +315,9 @@ static u32 notrace integrator_read_sched_clock(void) | |||
| 330 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); | 315 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); |
| 331 | } | 316 | } |
| 332 | 317 | ||
| 333 | static void integrator_clocksource_init(unsigned long inrate) | 318 | static void integrator_clocksource_init(unsigned long inrate, |
| 319 | void __iomem *base) | ||
| 334 | { | 320 | { |
| 335 | void __iomem *base = (void __iomem *)TIMER2_VA_BASE; | ||
| 336 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | 321 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; |
| 337 | unsigned long rate = inrate; | 322 | unsigned long rate = inrate; |
| 338 | 323 | ||
| @@ -349,7 +334,7 @@ static void integrator_clocksource_init(unsigned long inrate) | |||
| 349 | setup_sched_clock(integrator_read_sched_clock, 16, rate); | 334 | setup_sched_clock(integrator_read_sched_clock, 16, rate); |
| 350 | } | 335 | } |
| 351 | 336 | ||
| 352 | static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; | 337 | static void __iomem * clkevt_base; |
| 353 | 338 | ||
| 354 | /* | 339 | /* |
| 355 | * IRQ handler for the timer | 340 | * IRQ handler for the timer |
| @@ -421,11 +406,13 @@ static struct irqaction integrator_timer_irq = { | |||
| 421 | .dev_id = &integrator_clockevent, | 406 | .dev_id = &integrator_clockevent, |
| 422 | }; | 407 | }; |
| 423 | 408 | ||
| 424 | static void integrator_clockevent_init(unsigned long inrate) | 409 | static void integrator_clockevent_init(unsigned long inrate, |
| 410 | void __iomem *base, int irq) | ||
| 425 | { | 411 | { |
| 426 | unsigned long rate = inrate; | 412 | unsigned long rate = inrate; |
| 427 | unsigned int ctrl = 0; | 413 | unsigned int ctrl = 0; |
| 428 | 414 | ||
| 415 | clkevt_base = base; | ||
| 429 | /* Calculate and program a divisor */ | 416 | /* Calculate and program a divisor */ |
| 430 | if (rate > 0x100000 * HZ) { | 417 | if (rate > 0x100000 * HZ) { |
| 431 | rate /= 256; | 418 | rate /= 256; |
| @@ -437,7 +424,7 @@ static void integrator_clockevent_init(unsigned long inrate) | |||
| 437 | timer_reload = rate / HZ; | 424 | timer_reload = rate / HZ; |
| 438 | writel(ctrl, clkevt_base + TIMER_CTRL); | 425 | writel(ctrl, clkevt_base + TIMER_CTRL); |
| 439 | 426 | ||
| 440 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); | 427 | setup_irq(irq, &integrator_timer_irq); |
| 441 | clockevents_config_and_register(&integrator_clockevent, | 428 | clockevents_config_and_register(&integrator_clockevent, |
| 442 | rate, | 429 | rate, |
| 443 | 1, | 430 | 1, |
| @@ -448,9 +435,91 @@ void __init ap_init_early(void) | |||
| 448 | { | 435 | { |
| 449 | } | 436 | } |
| 450 | 437 | ||
| 438 | #ifdef CONFIG_OF | ||
| 439 | |||
| 440 | static void __init ap_init_timer_of(void) | ||
| 441 | { | ||
| 442 | struct device_node *node; | ||
| 443 | const char *path; | ||
| 444 | void __iomem *base; | ||
| 445 | int err; | ||
| 446 | int irq; | ||
| 447 | struct clk *clk; | ||
| 448 | unsigned long rate; | ||
| 449 | |||
| 450 | clk = clk_get_sys("ap_timer", NULL); | ||
| 451 | BUG_ON(IS_ERR(clk)); | ||
| 452 | clk_prepare_enable(clk); | ||
| 453 | rate = clk_get_rate(clk); | ||
| 454 | |||
| 455 | err = of_property_read_string(of_aliases, | ||
| 456 | "arm,timer-primary", &path); | ||
| 457 | if (WARN_ON(err)) | ||
| 458 | return; | ||
| 459 | node = of_find_node_by_path(path); | ||
| 460 | base = of_iomap(node, 0); | ||
| 461 | if (WARN_ON(!base)) | ||
| 462 | return; | ||
| 463 | writel(0, base + TIMER_CTRL); | ||
| 464 | integrator_clocksource_init(rate, base); | ||
| 465 | |||
| 466 | err = of_property_read_string(of_aliases, | ||
| 467 | "arm,timer-secondary", &path); | ||
| 468 | if (WARN_ON(err)) | ||
| 469 | return; | ||
| 470 | node = of_find_node_by_path(path); | ||
| 471 | base = of_iomap(node, 0); | ||
| 472 | if (WARN_ON(!base)) | ||
| 473 | return; | ||
| 474 | irq = irq_of_parse_and_map(node, 0); | ||
| 475 | writel(0, base + TIMER_CTRL); | ||
| 476 | integrator_clockevent_init(rate, base, irq); | ||
| 477 | } | ||
| 478 | |||
| 479 | static struct sys_timer ap_of_timer = { | ||
| 480 | .init = ap_init_timer_of, | ||
| 481 | }; | ||
| 482 | |||
| 483 | static const struct of_device_id fpga_irq_of_match[] __initconst = { | ||
| 484 | { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, | ||
| 485 | { /* Sentinel */ } | ||
| 486 | }; | ||
| 487 | |||
| 488 | static void __init ap_init_irq_of(void) | ||
| 489 | { | ||
| 490 | /* disable core module IRQs */ | ||
| 491 | writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 492 | of_irq_init(fpga_irq_of_match); | ||
| 493 | integrator_clk_init(false); | ||
| 494 | } | ||
| 495 | |||
| 496 | static const char * ap_dt_board_compat[] = { | ||
| 497 | "arm,integrator-ap", | ||
| 498 | NULL, | ||
| 499 | }; | ||
| 500 | |||
| 501 | DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") | ||
| 502 | .reserve = integrator_reserve, | ||
| 503 | .map_io = ap_map_io, | ||
| 504 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, | ||
| 505 | .init_early = ap_init_early, | ||
| 506 | .init_irq = ap_init_irq_of, | ||
| 507 | .handle_irq = fpga_handle_irq, | ||
| 508 | .timer = &ap_of_timer, | ||
| 509 | .init_machine = ap_init, | ||
| 510 | .restart = integrator_restart, | ||
| 511 | .dt_compat = ap_dt_board_compat, | ||
| 512 | MACHINE_END | ||
| 513 | |||
| 514 | #endif | ||
| 515 | |||
| 516 | #ifdef CONFIG_ATAGS | ||
| 517 | |||
| 451 | /* | 518 | /* |
| 452 | * Set up timer(s). | 519 | * This is where non-devicetree initialization code is collected and stashed |
| 520 | * for eventual deletion. | ||
| 453 | */ | 521 | */ |
| 522 | |||
| 454 | static void __init ap_init_timer(void) | 523 | static void __init ap_init_timer(void) |
| 455 | { | 524 | { |
| 456 | struct clk *clk; | 525 | struct clk *clk; |
| @@ -465,14 +534,32 @@ static void __init ap_init_timer(void) | |||
| 465 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | 534 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); |
| 466 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); | 535 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); |
| 467 | 536 | ||
| 468 | integrator_clocksource_init(rate); | 537 | integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE); |
| 469 | integrator_clockevent_init(rate); | 538 | integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE, |
| 539 | IRQ_TIMERINT1); | ||
| 470 | } | 540 | } |
| 471 | 541 | ||
| 472 | static struct sys_timer ap_timer = { | 542 | static struct sys_timer ap_timer = { |
| 473 | .init = ap_init_timer, | 543 | .init = ap_init_timer, |
| 474 | }; | 544 | }; |
| 475 | 545 | ||
| 546 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | ||
| 547 | |||
| 548 | static void __init ap_init_irq(void) | ||
| 549 | { | ||
| 550 | /* Disable all interrupts initially. */ | ||
| 551 | /* Do the core module ones */ | ||
| 552 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 553 | |||
| 554 | /* do the header card stuff next */ | ||
| 555 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
| 556 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
| 557 | |||
| 558 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, | ||
| 559 | -1, INTEGRATOR_SC_VALID_INT, NULL); | ||
| 560 | integrator_clk_init(false); | ||
| 561 | } | ||
| 562 | |||
| 476 | MACHINE_START(INTEGRATOR, "ARM-Integrator") | 563 | MACHINE_START(INTEGRATOR, "ARM-Integrator") |
| 477 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 564 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 478 | .atag_offset = 0x100, | 565 | .atag_offset = 0x100, |
| @@ -486,3 +573,5 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") | |||
| 486 | .init_machine = ap_init, | 573 | .init_machine = ap_init, |
| 487 | .restart = integrator_restart, | 574 | .restart = integrator_restart, |
| 488 | MACHINE_END | 575 | MACHINE_END |
| 576 | |||
| 577 | #endif | ||
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 2b40bc10b388..6a2293a28a84 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/gfp.h> | 23 | #include <linux/gfp.h> |
| 24 | #include <linux/mtd/physmap.h> | 24 | #include <linux/mtd/physmap.h> |
| 25 | #include <linux/platform_data/clk-integrator.h> | 25 | #include <linux/platform_data/clk-integrator.h> |
| 26 | #include <linux/of_irq.h> | ||
| 27 | #include <linux/of_address.h> | ||
| 26 | 28 | ||
| 27 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| 28 | #include <mach/platform.h> | 30 | #include <mach/platform.h> |
| @@ -53,10 +55,6 @@ | |||
| 53 | 55 | ||
| 54 | #define INTCP_PA_CLCD_BASE 0xc0000000 | 56 | #define INTCP_PA_CLCD_BASE 0xc0000000 |
| 55 | 57 | ||
| 56 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | ||
| 57 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
| 58 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
| 59 | |||
| 60 | #define INTCP_ETH_SIZE 0x10 | 58 | #define INTCP_ETH_SIZE 0x10 |
| 61 | 59 | ||
| 62 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) | 60 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) |
| @@ -143,37 +141,6 @@ static void __init intcp_map_io(void) | |||
| 143 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); | 141 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); |
| 144 | } | 142 | } |
| 145 | 143 | ||
| 146 | static void __init intcp_init_irq(void) | ||
| 147 | { | ||
| 148 | u32 pic_mask, cic_mask, sic_mask; | ||
| 149 | |||
| 150 | /* These masks are for the HW IRQ registers */ | ||
| 151 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
| 152 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
| 153 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
| 154 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Disable all interrupt sources | ||
| 158 | */ | ||
| 159 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 160 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 161 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 162 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 163 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 164 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 165 | |||
| 166 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
| 167 | -1, pic_mask, NULL); | ||
| 168 | |||
| 169 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
| 170 | -1, cic_mask, NULL); | ||
| 171 | |||
| 172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
| 173 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
| 174 | integrator_clk_init(true); | ||
| 175 | } | ||
| 176 | |||
| 177 | /* | 144 | /* |
| 178 | * Flash handling. | 145 | * Flash handling. |
| 179 | */ | 146 | */ |
| @@ -356,17 +323,116 @@ static void __init intcp_init_early(void) | |||
| 356 | #endif | 323 | #endif |
| 357 | } | 324 | } |
| 358 | 325 | ||
| 359 | static void __init intcp_init(void) | 326 | static void __init intcp_timer_init_of(void) |
| 327 | { | ||
| 328 | struct device_node *node; | ||
| 329 | const char *path; | ||
| 330 | void __iomem *base; | ||
| 331 | int err; | ||
| 332 | int irq; | ||
| 333 | |||
| 334 | err = of_property_read_string(of_aliases, | ||
| 335 | "arm,timer-primary", &path); | ||
| 336 | if (WARN_ON(err)) | ||
| 337 | return; | ||
| 338 | node = of_find_node_by_path(path); | ||
| 339 | base = of_iomap(node, 0); | ||
| 340 | if (WARN_ON(!base)) | ||
| 341 | return; | ||
| 342 | writel(0, base + TIMER_CTRL); | ||
| 343 | sp804_clocksource_init(base, node->name); | ||
| 344 | |||
| 345 | err = of_property_read_string(of_aliases, | ||
| 346 | "arm,timer-secondary", &path); | ||
| 347 | if (WARN_ON(err)) | ||
| 348 | return; | ||
| 349 | node = of_find_node_by_path(path); | ||
| 350 | base = of_iomap(node, 0); | ||
| 351 | if (WARN_ON(!base)) | ||
| 352 | return; | ||
| 353 | irq = irq_of_parse_and_map(node, 0); | ||
| 354 | writel(0, base + TIMER_CTRL); | ||
| 355 | sp804_clockevents_init(base, irq, node->name); | ||
| 356 | } | ||
| 357 | |||
| 358 | static struct sys_timer cp_of_timer = { | ||
| 359 | .init = intcp_timer_init_of, | ||
| 360 | }; | ||
| 361 | |||
| 362 | #ifdef CONFIG_OF | ||
| 363 | |||
| 364 | static const struct of_device_id fpga_irq_of_match[] __initconst = { | ||
| 365 | { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, | ||
| 366 | { /* Sentinel */ } | ||
| 367 | }; | ||
| 368 | |||
| 369 | static void __init intcp_init_irq_of(void) | ||
| 360 | { | 370 | { |
| 361 | int i; | 371 | of_irq_init(fpga_irq_of_match); |
| 372 | integrator_clk_init(true); | ||
| 373 | } | ||
| 362 | 374 | ||
| 363 | platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | 375 | static const char * intcp_dt_board_compat[] = { |
| 376 | "arm,integrator-cp", | ||
| 377 | NULL, | ||
| 378 | }; | ||
| 364 | 379 | ||
| 365 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 380 | DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") |
| 366 | struct amba_device *d = amba_devs[i]; | 381 | .reserve = integrator_reserve, |
| 367 | amba_device_register(d, &iomem_resource); | 382 | .map_io = intcp_map_io, |
| 368 | } | 383 | .nr_irqs = NR_IRQS_INTEGRATOR_CP, |
| 369 | integrator_init(true); | 384 | .init_early = intcp_init_early, |
| 385 | .init_irq = intcp_init_irq_of, | ||
| 386 | .handle_irq = fpga_handle_irq, | ||
| 387 | .timer = &cp_of_timer, | ||
| 388 | .init_machine = intcp_init, | ||
| 389 | .restart = integrator_restart, | ||
| 390 | .dt_compat = intcp_dt_board_compat, | ||
| 391 | MACHINE_END | ||
| 392 | |||
| 393 | #endif | ||
| 394 | |||
| 395 | #ifdef CONFIG_ATAGS | ||
| 396 | |||
| 397 | /* | ||
| 398 | * This is where non-devicetree initialization code is collected and stashed | ||
| 399 | * for eventual deletion. | ||
| 400 | */ | ||
| 401 | |||
| 402 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | ||
| 403 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
| 404 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
| 405 | |||
| 406 | static void __init intcp_init_irq(void) | ||
| 407 | { | ||
| 408 | u32 pic_mask, cic_mask, sic_mask; | ||
| 409 | |||
| 410 | /* These masks are for the HW IRQ registers */ | ||
| 411 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
| 412 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
| 413 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
| 414 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
| 415 | |||
| 416 | /* | ||
| 417 | * Disable all interrupt sources | ||
| 418 | */ | ||
| 419 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 420 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 421 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 422 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 423 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
| 424 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
| 425 | |||
| 426 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
| 427 | -1, pic_mask, NULL); | ||
| 428 | |||
| 429 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
| 430 | -1, cic_mask, NULL); | ||
| 431 | |||
| 432 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
| 433 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
| 434 | |||
| 435 | integrator_clk_init(true); | ||
| 370 | } | 436 | } |
| 371 | 437 | ||
| 372 | #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) | 438 | #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) |
| @@ -400,3 +466,5 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") | |||
| 400 | .init_machine = intcp_init, | 466 | .init_machine = intcp_init, |
| 401 | .restart = integrator_restart, | 467 | .restart = integrator_restart, |
| 402 | MACHINE_END | 468 | MACHINE_END |
| 469 | |||
| 470 | #endif | ||
