diff options
| -rw-r--r-- | Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt | 14 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt | 33 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt | 4 | ||||
| -rw-r--r-- | arch/arm/mach-imx/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/irqchip/Makefile | 1 | ||||
| -rw-r--r-- | drivers/irqchip/irq-armada-370-xp.c | 89 | ||||
| -rw-r--r-- | drivers/irqchip/irq-digicolor.c | 4 | ||||
| -rw-r--r-- | drivers/irqchip/irq-gic.c | 2 | ||||
| -rw-r--r-- | drivers/irqchip/irq-mips-gic.c | 21 | ||||
| -rw-r--r-- | drivers/irqchip/irq-renesas-irqc.c | 54 | ||||
| -rw-r--r-- | drivers/irqchip/irq-vf610-mscm-ir.c | 212 | ||||
| -rw-r--r-- | include/linux/irqchip/mips-gic.h | 2 |
12 files changed, 396 insertions, 41 deletions
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt new file mode 100644 index 000000000000..44aa3c451ccf --- /dev/null +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | Freescale Vybrid Miscellaneous System Control - CPU Configuration | ||
| 2 | |||
| 3 | The MSCM IP contains multiple sub modules, this binding describes the first | ||
| 4 | block of registers which contains CPU configuration information. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible: "fsl,vf610-mscm-cpucfg", "syscon" | ||
| 8 | - reg: the register range of the MSCM CPU configuration registers | ||
| 9 | |||
| 10 | Example: | ||
| 11 | mscm_cpucfg: cpucfg@40001000 { | ||
| 12 | compatible = "fsl,vf610-mscm-cpucfg", "syscon"; | ||
| 13 | reg = <0x40001000 0x800>; | ||
| 14 | } | ||
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt new file mode 100644 index 000000000000..669808b2af49 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | Freescale Vybrid Miscellaneous System Control - Interrupt Router | ||
| 2 | |||
| 3 | The MSCM IP contains multiple sub modules, this binding describes the second | ||
| 4 | block of registers which control the interrupt router. The interrupt router | ||
| 5 | allows to configure the recipient of each peripheral interrupt. Furthermore | ||
| 6 | it controls the directed processor interrupts. The module is available in all | ||
| 7 | Vybrid SoC's but is only really useful in dual core configurations (VF6xx | ||
| 8 | which comes with a Cortex-A5/Cortex-M4 combination). | ||
| 9 | |||
| 10 | Required properties: | ||
| 11 | - compatible: "fsl,vf610-mscm-ir" | ||
| 12 | - reg: the register range of the MSCM Interrupt Router | ||
| 13 | - fsl,cpucfg: The handle to the MSCM CPU configuration node, required | ||
| 14 | to get the current CPU ID | ||
| 15 | - interrupt-controller: Identifies the node as an interrupt controller | ||
| 16 | - #interrupt-cells: Two cells, interrupt number and cells. | ||
| 17 | The hardware interrupt number according to interrupt | ||
| 18 | assignment of the interrupt router is required. | ||
| 19 | Flags get passed only when using GIC as parent. Flags | ||
| 20 | encoding as documented by the GIC bindings. | ||
| 21 | - interrupt-parent: Should be the phandle for the interrupt controller of | ||
| 22 | the CPU the device tree is intended to be used on. This | ||
| 23 | is either the node of the GIC or NVIC controller. | ||
| 24 | |||
| 25 | Example: | ||
| 26 | mscm_ir: interrupt-controller@40001800 { | ||
| 27 | compatible = "fsl,vf610-mscm-ir"; | ||
| 28 | reg = <0x40001800 0x400>; | ||
| 29 | fsl,cpucfg = <&mscm_cpucfg>; | ||
| 30 | interrupt-controller; | ||
| 31 | #interrupt-cells = <2>; | ||
| 32 | interrupt-parent = <&intc>; | ||
| 33 | } | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt index 1a88e62228e5..63633bdea7e4 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt | |||
| @@ -4,7 +4,7 @@ Required properties: | |||
| 4 | 4 | ||
| 5 | - compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. | 5 | - compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. |
| 6 | Examples with soctypes are: | 6 | Examples with soctypes are: |
| 7 | - "renesas,irqc-r8a73a4" (R-Mobile AP6) | 7 | - "renesas,irqc-r8a73a4" (R-Mobile APE6) |
| 8 | - "renesas,irqc-r8a7790" (R-Car H2) | 8 | - "renesas,irqc-r8a7790" (R-Car H2) |
| 9 | - "renesas,irqc-r8a7791" (R-Car M2-W) | 9 | - "renesas,irqc-r8a7791" (R-Car M2-W) |
| 10 | - "renesas,irqc-r8a7792" (R-Car V2H) | 10 | - "renesas,irqc-r8a7792" (R-Car V2H) |
| @@ -12,6 +12,7 @@ Required properties: | |||
| 12 | - "renesas,irqc-r8a7794" (R-Car E2) | 12 | - "renesas,irqc-r8a7794" (R-Car E2) |
| 13 | - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in | 13 | - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in |
| 14 | interrupts.txt in this directory | 14 | interrupts.txt in this directory |
| 15 | - clocks: Must contain a reference to the functional clock. | ||
| 15 | 16 | ||
| 16 | Optional properties: | 17 | Optional properties: |
| 17 | 18 | ||
| @@ -29,4 +30,5 @@ Example: | |||
| 29 | <0 1 IRQ_TYPE_LEVEL_HIGH>, | 30 | <0 1 IRQ_TYPE_LEVEL_HIGH>, |
| 30 | <0 2 IRQ_TYPE_LEVEL_HIGH>, | 31 | <0 2 IRQ_TYPE_LEVEL_HIGH>, |
| 31 | <0 3 IRQ_TYPE_LEVEL_HIGH>; | 32 | <0 3 IRQ_TYPE_LEVEL_HIGH>; |
| 33 | clocks = <&mstp4_clks R8A7790_CLK_IRQC>; | ||
| 32 | }; | 34 | }; |
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index e8627e04e1e6..c8dffcee9736 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
| @@ -631,6 +631,7 @@ config SOC_IMX6SX | |||
| 631 | 631 | ||
| 632 | config SOC_VF610 | 632 | config SOC_VF610 |
| 633 | bool "Vybrid Family VF610 support" | 633 | bool "Vybrid Family VF610 support" |
| 634 | select IRQ_DOMAIN_HIERARCHY | ||
| 634 | select ARM_GIC | 635 | select ARM_GIC |
| 635 | select PINCTRL_VF610 | 636 | select PINCTRL_VF610 |
| 636 | select PL310_ERRATA_769419 if CACHE_L2X0 | 637 | select PL310_ERRATA_769419 if CACHE_L2X0 |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 9bb4fd191e94..f117092ae014 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
| @@ -38,6 +38,7 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o | |||
| 38 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o | 38 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o |
| 39 | obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o | 39 | obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o |
| 40 | obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o | 40 | obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o |
| 41 | obj-$(CONFIG_SOC_VF610) += irq-vf610-mscm-ir.o | ||
| 41 | obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o | 42 | obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o |
| 42 | obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o | 43 | obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o |
| 43 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o | 44 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o |
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 4387dae14e45..daccc8bdbb42 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
| @@ -38,6 +38,8 @@ | |||
| 38 | /* Interrupt Controller Registers Map */ | 38 | /* Interrupt Controller Registers Map */ |
| 39 | #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) | 39 | #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) |
| 40 | #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) | 40 | #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) |
| 41 | #define ARMADA_370_XP_INT_FABRIC_MASK_OFFS (0x54) | ||
| 42 | #define ARMADA_370_XP_INT_CAUSE_PERF(cpu) (1 << cpu) | ||
| 41 | 43 | ||
| 42 | #define ARMADA_370_XP_INT_CONTROL (0x00) | 44 | #define ARMADA_370_XP_INT_CONTROL (0x00) |
| 43 | #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) | 45 | #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) |
| @@ -56,6 +58,7 @@ | |||
| 56 | #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) | 58 | #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) |
| 57 | 59 | ||
| 58 | #define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) | 60 | #define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) |
| 61 | #define ARMADA_370_XP_FABRIC_IRQ (3) | ||
| 59 | 62 | ||
| 60 | #define IPI_DOORBELL_START (0) | 63 | #define IPI_DOORBELL_START (0) |
| 61 | #define IPI_DOORBELL_END (8) | 64 | #define IPI_DOORBELL_END (8) |
| @@ -77,6 +80,17 @@ static DEFINE_MUTEX(msi_used_lock); | |||
| 77 | static phys_addr_t msi_doorbell_addr; | 80 | static phys_addr_t msi_doorbell_addr; |
| 78 | #endif | 81 | #endif |
| 79 | 82 | ||
| 83 | static inline bool is_percpu_irq(irq_hw_number_t irq) | ||
| 84 | { | ||
| 85 | switch (irq) { | ||
| 86 | case ARMADA_370_XP_TIMER0_PER_CPU_IRQ: | ||
| 87 | case ARMADA_370_XP_FABRIC_IRQ: | ||
| 88 | return true; | ||
| 89 | default: | ||
| 90 | return false; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 80 | /* | 94 | /* |
| 81 | * In SMP mode: | 95 | * In SMP mode: |
| 82 | * For shared global interrupts, mask/unmask global enable bit | 96 | * For shared global interrupts, mask/unmask global enable bit |
| @@ -86,7 +100,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d) | |||
| 86 | { | 100 | { |
| 87 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | 101 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 88 | 102 | ||
| 89 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | 103 | if (!is_percpu_irq(hwirq)) |
| 90 | writel(hwirq, main_int_base + | 104 | writel(hwirq, main_int_base + |
| 91 | ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); | 105 | ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); |
| 92 | else | 106 | else |
| @@ -98,7 +112,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) | |||
| 98 | { | 112 | { |
| 99 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | 113 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 100 | 114 | ||
| 101 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | 115 | if (!is_percpu_irq(hwirq)) |
| 102 | writel(hwirq, main_int_base + | 116 | writel(hwirq, main_int_base + |
| 103 | ARMADA_370_XP_INT_SET_ENABLE_OFFS); | 117 | ARMADA_370_XP_INT_SET_ENABLE_OFFS); |
| 104 | else | 118 | else |
| @@ -281,20 +295,21 @@ static struct irq_chip armada_370_xp_irq_chip = { | |||
| 281 | #ifdef CONFIG_SMP | 295 | #ifdef CONFIG_SMP |
| 282 | .irq_set_affinity = armada_xp_set_affinity, | 296 | .irq_set_affinity = armada_xp_set_affinity, |
| 283 | #endif | 297 | #endif |
| 298 | .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, | ||
| 284 | }; | 299 | }; |
| 285 | 300 | ||
| 286 | static int armada_370_xp_mpic_irq_map(struct irq_domain *h, | 301 | static int armada_370_xp_mpic_irq_map(struct irq_domain *h, |
| 287 | unsigned int virq, irq_hw_number_t hw) | 302 | unsigned int virq, irq_hw_number_t hw) |
| 288 | { | 303 | { |
| 289 | armada_370_xp_irq_mask(irq_get_irq_data(virq)); | 304 | armada_370_xp_irq_mask(irq_get_irq_data(virq)); |
| 290 | if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | 305 | if (!is_percpu_irq(hw)) |
| 291 | writel(hw, per_cpu_int_base + | 306 | writel(hw, per_cpu_int_base + |
| 292 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | 307 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); |
| 293 | else | 308 | else |
| 294 | writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); | 309 | writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); |
| 295 | irq_set_status_flags(virq, IRQ_LEVEL); | 310 | irq_set_status_flags(virq, IRQ_LEVEL); |
| 296 | 311 | ||
| 297 | if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { | 312 | if (is_percpu_irq(hw)) { |
| 298 | irq_set_percpu_devid(virq); | 313 | irq_set_percpu_devid(virq); |
| 299 | irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, | 314 | irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, |
| 300 | handle_percpu_devid_irq); | 315 | handle_percpu_devid_irq); |
| @@ -308,28 +323,6 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, | |||
| 308 | return 0; | 323 | return 0; |
| 309 | } | 324 | } |
| 310 | 325 | ||
| 311 | #ifdef CONFIG_SMP | ||
| 312 | static void armada_mpic_send_doorbell(const struct cpumask *mask, | ||
| 313 | unsigned int irq) | ||
| 314 | { | ||
| 315 | int cpu; | ||
| 316 | unsigned long map = 0; | ||
| 317 | |||
| 318 | /* Convert our logical CPU mask into a physical one. */ | ||
| 319 | for_each_cpu(cpu, mask) | ||
| 320 | map |= 1 << cpu_logical_map(cpu); | ||
| 321 | |||
| 322 | /* | ||
| 323 | * Ensure that stores to Normal memory are visible to the | ||
| 324 | * other CPUs before issuing the IPI. | ||
| 325 | */ | ||
| 326 | dsb(); | ||
| 327 | |||
| 328 | /* submit softirq */ | ||
| 329 | writel((map << 8) | irq, main_int_base + | ||
| 330 | ARMADA_370_XP_SW_TRIG_INT_OFFS); | ||
| 331 | } | ||
| 332 | |||
| 333 | static void armada_xp_mpic_smp_cpu_init(void) | 326 | static void armada_xp_mpic_smp_cpu_init(void) |
| 334 | { | 327 | { |
| 335 | u32 control; | 328 | u32 control; |
| @@ -352,11 +345,44 @@ static void armada_xp_mpic_smp_cpu_init(void) | |||
| 352 | writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | 345 | writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); |
| 353 | } | 346 | } |
| 354 | 347 | ||
| 348 | static void armada_xp_mpic_perf_init(void) | ||
| 349 | { | ||
| 350 | unsigned long cpuid = cpu_logical_map(smp_processor_id()); | ||
| 351 | |||
| 352 | /* Enable Performance Counter Overflow interrupts */ | ||
| 353 | writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid), | ||
| 354 | per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS); | ||
| 355 | } | ||
| 356 | |||
| 357 | #ifdef CONFIG_SMP | ||
| 358 | static void armada_mpic_send_doorbell(const struct cpumask *mask, | ||
| 359 | unsigned int irq) | ||
| 360 | { | ||
| 361 | int cpu; | ||
| 362 | unsigned long map = 0; | ||
| 363 | |||
| 364 | /* Convert our logical CPU mask into a physical one. */ | ||
| 365 | for_each_cpu(cpu, mask) | ||
| 366 | map |= 1 << cpu_logical_map(cpu); | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Ensure that stores to Normal memory are visible to the | ||
| 370 | * other CPUs before issuing the IPI. | ||
| 371 | */ | ||
| 372 | dsb(); | ||
| 373 | |||
| 374 | /* submit softirq */ | ||
| 375 | writel((map << 8) | irq, main_int_base + | ||
| 376 | ARMADA_370_XP_SW_TRIG_INT_OFFS); | ||
| 377 | } | ||
| 378 | |||
| 355 | static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, | 379 | static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, |
| 356 | unsigned long action, void *hcpu) | 380 | unsigned long action, void *hcpu) |
| 357 | { | 381 | { |
| 358 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | 382 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) { |
| 383 | armada_xp_mpic_perf_init(); | ||
| 359 | armada_xp_mpic_smp_cpu_init(); | 384 | armada_xp_mpic_smp_cpu_init(); |
| 385 | } | ||
| 360 | 386 | ||
| 361 | return NOTIFY_OK; | 387 | return NOTIFY_OK; |
| 362 | } | 388 | } |
| @@ -369,8 +395,10 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = { | |||
| 369 | static int mpic_cascaded_secondary_init(struct notifier_block *nfb, | 395 | static int mpic_cascaded_secondary_init(struct notifier_block *nfb, |
| 370 | unsigned long action, void *hcpu) | 396 | unsigned long action, void *hcpu) |
| 371 | { | 397 | { |
| 372 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | 398 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) { |
| 399 | armada_xp_mpic_perf_init(); | ||
| 373 | enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); | 400 | enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); |
| 401 | } | ||
| 374 | 402 | ||
| 375 | return NOTIFY_OK; | 403 | return NOTIFY_OK; |
| 376 | } | 404 | } |
| @@ -379,7 +407,6 @@ static struct notifier_block mpic_cascaded_cpu_notifier = { | |||
| 379 | .notifier_call = mpic_cascaded_secondary_init, | 407 | .notifier_call = mpic_cascaded_secondary_init, |
| 380 | .priority = 100, | 408 | .priority = 100, |
| 381 | }; | 409 | }; |
| 382 | |||
| 383 | #endif /* CONFIG_SMP */ | 410 | #endif /* CONFIG_SMP */ |
| 384 | 411 | ||
| 385 | static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { | 412 | static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { |
| @@ -588,9 +615,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, | |||
| 588 | 615 | ||
| 589 | BUG_ON(!armada_370_xp_mpic_domain); | 616 | BUG_ON(!armada_370_xp_mpic_domain); |
| 590 | 617 | ||
| 591 | #ifdef CONFIG_SMP | 618 | /* Setup for the boot CPU */ |
| 619 | armada_xp_mpic_perf_init(); | ||
| 592 | armada_xp_mpic_smp_cpu_init(); | 620 | armada_xp_mpic_smp_cpu_init(); |
| 593 | #endif | ||
| 594 | 621 | ||
| 595 | armada_370_xp_msi_init(node, main_int_res.start); | 622 | armada_370_xp_msi_init(node, main_int_res.start); |
| 596 | 623 | ||
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index 930a2a2fac7f..3cbc658afe27 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c | |||
| @@ -55,8 +55,8 @@ static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs) | |||
| 55 | } while (1); | 55 | } while (1); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, | 58 | static void __init digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, |
| 59 | unsigned en_reg, unsigned ack_reg) | 59 | unsigned en_reg, unsigned ack_reg) |
| 60 | { | 60 | { |
| 61 | struct irq_chip_generic *gc; | 61 | struct irq_chip_generic *gc; |
| 62 | 62 | ||
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 0b4a4d0238e7..d6d6b74801d4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
| @@ -414,7 +414,7 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic) | |||
| 414 | break; | 414 | break; |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | if (!mask) | 417 | if (!mask && num_possible_cpus() > 1) |
| 418 | pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); | 418 | pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); |
| 419 | 419 | ||
| 420 | return mask; | 420 | return mask; |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 9acdc080e7ec..f2d269bca789 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
| @@ -166,6 +166,27 @@ cycle_t gic_read_compare(void) | |||
| 166 | 166 | ||
| 167 | return (((cycle_t) hi) << 32) + lo; | 167 | return (((cycle_t) hi) << 32) + lo; |
| 168 | } | 168 | } |
| 169 | |||
| 170 | void gic_start_count(void) | ||
| 171 | { | ||
| 172 | u32 gicconfig; | ||
| 173 | |||
| 174 | /* Start the counter */ | ||
| 175 | gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); | ||
| 176 | gicconfig &= ~(1 << GIC_SH_CONFIG_COUNTSTOP_SHF); | ||
| 177 | gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | ||
| 178 | } | ||
| 179 | |||
| 180 | void gic_stop_count(void) | ||
| 181 | { | ||
| 182 | u32 gicconfig; | ||
| 183 | |||
| 184 | /* Stop the counter */ | ||
| 185 | gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); | ||
| 186 | gicconfig |= 1 << GIC_SH_CONFIG_COUNTSTOP_SHF; | ||
| 187 | gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | ||
| 188 | } | ||
| 189 | |||
| 169 | #endif | 190 | #endif |
| 170 | 191 | ||
| 171 | static bool gic_local_irq_is_routable(int intr) | 192 | static bool gic_local_irq_is_routable(int intr) |
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 2ea3412fdf8c..cdf80b7794cd 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/clk.h> | ||
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
| @@ -29,15 +30,26 @@ | |||
| 29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
| 31 | #include <linux/platform_data/irq-renesas-irqc.h> | 32 | #include <linux/platform_data/irq-renesas-irqc.h> |
| 33 | #include <linux/pm_runtime.h> | ||
| 32 | 34 | ||
| 33 | #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ | 35 | #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ |
| 34 | 36 | ||
| 35 | #define IRQC_REQ_STS 0x00 | 37 | #define IRQC_REQ_STS 0x00 /* Interrupt Request Status Register */ |
| 36 | #define IRQC_EN_STS 0x04 | 38 | #define IRQC_EN_STS 0x04 /* Interrupt Enable Status Register */ |
| 37 | #define IRQC_EN_SET 0x08 | 39 | #define IRQC_EN_SET 0x08 /* Interrupt Enable Set Register */ |
| 38 | #define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) | 40 | #define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) |
| 39 | #define DETECT_STATUS 0x100 | 41 | /* SYS-CPU vs. RT-CPU */ |
| 42 | #define DETECT_STATUS 0x100 /* IRQn Detect Status Register */ | ||
| 43 | #define MONITOR 0x104 /* IRQn Signal Level Monitor Register */ | ||
| 44 | #define HLVL_STS 0x108 /* IRQn High Level Detect Status Register */ | ||
| 45 | #define LLVL_STS 0x10c /* IRQn Low Level Detect Status Register */ | ||
| 46 | #define S_R_EDGE_STS 0x110 /* IRQn Sync Rising Edge Detect Status Reg. */ | ||
| 47 | #define S_F_EDGE_STS 0x114 /* IRQn Sync Falling Edge Detect Status Reg. */ | ||
| 48 | #define A_R_EDGE_STS 0x118 /* IRQn Async Rising Edge Detect Status Reg. */ | ||
| 49 | #define A_F_EDGE_STS 0x11c /* IRQn Async Falling Edge Detect Status Reg. */ | ||
| 50 | #define CHTEN_STS 0x120 /* Chattering Reduction Status Register */ | ||
| 40 | #define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) | 51 | #define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) |
| 52 | /* IRQn Configuration Register */ | ||
| 41 | 53 | ||
| 42 | struct irqc_irq { | 54 | struct irqc_irq { |
| 43 | int hw_irq; | 55 | int hw_irq; |
| @@ -55,6 +67,7 @@ struct irqc_priv { | |||
| 55 | struct platform_device *pdev; | 67 | struct platform_device *pdev; |
| 56 | struct irq_chip irq_chip; | 68 | struct irq_chip irq_chip; |
| 57 | struct irq_domain *irq_domain; | 69 | struct irq_domain *irq_domain; |
| 70 | struct clk *clk; | ||
| 58 | }; | 71 | }; |
| 59 | 72 | ||
| 60 | static void irqc_dbg(struct irqc_irq *i, char *str) | 73 | static void irqc_dbg(struct irqc_irq *i, char *str) |
| @@ -108,6 +121,21 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 108 | return 0; | 121 | return 0; |
| 109 | } | 122 | } |
| 110 | 123 | ||
| 124 | static int irqc_irq_set_wake(struct irq_data *d, unsigned int on) | ||
| 125 | { | ||
| 126 | struct irqc_priv *p = irq_data_get_irq_chip_data(d); | ||
| 127 | |||
| 128 | if (!p->clk) | ||
| 129 | return 0; | ||
| 130 | |||
| 131 | if (on) | ||
| 132 | clk_enable(p->clk); | ||
| 133 | else | ||
| 134 | clk_disable(p->clk); | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 111 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) | 139 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) |
| 112 | { | 140 | { |
| 113 | struct irqc_irq *i = dev_id; | 141 | struct irqc_irq *i = dev_id; |
| @@ -170,6 +198,15 @@ static int irqc_probe(struct platform_device *pdev) | |||
| 170 | p->pdev = pdev; | 198 | p->pdev = pdev; |
| 171 | platform_set_drvdata(pdev, p); | 199 | platform_set_drvdata(pdev, p); |
| 172 | 200 | ||
| 201 | p->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 202 | if (IS_ERR(p->clk)) { | ||
| 203 | dev_warn(&pdev->dev, "unable to get clock\n"); | ||
| 204 | p->clk = NULL; | ||
| 205 | } | ||
| 206 | |||
| 207 | pm_runtime_enable(&pdev->dev); | ||
| 208 | pm_runtime_get_sync(&pdev->dev); | ||
| 209 | |||
| 173 | /* get hold of manadatory IOMEM */ | 210 | /* get hold of manadatory IOMEM */ |
| 174 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 211 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 175 | if (!io) { | 212 | if (!io) { |
| @@ -210,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev) | |||
| 210 | irq_chip->irq_mask = irqc_irq_disable; | 247 | irq_chip->irq_mask = irqc_irq_disable; |
| 211 | irq_chip->irq_unmask = irqc_irq_enable; | 248 | irq_chip->irq_unmask = irqc_irq_enable; |
| 212 | irq_chip->irq_set_type = irqc_irq_set_type; | 249 | irq_chip->irq_set_type = irqc_irq_set_type; |
| 213 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; | 250 | irq_chip->irq_set_wake = irqc_irq_set_wake; |
| 251 | irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; | ||
| 214 | 252 | ||
| 215 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 253 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, |
| 216 | p->number_of_irqs, | 254 | p->number_of_irqs, |
| @@ -250,6 +288,8 @@ err3: | |||
| 250 | err2: | 288 | err2: |
| 251 | iounmap(p->iomem); | 289 | iounmap(p->iomem); |
| 252 | err1: | 290 | err1: |
| 291 | pm_runtime_put(&pdev->dev); | ||
| 292 | pm_runtime_disable(&pdev->dev); | ||
| 253 | kfree(p); | 293 | kfree(p); |
| 254 | err0: | 294 | err0: |
| 255 | return ret; | 295 | return ret; |
| @@ -265,6 +305,8 @@ static int irqc_remove(struct platform_device *pdev) | |||
| 265 | 305 | ||
| 266 | irq_domain_remove(p->irq_domain); | 306 | irq_domain_remove(p->irq_domain); |
| 267 | iounmap(p->iomem); | 307 | iounmap(p->iomem); |
| 308 | pm_runtime_put(&pdev->dev); | ||
| 309 | pm_runtime_disable(&pdev->dev); | ||
| 268 | kfree(p); | 310 | kfree(p); |
| 269 | return 0; | 311 | return 0; |
| 270 | } | 312 | } |
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c new file mode 100644 index 000000000000..9521057d4744 --- /dev/null +++ b/drivers/irqchip/irq-vf610-mscm-ir.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014-2015 Toradex AG | ||
| 3 | * Author: Stefan Agner <stefan@agner.ch> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * IRQ chip driver for MSCM interrupt router available on Vybrid SoC's. | ||
| 11 | * The interrupt router is between the CPU's interrupt controller and the | ||
| 12 | * peripheral. The router allows to route the peripheral interrupts to | ||
| 13 | * one of the two available CPU's on Vybrid VF6xx SoC's (Cortex-A5 or | ||
| 14 | * Cortex-M4). The router will be configured transparently on a IRQ | ||
| 15 | * request. | ||
| 16 | * | ||
| 17 | * o All peripheral interrupts of the Vybrid SoC can be routed to | ||
| 18 | * CPU 0, CPU 1 or both. The routing is useful for dual-core | ||
| 19 | * variants of Vybrid SoC such as VF6xx. This driver routes the | ||
| 20 | * requested interrupt to the CPU currently running on. | ||
| 21 | * | ||
| 22 | * o It is required to setup the interrupt router even on single-core | ||
| 23 | * variants of Vybrid. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/cpu_pm.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/irqdomain.h> | ||
| 30 | #include <linux/mfd/syscon.h> | ||
| 31 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 32 | #include <linux/of.h> | ||
| 33 | #include <linux/of_address.h> | ||
| 34 | #include <linux/slab.h> | ||
| 35 | #include <linux/regmap.h> | ||
| 36 | |||
| 37 | #include "irqchip.h" | ||
| 38 | |||
| 39 | #define MSCM_CPxNUM 0x4 | ||
| 40 | |||
| 41 | #define MSCM_IRSPRC(n) (0x80 + 2 * (n)) | ||
| 42 | #define MSCM_IRSPRC_CPEN_MASK 0x3 | ||
| 43 | |||
| 44 | #define MSCM_IRSPRC_NUM 112 | ||
| 45 | |||
| 46 | struct vf610_mscm_ir_chip_data { | ||
| 47 | void __iomem *mscm_ir_base; | ||
| 48 | u16 cpu_mask; | ||
| 49 | u16 saved_irsprc[MSCM_IRSPRC_NUM]; | ||
| 50 | }; | ||
| 51 | |||
| 52 | static struct vf610_mscm_ir_chip_data *mscm_ir_data; | ||
| 53 | |||
| 54 | static inline void vf610_mscm_ir_save(struct vf610_mscm_ir_chip_data *data) | ||
| 55 | { | ||
| 56 | int i; | ||
| 57 | |||
| 58 | for (i = 0; i < MSCM_IRSPRC_NUM; i++) | ||
| 59 | data->saved_irsprc[i] = readw_relaxed(data->mscm_ir_base + MSCM_IRSPRC(i)); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void vf610_mscm_ir_restore(struct vf610_mscm_ir_chip_data *data) | ||
| 63 | { | ||
| 64 | int i; | ||
| 65 | |||
| 66 | for (i = 0; i < MSCM_IRSPRC_NUM; i++) | ||
| 67 | writew_relaxed(data->saved_irsprc[i], data->mscm_ir_base + MSCM_IRSPRC(i)); | ||
| 68 | } | ||
| 69 | |||
| 70 | static int vf610_mscm_ir_notifier(struct notifier_block *self, | ||
| 71 | unsigned long cmd, void *v) | ||
| 72 | { | ||
| 73 | switch (cmd) { | ||
| 74 | case CPU_CLUSTER_PM_ENTER: | ||
| 75 | vf610_mscm_ir_save(mscm_ir_data); | ||
| 76 | break; | ||
| 77 | case CPU_CLUSTER_PM_ENTER_FAILED: | ||
| 78 | case CPU_CLUSTER_PM_EXIT: | ||
| 79 | vf610_mscm_ir_restore(mscm_ir_data); | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | |||
| 83 | return NOTIFY_OK; | ||
| 84 | } | ||
| 85 | |||
| 86 | static struct notifier_block mscm_ir_notifier_block = { | ||
| 87 | .notifier_call = vf610_mscm_ir_notifier, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static void vf610_mscm_ir_enable(struct irq_data *data) | ||
| 91 | { | ||
| 92 | irq_hw_number_t hwirq = data->hwirq; | ||
| 93 | struct vf610_mscm_ir_chip_data *chip_data = data->chip_data; | ||
| 94 | u16 irsprc; | ||
| 95 | |||
| 96 | irsprc = readw_relaxed(chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); | ||
| 97 | irsprc &= MSCM_IRSPRC_CPEN_MASK; | ||
| 98 | |||
| 99 | WARN_ON(irsprc & ~chip_data->cpu_mask); | ||
| 100 | |||
| 101 | writew_relaxed(chip_data->cpu_mask, | ||
| 102 | chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); | ||
| 103 | |||
| 104 | irq_chip_unmask_parent(data); | ||
| 105 | } | ||
| 106 | |||
| 107 | static void vf610_mscm_ir_disable(struct irq_data *data) | ||
| 108 | { | ||
| 109 | irq_hw_number_t hwirq = data->hwirq; | ||
| 110 | struct vf610_mscm_ir_chip_data *chip_data = data->chip_data; | ||
| 111 | |||
| 112 | writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); | ||
| 113 | |||
| 114 | irq_chip_mask_parent(data); | ||
| 115 | } | ||
| 116 | |||
| 117 | static struct irq_chip vf610_mscm_ir_irq_chip = { | ||
| 118 | .name = "mscm-ir", | ||
| 119 | .irq_mask = irq_chip_mask_parent, | ||
| 120 | .irq_unmask = irq_chip_unmask_parent, | ||
| 121 | .irq_eoi = irq_chip_eoi_parent, | ||
| 122 | .irq_enable = vf610_mscm_ir_enable, | ||
| 123 | .irq_disable = vf610_mscm_ir_disable, | ||
| 124 | .irq_retrigger = irq_chip_retrigger_hierarchy, | ||
| 125 | .irq_set_affinity = irq_chip_set_affinity_parent, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int virq, | ||
| 129 | unsigned int nr_irqs, void *arg) | ||
| 130 | { | ||
| 131 | int i; | ||
| 132 | irq_hw_number_t hwirq; | ||
| 133 | struct of_phandle_args *irq_data = arg; | ||
| 134 | struct of_phandle_args gic_data; | ||
| 135 | |||
| 136 | if (irq_data->args_count != 2) | ||
| 137 | return -EINVAL; | ||
| 138 | |||
| 139 | hwirq = irq_data->args[0]; | ||
| 140 | for (i = 0; i < nr_irqs; i++) | ||
| 141 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | ||
| 142 | &vf610_mscm_ir_irq_chip, | ||
| 143 | domain->host_data); | ||
| 144 | |||
| 145 | gic_data.np = domain->parent->of_node; | ||
| 146 | gic_data.args_count = 3; | ||
| 147 | gic_data.args[0] = GIC_SPI; | ||
| 148 | gic_data.args[1] = irq_data->args[0]; | ||
| 149 | gic_data.args[2] = irq_data->args[1]; | ||
| 150 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); | ||
| 151 | } | ||
| 152 | |||
| 153 | static const struct irq_domain_ops mscm_irq_domain_ops = { | ||
| 154 | .xlate = irq_domain_xlate_twocell, | ||
| 155 | .alloc = vf610_mscm_ir_domain_alloc, | ||
| 156 | .free = irq_domain_free_irqs_common, | ||
| 157 | }; | ||
| 158 | |||
| 159 | static int __init vf610_mscm_ir_of_init(struct device_node *node, | ||
| 160 | struct device_node *parent) | ||
| 161 | { | ||
| 162 | struct irq_domain *domain, *domain_parent; | ||
| 163 | struct regmap *mscm_cp_regmap; | ||
| 164 | int ret, cpuid; | ||
| 165 | |||
| 166 | domain_parent = irq_find_host(parent); | ||
| 167 | if (!domain_parent) { | ||
| 168 | pr_err("vf610_mscm_ir: interrupt-parent not found\n"); | ||
| 169 | return -EINVAL; | ||
| 170 | } | ||
| 171 | |||
| 172 | mscm_ir_data = kzalloc(sizeof(*mscm_ir_data), GFP_KERNEL); | ||
| 173 | if (!mscm_ir_data) | ||
| 174 | return -ENOMEM; | ||
| 175 | |||
| 176 | mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir"); | ||
| 177 | |||
| 178 | if (!mscm_ir_data->mscm_ir_base) { | ||
| 179 | pr_err("vf610_mscm_ir: unable to map mscm register\n"); | ||
| 180 | ret = -ENOMEM; | ||
| 181 | goto out_free; | ||
| 182 | } | ||
| 183 | |||
| 184 | mscm_cp_regmap = syscon_regmap_lookup_by_phandle(node, "fsl,cpucfg"); | ||
| 185 | if (IS_ERR(mscm_cp_regmap)) { | ||
| 186 | ret = PTR_ERR(mscm_cp_regmap); | ||
| 187 | pr_err("vf610_mscm_ir: regmap lookup for cpucfg failed\n"); | ||
| 188 | goto out_unmap; | ||
| 189 | } | ||
| 190 | |||
| 191 | regmap_read(mscm_cp_regmap, MSCM_CPxNUM, &cpuid); | ||
| 192 | mscm_ir_data->cpu_mask = 0x1 << cpuid; | ||
| 193 | |||
| 194 | domain = irq_domain_add_hierarchy(domain_parent, 0, | ||
| 195 | MSCM_IRSPRC_NUM, node, | ||
| 196 | &mscm_irq_domain_ops, mscm_ir_data); | ||
| 197 | if (!domain) { | ||
| 198 | ret = -ENOMEM; | ||
| 199 | goto out_unmap; | ||
| 200 | } | ||
| 201 | |||
| 202 | cpu_pm_register_notifier(&mscm_ir_notifier_block); | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | |||
| 206 | out_unmap: | ||
| 207 | iounmap(mscm_ir_data->mscm_ir_base); | ||
| 208 | out_free: | ||
| 209 | kfree(mscm_ir_data); | ||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | IRQCHIP_DECLARE(vf610_mscm_ir, "fsl,vf610-mscm-ir", vf610_mscm_ir_of_init); | ||
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index e6a6aac451db..3ea2e4754c40 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h | |||
| @@ -240,6 +240,8 @@ extern unsigned int gic_get_count_width(void); | |||
| 240 | extern cycle_t gic_read_compare(void); | 240 | extern cycle_t gic_read_compare(void); |
| 241 | extern void gic_write_compare(cycle_t cnt); | 241 | extern void gic_write_compare(cycle_t cnt); |
| 242 | extern void gic_write_cpu_compare(cycle_t cnt, int cpu); | 242 | extern void gic_write_cpu_compare(cycle_t cnt, int cpu); |
| 243 | extern void gic_start_count(void); | ||
| 244 | extern void gic_stop_count(void); | ||
| 243 | extern void gic_send_ipi(unsigned int intr); | 245 | extern void gic_send_ipi(unsigned int intr); |
| 244 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 246 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
| 245 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 247 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
