diff options
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index a32e0d5aa45f..add1fd84fc4b 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
31 | #include <linux/cpu.h> | ||
31 | #include <linux/cpu_pm.h> | 32 | #include <linux/cpu_pm.h> |
32 | #include <linux/cpumask.h> | 33 | #include <linux/cpumask.h> |
33 | #include <linux/io.h> | 34 | #include <linux/io.h> |
@@ -38,12 +39,12 @@ | |||
38 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
39 | #include <linux/percpu.h> | 40 | #include <linux/percpu.h> |
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/irqchip/chained_irq.h> | ||
41 | #include <linux/irqchip/arm-gic.h> | 43 | #include <linux/irqchip/arm-gic.h> |
42 | 44 | ||
43 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
44 | #include <asm/exception.h> | 46 | #include <asm/exception.h> |
45 | #include <asm/smp_plat.h> | 47 | #include <asm/smp_plat.h> |
46 | #include <asm/mach/irq.h> | ||
47 | 48 | ||
48 | #include "irqchip.h" | 49 | #include "irqchip.h" |
49 | 50 | ||
@@ -323,7 +324,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
323 | 324 | ||
324 | cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); | 325 | cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); |
325 | if (unlikely(gic_irq < 32 || gic_irq > 1020)) | 326 | if (unlikely(gic_irq < 32 || gic_irq > 1020)) |
326 | do_bad_IRQ(cascade_irq, desc); | 327 | handle_bad_irq(cascade_irq, desc); |
327 | else | 328 | else |
328 | generic_handle_irq(cascade_irq); | 329 | generic_handle_irq(cascade_irq); |
329 | 330 | ||
@@ -699,6 +700,25 @@ static int gic_irq_domain_xlate(struct irq_domain *d, | |||
699 | return 0; | 700 | return 0; |
700 | } | 701 | } |
701 | 702 | ||
703 | #ifdef CONFIG_SMP | ||
704 | static int __cpuinit gic_secondary_init(struct notifier_block *nfb, | ||
705 | unsigned long action, void *hcpu) | ||
706 | { | ||
707 | if (action == CPU_STARTING) | ||
708 | gic_cpu_init(&gic_data[0]); | ||
709 | return NOTIFY_OK; | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * Notifier for enabling the GIC CPU interface. Set an arbitrarily high | ||
714 | * priority because the GIC needs to be up before the ARM generic timers. | ||
715 | */ | ||
716 | static struct notifier_block __cpuinitdata gic_cpu_notifier = { | ||
717 | .notifier_call = gic_secondary_init, | ||
718 | .priority = 100, | ||
719 | }; | ||
720 | #endif | ||
721 | |||
702 | const struct irq_domain_ops gic_irq_domain_ops = { | 722 | const struct irq_domain_ops gic_irq_domain_ops = { |
703 | .map = gic_irq_domain_map, | 723 | .map = gic_irq_domain_map, |
704 | .xlate = gic_irq_domain_xlate, | 724 | .xlate = gic_irq_domain_xlate, |
@@ -789,6 +809,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
789 | 809 | ||
790 | #ifdef CONFIG_SMP | 810 | #ifdef CONFIG_SMP |
791 | set_smp_cross_call(gic_raise_softirq); | 811 | set_smp_cross_call(gic_raise_softirq); |
812 | register_cpu_notifier(&gic_cpu_notifier); | ||
792 | #endif | 813 | #endif |
793 | 814 | ||
794 | set_handle_irq(gic_handle_irq); | 815 | set_handle_irq(gic_handle_irq); |
@@ -799,13 +820,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
799 | gic_pm_init(gic); | 820 | gic_pm_init(gic); |
800 | } | 821 | } |
801 | 822 | ||
802 | void __cpuinit gic_secondary_init(unsigned int gic_nr) | ||
803 | { | ||
804 | BUG_ON(gic_nr >= MAX_GIC_NR); | ||
805 | |||
806 | gic_cpu_init(&gic_data[gic_nr]); | ||
807 | } | ||
808 | |||
809 | #ifdef CONFIG_OF | 823 | #ifdef CONFIG_OF |
810 | static int gic_cnt __initdata = 0; | 824 | static int gic_cnt __initdata = 0; |
811 | 825 | ||