From a528721da08a793e0cec6ef6281d404eddd6e27b Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 4 Nov 2011 15:05:24 +0000 Subject: ARM: restart: add restart hook to machine_desc record Add a restart hook to the machine_desc record so we don't have to populate all platforms with init_early methods to initialize the arm_pm_restart function pointer. Acked-by: Nicolas Pitre Acked-by: Will Deacon Acked-by: H Hartley Sweeten Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/include/asm/mach/arch.h | 1 + arch/arm/kernel/setup.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 7d19425dd49..8aa397a5ea7 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -45,6 +45,7 @@ struct machine_desc { #ifdef CONFIG_MULTI_IRQ_HANDLER void (*handle_irq)(struct pt_regs *); #endif + void (*restart)(char, const char *); }; /* diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 7e7977ab994..4755e2827dc 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -922,6 +922,9 @@ void __init setup_arch(char **cmdline_p) paging_init(mdesc); request_standard_resources(mdesc); + if (mdesc->restart) + arm_pm_restart = mdesc->restart; + unflatten_device_tree(); #ifdef CONFIG_SMP -- cgit v1.2.3 From b44c350d4104265cf3a6b4355dc1ee05c16aa5de Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 1 Nov 2011 14:27:33 +0000 Subject: ARM: restart: allow platforms more flexibility specifying restart mode Change 'soft_reboot' into a more generic 'restart_mode' variable, allowing the default restart mode to be specified. Acked-by: Nicolas Pitre Acked-by: Will Deacon Acked-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/include/asm/mach/arch.h | 8 ++++---- arch/arm/kernel/setup.c | 4 ++-- arch/arm/mach-ebsa110/core.c | 2 +- arch/arm/mach-footbridge/cats-hw.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 8aa397a5ea7..6fe6cf0895c 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -30,10 +30,10 @@ struct machine_desc { unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ - unsigned int reserve_lp0 :1; /* never has lp0 */ - unsigned int reserve_lp1 :1; /* never has lp1 */ - unsigned int reserve_lp2 :1; /* never has lp2 */ - unsigned int soft_reboot :1; /* soft reboot */ + unsigned char reserve_lp0 :1; /* never has lp0 */ + unsigned char reserve_lp1 :1; /* never has lp1 */ + unsigned char reserve_lp2 :1; /* never has lp2 */ + char restart_mode; /* default restart mode */ void (*fixup)(struct tag *, char **, struct meminfo *); void (*reserve)(void);/* reserve mem blocks */ diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 4755e2827dc..a753880e984 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -902,8 +902,8 @@ void __init setup_arch(char **cmdline_p) machine_desc = mdesc; machine_name = mdesc->name; - if (mdesc->soft_reboot) - reboot_setup("s"); + if (mdesc->restart_mode) + reboot_setup(&mdesc->restart_mode); init_mm.start_code = (unsigned long) _text; init_mm.end_code = (unsigned long) _etext; diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index d0ce8abdd4b..ce3ed244c4b 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -283,7 +283,7 @@ MACHINE_START(EBSA110, "EBSA110") .atag_offset = 0x400, .reserve_lp0 = 1, .reserve_lp2 = 1, - .soft_reboot = 1, + .restart_mode = 's', .map_io = ebsa110_map_io, .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index d5f17854092..60b6774e1ea 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -86,7 +86,7 @@ fixup_cats(struct tag *tags, char **cmdline, struct meminfo *mi) MACHINE_START(CATS, "Chalice-CATS") /* Maintainer: Philip Blundell */ .atag_offset = 0x100, - .soft_reboot = 1, + .restart_mode = 's', .fixup = fixup_cats, .map_io = footbridge_map_io, .init_irq = footbridge_init_irq, -- cgit v1.2.3 From 34adeda943e1fb10e8de022b834996e04241fa7d Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 1 Nov 2011 16:24:18 +0000 Subject: ARM: restart: add default restart modes for PXA mioa701, spitz and tosa Add a default restart mode to reflect the hard-coded restart mode found in these files. Acked-by: Nicolas Pitre Acked-by: Will Deacon Acked-by: H Hartley Sweeten Acked-by: Robert Jarzmik Signed-off-by: Russell King --- arch/arm/mach-pxa/mioa701.c | 1 + arch/arm/mach-pxa/spitz.c | 3 +++ arch/arm/mach-pxa/tosa.c | 1 + 3 files changed, 5 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index b938fc2c316..4f47a760398 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -752,6 +752,7 @@ static void mioa701_machine_exit(void) MACHINE_START(MIOA701, "MIO A701") .atag_offset = 0x100, + .restart_mode = 's', .map_io = &pxa27x_map_io, .init_irq = &pxa27x_init_irq, .handle_irq = &pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 953a9195f9e..2f57d94de72 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -982,6 +982,7 @@ static void __init spitz_fixup(struct tag *tags, char **cmdline, #ifdef CONFIG_MACH_SPITZ MACHINE_START(SPITZ, "SHARP Spitz") + .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, @@ -993,6 +994,7 @@ MACHINE_END #ifdef CONFIG_MACH_BORZOI MACHINE_START(BORZOI, "SHARP Borzoi") + .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, @@ -1004,6 +1006,7 @@ MACHINE_END #ifdef CONFIG_MACH_AKITA MACHINE_START(AKITA, "SHARP Akita") + .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 402b0c96613..ef6453041cf 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -970,6 +970,7 @@ static void __init fixup_tosa(struct tag *tags, char **cmdline, } MACHINE_START(TOSA, "SHARP Tosa") + .restart_mode = 'g', .fixup = fixup_tosa, .map_io = pxa25x_map_io, .nr_irqs = TOSA_NR_IRQS, -- cgit v1.2.3 From ac15e00b1efe705b66a36d1a6a9db7f6ed524c43 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 31 Oct 2011 09:22:22 +0000 Subject: ARM: restart: move reboot failure handing into machine_restart() Move the failure to reboot into machine_restart() to always catch this condition, even if a platform decides to hook the restarting via arm_pm_restart(). Acked-by: Nicolas Pitre Acked-by: Will Deacon Acked-by: H Hartley Sweeten Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/kernel/process.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 75316f0dd02..3bda1c37977 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -114,18 +114,8 @@ void arm_machine_restart(char mode, const char *cmd) /* Push out any further dirty data, and ensure cache is empty */ flush_cache_all(); - /* - * Now call the architecture specific reboot code. - */ + /* Now call the architecture specific reboot code. */ arch_reset(mode, cmd); - - /* - * Whoops - the architecture was unable to reboot. - * Tell the user! - */ - mdelay(1000); - printk("Reboot failed -- System halted\n"); - while (1); } /* @@ -250,7 +240,15 @@ void machine_power_off(void) void machine_restart(char *cmd) { machine_shutdown(); + arm_pm_restart(reboot_mode, cmd); + + /* Give a grace period for failure to restart of 1s */ + mdelay(1000); + + /* Whoops - the platform was unable to reboot. Tell the user! */ + printk("Reboot failed -- System halted\n"); + while (1); } void __show_regs(struct pt_regs *regs) -- cgit v1.2.3 From 5aafec15bdc54cf0722696c95091d7bd674bfcad Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 1 Nov 2011 10:15:27 +0000 Subject: ARM: restart: remove argument to setup_mm_for_reboot() setup_mm_for_reboot() doesn't make use of its argument, so remove it. Acked-by: Nicolas Pitre Acked-by: Will Deacon Acked-by: H Hartley Sweeten Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/kernel/machine_kexec.c | 4 ++-- arch/arm/kernel/process.c | 4 ++-- arch/arm/mm/idmap.c | 2 +- arch/arm/mm/nommu.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index c1b4463dcc8..cc40b965d42 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -16,7 +16,7 @@ extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; -extern void setup_mm_for_reboot(char mode); +extern void setup_mm_for_reboot(void); extern unsigned long kexec_start_address; extern unsigned long kexec_indirection_page; @@ -114,7 +114,7 @@ void machine_kexec(struct kimage *image) kexec_reinit(); local_irq_disable(); local_fiq_disable(); - setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ + setup_mm_for_reboot(); flush_cache_all(); outer_flush_all(); outer_disable(); diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3bda1c37977..4181738452f 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -57,7 +57,7 @@ static const char *isa_modes[] = { "ARM" , "Thumb" , "Jazelle", "ThumbEE" }; -extern void setup_mm_for_reboot(char mode); +extern void setup_mm_for_reboot(void); static volatile int hlt_counter; @@ -103,7 +103,7 @@ void arm_machine_restart(char mode, const char *cmd) * we may need it to insert some 1:1 mappings so that * soft boot works. */ - setup_mm_for_reboot(mode); + setup_mm_for_reboot(); /* Clean and invalidate caches */ flush_cache_all(); diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 2be9139a4ef..296ad2eaddb 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -78,7 +78,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) * the user-mode pages. This will then ensure that we have predictable * results when turning the mmu off */ -void setup_mm_for_reboot(char mode) +void setup_mm_for_reboot(void) { /* * We need to access to user-mode page tables here. For kernel threads diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 941a98c9e8a..88417514b2c 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -43,7 +43,7 @@ void __init paging_init(struct machine_desc *mdesc) /* * We don't need to do anything here for nommu machines. */ -void setup_mm_for_reboot(char mode) +void setup_mm_for_reboot(void) { } -- cgit v1.2.3 From db0d4db22a78d31c59087f7057b8f1612fecc35d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 12 Nov 2011 16:09:49 +0000 Subject: ARM: gic: allow GIC to support non-banked setups The GIC support code is heavily using the fact that hardware implementations are exposing banked registers. Unfortunately, it looks like at least one GIC implementation (EXYNOS) offers both the distributor and the CPU interfaces at different addresses, depending on the CPU. This problem is solved by allowing the distributor and CPU interface addresses to be per-cpu variables for the platforms that require it. The EXYNOS code is updated not to mess with the GIC internals while handling interrupts, and struct gic_chip_data is back to being private. The DT binding for the gic is updated to allow an optional "cpu-offset" value, which is used to compute the various base addresses. Finally, a new config option (GIC_NON_BANKED) is used to control this feature, so the overhead is only present on kernels compiled with support for EXYNOS. Tested on Origen (EXYNOS4) and Panda (OMAP4). Cc: Kukjin Kim Cc: Will Deacon Cc: Thomas Abraham Acked-by: Rob Herring Signed-off-by: Marc Zyngier --- arch/arm/common/Kconfig | 3 + arch/arm/common/gic.c | 133 ++++++++++++++++++++++++++++++------ arch/arm/include/asm/hardware/gic.h | 24 +++---- arch/arm/mach-exynos/cpu.c | 16 +---- arch/arm/mach-exynos/platsmp.c | 28 +------- arch/arm/plat-s5p/Kconfig | 1 + 6 files changed, 128 insertions(+), 77 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 74df9ca2be3..a3beda1213d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -2,6 +2,9 @@ config ARM_GIC select IRQ_DOMAIN bool +config GIC_NON_BANKED + bool + config ARM_VIC bool diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 0e6ae470c94..43cb6f1a7cf 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -43,6 +43,31 @@ #include #include +union gic_base { + void __iomem *common_base; + void __percpu __iomem **percpu_base; +}; + +struct gic_chip_data { + unsigned int irq_offset; + union gic_base dist_base; + union gic_base cpu_base; +#ifdef CONFIG_CPU_PM + u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; + u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; + u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; + u32 __percpu *saved_ppi_enable; + u32 __percpu *saved_ppi_conf; +#endif +#ifdef CONFIG_IRQ_DOMAIN + struct irq_domain domain; +#endif + unsigned int gic_irqs; +#ifdef CONFIG_GIC_NON_BANKED + void __iomem *(*get_base)(union gic_base *); +#endif +}; + static DEFINE_RAW_SPINLOCK(irq_controller_lock); /* Address of GIC 0 CPU interface */ @@ -67,16 +92,48 @@ struct irq_chip gic_arch_extn = { static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; +#ifdef CONFIG_GIC_NON_BANKED +static void __iomem *gic_get_percpu_base(union gic_base *base) +{ + return *__this_cpu_ptr(base->percpu_base); +} + +static void __iomem *gic_get_common_base(union gic_base *base) +{ + return base->common_base; +} + +static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) +{ + return data->get_base(&data->dist_base); +} + +static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) +{ + return data->get_base(&data->cpu_base); +} + +static inline void gic_set_base_accessor(struct gic_chip_data *data, + void __iomem *(*f)(union gic_base *)) +{ + data->get_base = f; +} +#else +#define gic_data_dist_base(d) ((d)->dist_base.common_base) +#define gic_data_cpu_base(d) ((d)->cpu_base.common_base) +#define gic_set_base_accessor(d,f) +#endif + static inline void __iomem *gic_dist_base(struct irq_data *d) { struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - return gic_data->dist_base; + return gic_data_dist_base(gic_data); } static inline void __iomem *gic_cpu_base(struct irq_data *d) { struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - return gic_data->cpu_base; + return gic_data_cpu_base(gic_data); } static inline unsigned int gic_irq(struct irq_data *d) @@ -225,7 +282,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) chained_irq_enter(chip, desc); raw_spin_lock(&irq_controller_lock); - status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); + status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); raw_spin_unlock(&irq_controller_lock); gic_irq = (status & 0x3ff); @@ -270,7 +327,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) u32 cpumask; unsigned int gic_irqs = gic->gic_irqs; struct irq_domain *domain = &gic->domain; - void __iomem *base = gic->dist_base; + void __iomem *base = gic_data_dist_base(gic); u32 cpu = 0; #ifdef CONFIG_SMP @@ -330,8 +387,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic) static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) { - void __iomem *dist_base = gic->dist_base; - void __iomem *base = gic->cpu_base; + void __iomem *dist_base = gic_data_dist_base(gic); + void __iomem *base = gic_data_cpu_base(gic); int i; /* @@ -368,7 +425,7 @@ static void gic_dist_save(unsigned int gic_nr) BUG(); gic_irqs = gic_data[gic_nr].gic_irqs; - dist_base = gic_data[gic_nr].dist_base; + dist_base = gic_data_dist_base(&gic_data[gic_nr]); if (!dist_base) return; @@ -403,7 +460,7 @@ static void gic_dist_restore(unsigned int gic_nr) BUG(); gic_irqs = gic_data[gic_nr].gic_irqs; - dist_base = gic_data[gic_nr].dist_base; + dist_base = gic_data_dist_base(&gic_data[gic_nr]); if (!dist_base) return; @@ -439,8 +496,8 @@ static void gic_cpu_save(unsigned int gic_nr) if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data[gic_nr].dist_base; - cpu_base = gic_data[gic_nr].cpu_base; + dist_base = gic_data_dist_base(&gic_data[gic_nr]); + cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); if (!dist_base || !cpu_base) return; @@ -465,8 +522,8 @@ static void gic_cpu_restore(unsigned int gic_nr) if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data[gic_nr].dist_base; - cpu_base = gic_data[gic_nr].cpu_base; + dist_base = gic_data_dist_base(&gic_data[gic_nr]); + cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); if (!dist_base || !cpu_base) return; @@ -491,6 +548,11 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) int i; for (i = 0; i < MAX_GIC_NR; i++) { +#ifdef CONFIG_GIC_NON_BANKED + /* Skip over unused GICs */ + if (!gic_data[i].get_base) + continue; +#endif switch (cmd) { case CPU_PM_ENTER: gic_cpu_save(i); @@ -563,8 +625,9 @@ const struct irq_domain_ops gic_irq_domain_ops = { #endif }; -void __init gic_init(unsigned int gic_nr, int irq_start, - void __iomem *dist_base, void __iomem *cpu_base) +void __init gic_init_bases(unsigned int gic_nr, int irq_start, + void __iomem *dist_base, void __iomem *cpu_base, + u32 percpu_offset) { struct gic_chip_data *gic; struct irq_domain *domain; @@ -574,8 +637,36 @@ void __init gic_init(unsigned int gic_nr, int irq_start, gic = &gic_data[gic_nr]; domain = &gic->domain; - gic->dist_base = dist_base; - gic->cpu_base = cpu_base; +#ifdef CONFIG_GIC_NON_BANKED + if (percpu_offset) { /* Frankein-GIC without banked registers... */ + unsigned int cpu; + + gic->dist_base.percpu_base = alloc_percpu(void __iomem *); + gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); + if (WARN_ON(!gic->dist_base.percpu_base || + !gic->cpu_base.percpu_base)) { + free_percpu(gic->dist_base.percpu_base); + free_percpu(gic->cpu_base.percpu_base); + return; + } + + for_each_possible_cpu(cpu) { + unsigned long offset = percpu_offset * cpu_logical_map(cpu); + *per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset; + *per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset; + } + + gic_set_base_accessor(gic, gic_get_percpu_base); + } else +#endif + { /* Normal, sane GIC... */ + WARN(percpu_offset, + "GIC_NON_BANKED not enabled, ignoring %08x offset!", + percpu_offset); + gic->dist_base.common_base = dist_base; + gic->cpu_base.common_base = cpu_base; + gic_set_base_accessor(gic, gic_get_common_base); + } /* * For primary GICs, skip over SGIs. @@ -593,7 +684,7 @@ void __init gic_init(unsigned int gic_nr, int irq_start, * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources. */ - gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f; + gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f; gic_irqs = (gic_irqs + 1) * 32; if (gic_irqs > 1020) gic_irqs = 1020; @@ -641,7 +732,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) dsb(); /* this always happens on GIC0 */ - writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); + writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); } #endif @@ -652,6 +743,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *cpu_base; void __iomem *dist_base; + u32 percpu_offset; int irq; struct irq_domain *domain = &gic_data[gic_cnt].domain; @@ -664,9 +756,12 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) cpu_base = of_iomap(node, 1); WARN(!cpu_base, "unable to map gic cpu registers\n"); + if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) + percpu_offset = 0; + domain->of_node = of_node_get(node); - gic_init(gic_cnt, -1, dist_base, cpu_base); + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset); if (parent) { irq = irq_of_parse_and_map(node, 0); diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 3e91f22046f..2721d90625e 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -39,27 +39,19 @@ struct device_node; extern void __iomem *gic_cpu_base_addr; extern struct irq_chip gic_arch_extn; -void gic_init(unsigned int, int, void __iomem *, void __iomem *); +void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, + u32 offset); int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); -struct gic_chip_data { - void __iomem *dist_base; - void __iomem *cpu_base; -#ifdef CONFIG_CPU_PM - u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; - u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; - u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; - u32 __percpu *saved_ppi_enable; - u32 __percpu *saved_ppi_conf; -#endif -#ifdef CONFIG_IRQ_DOMAIN - struct irq_domain domain; -#endif - unsigned int gic_irqs; -}; +static inline void gic_init(unsigned int nr, int start, + void __iomem *dist , void __iomem *cpu) +{ + gic_init_bases(nr, start, dist, cpu, 0); +} + #endif #endif diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c index 90ec247f3b3..e92e464bdbb 100644 --- a/arch/arm/mach-exynos/cpu.c +++ b/arch/arm/mach-exynos/cpu.c @@ -207,27 +207,13 @@ void __init exynos4_init_clocks(int xtal) exynos4_setup_clocks(); } -static void exynos4_gic_irq_fix_base(struct irq_data *d) -{ - struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - - gic_data->cpu_base = S5P_VA_GIC_CPU + - (gic_bank_offset * smp_processor_id()); - - gic_data->dist_base = S5P_VA_GIC_DIST + - (gic_bank_offset * smp_processor_id()); -} - void __init exynos4_init_irq(void) { int irq; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; - gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); - gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; - gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; - gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; + gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); for (irq = 0; irq < MAX_COMBINER_NR; irq++) { diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 69ffb2fb387..60bc45e3e70 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -32,7 +32,6 @@ #include -extern unsigned int gic_bank_offset; extern void exynos4_secondary_startup(void); #define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ @@ -65,31 +64,6 @@ static void __iomem *scu_base_addr(void) static DEFINE_SPINLOCK(boot_lock); -static void __cpuinit exynos4_gic_secondary_init(void) -{ - void __iomem *dist_base = S5P_VA_GIC_DIST + - (gic_bank_offset * smp_processor_id()); - void __iomem *cpu_base = S5P_VA_GIC_CPU + - (gic_bank_offset * smp_processor_id()); - int i; - - /* - * Deal with the banked PPI and SGI interrupts - disable all - * PPI interrupts, ensure all SGI interrupts are enabled. - */ - __raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); - __raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); - - /* - * Set priority on PPI and SGI interrupts - */ - for (i = 0; i < 32; i += 4) - __raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); - - __raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK); - __raw_writel(1, cpu_base + GIC_CPU_CTRL); -} - void __cpuinit platform_secondary_init(unsigned int cpu) { /* @@ -97,7 +71,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * core (e.g. timer irq), then they will not have been enabled * for us: do so */ - exynos4_gic_secondary_init(); + gic_secondary_init(0); /* * let the primary processor know we're out of the diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 9b9968fa869..8167ce66188 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -11,6 +11,7 @@ config PLAT_S5P default y select ARM_VIC if !ARCH_EXYNOS4 select ARM_GIC if ARCH_EXYNOS4 + select GIC_NON_BANKED if ARCH_EXYNOS4 select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK -- cgit v1.2.3 From abeb24ae4d3e543ecf0104cff08a3af4e7a42479 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 09:23:26 +0100 Subject: ARM: Make global handler and CONFIG_MULTI_IRQ_HANDLER mutually exclusive Even when CONFIG_MULTI_IRQ_HANDLER is selected, the core code requires the arch_irq_handler_default macro to be defined as a fallback. It turns out nobody is using that particular feature as both PXA and shmobile have all their machine descriptors populated with the interrupt handler, leaving unused code (or empty macros) in their entry-macro.S file just to be able to compile entry-armv.S. Make CONFIG_MULTI_IRQ_HANDLER exclusive wrt arch_irq_handler_default, which allows to remove one test from the hot path. Also cleanup both PXA and shmobile entry-macro.S. Cc: Paul Mundt Acked-by: Nicolas Pitre Acked-by: Eric Miao Tested-by: Jamie Iles Signed-off-by: Marc Zyngier --- arch/arm/kernel/entry-armv.S | 7 ++--- arch/arm/mach-pxa/include/mach/entry-macro.S | 36 ----------------------- arch/arm/mach-shmobile/include/mach/entry-macro.S | 9 ------ 3 files changed, 3 insertions(+), 49 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 9ad50c4208a..bd49a6a2a17 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -36,12 +36,11 @@ #ifdef CONFIG_MULTI_IRQ_HANDLER ldr r1, =handle_arch_irq mov r0, sp - ldr r1, [r1] adr lr, BSYM(9997f) - teq r1, #0 - movne pc, r1 -#endif + ldr pc, [r1] +#else arch_irq_handler_default +#endif 9997: .endm diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S index a73bc86a3c2..260c0c17692 100644 --- a/arch/arm/mach-pxa/include/mach/entry-macro.S +++ b/arch/arm/mach-pxa/include/mach/entry-macro.S @@ -7,45 +7,9 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#include -#include .macro disable_fiq .endm - .macro get_irqnr_preamble, base, tmp - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mrc p15, 0, \tmp, c0, c0, 0 @ CPUID - mov \tmp, \tmp, lsr #13 - and \tmp, \tmp, #0x7 @ Core G - cmp \tmp, #1 - bhi 1002f - - @ Core Generation 1 (PXA25x) - mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000 - add \base, \base, #0x00d00000 - ldr \irqstat, [\base, #0] @ ICIP - ldr \irqnr, [\base, #4] @ ICMR - - ands \irqnr, \irqstat, \irqnr - beq 1001f - rsb \irqstat, \irqnr, #0 - and \irqstat, \irqstat, \irqnr - clz \irqnr, \irqstat - rsb \irqnr, \irqnr, #(31 + PXA_IRQ(0)) - b 1001f -1002: - @ Core Generation 2 (PXA27x) or Core Generation 3 (PXA3xx) - mrc p6, 0, \irqstat, c5, c0, 0 @ ICHP - tst \irqstat, #0x80000000 - beq 1001f - bic \irqstat, \irqstat, #0x80000000 - mov \irqnr, \irqstat, lsr #16 - add \irqnr, \irqnr, #(PXA_IRQ(0)) -1001: - .endm diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S index 8d4a416d428..2a57b2964ee 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S @@ -18,14 +18,5 @@ .macro disable_fiq .endm - .macro get_irqnr_preamble, base, tmp - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - .endm - - .macro test_for_ipi, irqnr, irqstat, base, tmp - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm -- cgit v1.2.3 From baeeb8229cace91c10c856d91e5ca861d3c44968 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 2 Nov 2011 15:28:49 +0000 Subject: ARM: mxc: rename gic_handle_irq to avoid name clash Before introducing a global gic_handle_irq(), rename MXC's version to mxc_gic_handle_irq(). This function will be removed altogether in a later patch. Cc: Sascha Hauer Acked-by: Shawn Guo Signed-off-by: Marc Zyngier --- arch/arm/plat-mxc/gic.c | 2 +- arch/arm/plat-mxc/include/mach/common.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c index 12f8f810901..ea51ea4aba6 100644 --- a/arch/arm/plat-mxc/gic.c +++ b/arch/arm/plat-mxc/gic.c @@ -18,7 +18,7 @@ #include #endif -asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) +asmlinkage void __exception_irq_entry mxc_gic_handle_irq(struct pt_regs *regs) { u32 irqstat, irqnr; diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 83b745a5e1b..d7c290d32e3 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -90,7 +90,7 @@ extern void imx_print_silicon_rev(const char *cpu, int srev); void avic_handle_irq(struct pt_regs *); void tzic_handle_irq(struct pt_regs *); -void gic_handle_irq(struct pt_regs *); +void mxc_gic_handle_irq(struct pt_regs *); #define imx1_handle_irq avic_handle_irq #define imx21_handle_irq avic_handle_irq @@ -101,7 +101,7 @@ void gic_handle_irq(struct pt_regs *); #define imx50_handle_irq tzic_handle_irq #define imx51_handle_irq tzic_handle_irq #define imx53_handle_irq tzic_handle_irq -#define imx6q_handle_irq gic_handle_irq +#define imx6q_handle_irq mxc_gic_handle_irq extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); -- cgit v1.2.3 From 562e0027d21bf64838178e2f5157df3d5833972e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 09:56:17 +0100 Subject: ARM: GIC: Add global gic_handle_irq() function Provide the GIC code with a low level handler that can be used by platforms using CONFIG_MULTI_IRQ_HANDLER. Signed-off-by: Marc Zyngier --- arch/arm/common/gic.c | 27 +++++++++++++++++++++++++++ arch/arm/include/asm/hardware/gic.h | 1 + 2 files changed, 28 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 43cb6f1a7cf..3c78b7c6069 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -272,6 +273,32 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) #define gic_set_wake NULL #endif +asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) +{ + u32 irqstat, irqnr; + struct gic_chip_data *gic = &gic_data[0]; + void __iomem *cpu_base = gic_data_cpu_base(gic); + + do { + irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); + irqnr = irqstat & ~0x1c00; + + if (likely(irqnr > 15 && irqnr < 1021)) { + irqnr = irq_domain_to_irq(&gic->domain, irqnr); + handle_IRQ(irqnr, regs); + continue; + } + if (irqnr < 16) { + writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); +#ifdef CONFIG_SMP + handle_IPI(irqnr, regs); +#endif + continue; + } + break; + } while (1); +} + static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct gic_chip_data *chip_data = irq_get_handler_data(irq); diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 2721d90625e..ecf7c02fa16 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -43,6 +43,7 @@ void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset); int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); +void gic_handle_irq(struct pt_regs *regs); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); -- cgit v1.2.3 From fea9fe8329c74159fb2030f1aacf29fdab9fc6d6 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 10:23:45 +0100 Subject: ARM: imx: convert smp platforms to global gic_handle_irq() Convert the SMP imx platforms to use the global gic_handle_irq() function instead a private function. Cc: Sascha Hauer Acked-by: Shawn Guo Signed-off-by: Marc Zyngier --- arch/arm/plat-mxc/Makefile | 1 - arch/arm/plat-mxc/gic.c | 41 ---------------------------- arch/arm/plat-mxc/include/mach/common.h | 3 +- arch/arm/plat-mxc/include/mach/entry-macro.S | 11 -------- 4 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 arch/arm/plat-mxc/gic.c (limited to 'arch/arm') diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index b9f0f5f499a..076db84f3e3 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -5,7 +5,6 @@ # Common support obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o -obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_MXC_AVIC) += avic.o diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c deleted file mode 100644 index ea51ea4aba6..00000000000 --- a/arch/arm/plat-mxc/gic.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#ifdef CONFIG_SMP -#include -#endif - -asmlinkage void __exception_irq_entry mxc_gic_handle_irq(struct pt_regs *regs) -{ - u32 irqstat, irqnr; - - do { - irqstat = readl_relaxed(gic_cpu_base_addr + GIC_CPU_INTACK); - irqnr = irqstat & 0x3ff; - if (irqnr == 1023) - break; - - if (irqnr > 15 && irqnr < 1021) - handle_IRQ(irqnr, regs); -#ifdef CONFIG_SMP - else { - writel_relaxed(irqstat, gic_cpu_base_addr + - GIC_CPU_EOI); - handle_IPI(irqnr, regs); - } -#endif - } while (1); -} diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index d7c290d32e3..14b4703e6e4 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -90,7 +90,6 @@ extern void imx_print_silicon_rev(const char *cpu, int srev); void avic_handle_irq(struct pt_regs *); void tzic_handle_irq(struct pt_regs *); -void mxc_gic_handle_irq(struct pt_regs *); #define imx1_handle_irq avic_handle_irq #define imx21_handle_irq avic_handle_irq @@ -101,7 +100,7 @@ void mxc_gic_handle_irq(struct pt_regs *); #define imx50_handle_irq tzic_handle_irq #define imx51_handle_irq tzic_handle_irq #define imx53_handle_irq tzic_handle_irq -#define imx6q_handle_irq mxc_gic_handle_irq +#define imx6q_handle_irq gic_handle_irq extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S index ca5cf26a04b..def5d30cb67 100644 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S @@ -9,19 +9,8 @@ * published by the Free Software Foundation. */ -/* Unused, we use CONFIG_MULTI_IRQ_HANDLER */ - .macro disable_fiq .endm - .macro get_irqnr_preamble, base, tmp - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - .endm - - .macro test_for_ipi, irqnr, irqstat, base, tmp - .endm -- cgit v1.2.3 From 7e01799c669c60460dce43556065ca3b66760dcf Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 10:23:45 +0100 Subject: ARM: highbank: convert to CONFIG_MULTI_IRQ_HANDLER Convert the highbank platform to be using the gic_handle_irq function as its primary interrupt handler. Cc: Rob Herring Signed-off-by: Marc Zyngier --- arch/arm/Kconfig | 1 + arch/arm/mach-highbank/highbank.c | 1 + arch/arm/mach-highbank/include/mach/entry-macro.S | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 44789eff983..5c014c6f056 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -345,6 +345,7 @@ config ARCH_HIGHBANK select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU select USE_OF + select MULTI_IRQ_HANDLER help Support for the Calxeda Highbank SoC based boards. diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index b82dcf08e74..89bdf0039f7 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -140,6 +140,7 @@ DT_MACHINE_START(HIGHBANK, "Highbank") .map_io = highbank_map_io, .init_irq = highbank_init_irq, .timer = &highbank_timer, + .handle_irq = gic_handle_irq, .init_machine = highbank_init, .dt_compat = highbank_match, MACHINE_END diff --git a/arch/arm/mach-highbank/include/mach/entry-macro.S b/arch/arm/mach-highbank/include/mach/entry-macro.S index 73c11297509..a14f9e62ca9 100644 --- a/arch/arm/mach-highbank/include/mach/entry-macro.S +++ b/arch/arm/mach-highbank/include/mach/entry-macro.S @@ -1,5 +1,3 @@ -#include - .macro disable_fiq .endm -- cgit v1.2.3 From 1b99d9ccb52d64bfdab0d58915909b10cbbdf9e1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 10:23:45 +0100 Subject: ARM: RealView: convert to CONFIG_MULTI_IRQ_HANDLER Convert the RealView platforms to be using the gic_handle_irq function as their primary interrupt handler. Signed-off-by: Marc Zyngier --- arch/arm/Kconfig | 1 + arch/arm/mach-realview/include/mach/entry-macro.S | 2 -- arch/arm/mach-realview/realview_eb.c | 1 + arch/arm/mach-realview/realview_pb1176.c | 1 + arch/arm/mach-realview/realview_pb11mp.c | 1 + arch/arm/mach-realview/realview_pba8.c | 1 + arch/arm/mach-realview/realview_pbx.c | 1 + 7 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c014c6f056..5f3b7fedc66 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -278,6 +278,7 @@ config ARCH_REALVIEW select ARM_TIMER_SP804 select GPIO_PL061 if GPIOLIB select NEED_MACH_MEMORY_H + select MULTI_IRQ_HANDLER help This enables support for ARM Ltd RealView boards. diff --git a/arch/arm/mach-realview/include/mach/entry-macro.S b/arch/arm/mach-realview/include/mach/entry-macro.S index 4071164aeba..e8a5179c265 100644 --- a/arch/arm/mach-realview/include/mach/entry-macro.S +++ b/arch/arm/mach-realview/include/mach/entry-macro.S @@ -7,8 +7,6 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#include -#include .macro disable_fiq .endm diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 026c66ad7ec..10ef2e74cce 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -469,6 +469,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB") .init_early = realview_init_early, .init_irq = gic_init_irq, .timer = &realview_eb_timer, + .handle_irq = gic_handle_irq, .init_machine = realview_eb_init, #ifdef CONFIG_ZONE_DMA .dma_zone_size = SZ_256M, diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index c057540ec77..bd8fec8b20d 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -392,6 +392,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") .init_early = realview_init_early, .init_irq = gic_init_irq, .timer = &realview_pb1176_timer, + .handle_irq = gic_handle_irq, .init_machine = realview_pb1176_init, #ifdef CONFIG_ZONE_DMA .dma_zone_size = SZ_256M, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 671ad6d6ff0..fa73ba81a44 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -366,6 +366,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") .init_early = realview_init_early, .init_irq = gic_init_irq, .timer = &realview_pb11mp_timer, + .handle_irq = gic_handle_irq, .init_machine = realview_pb11mp_init, #ifdef CONFIG_ZONE_DMA .dma_zone_size = SZ_256M, diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index cbf22df4ad5..6e5f2b9ddb7 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -316,6 +316,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") .init_early = realview_init_early, .init_irq = gic_init_irq, .timer = &realview_pba8_timer, + .handle_irq = gic_handle_irq, .init_machine = realview_pba8_init, #ifdef CONFIG_ZONE_DMA .dma_zone_size = SZ_256M, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 63c4114afae..291bf1a8f2f 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -399,6 +399,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") .init_early = realview_init_early, .init_irq = gic_init_irq, .timer = &realview_pbx_timer, + .handle_irq = gic_handle_irq, .init_machine = realview_pbx_init, #ifdef CONFIG_ZONE_DMA .dma_zone_size = SZ_256M, -- cgit v1.2.3 From abd3ca51fba8bc200ae78e99bd1ac19c4e3b6781 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 10:23:45 +0100 Subject: ARM: VExpress: convert to CONFIG_MULTI_IRQ_HANDLER Convert the VExpress platform to be using the gic_handle_irq function as its primary interrupt handler. Signed-off-by: Marc Zyngier --- arch/arm/Kconfig | 1 + arch/arm/mach-vexpress/include/mach/entry-macro.S | 2 -- arch/arm/mach-vexpress/v2m.c | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5f3b7fedc66..8f39263c076 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -311,6 +311,7 @@ config ARCH_VEXPRESS select ICST select PLAT_VERSATILE select PLAT_VERSATILE_CLCD + select MULTI_IRQ_HANDLER help This enables support for the ARM Ltd Versatile Express boards. diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S index 73c11297509..a14f9e62ca9 100644 --- a/arch/arm/mach-vexpress/include/mach/entry-macro.S +++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S @@ -1,5 +1,3 @@ -#include - .macro disable_fiq .endm diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 1fafc324460..7aa07a8ce23 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -448,5 +449,6 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") .init_early = v2m_init_early, .init_irq = v2m_init_irq, .timer = &v2m_timer, + .handle_irq = gic_handle_irq, .init_machine = v2m_init, MACHINE_END -- cgit v1.2.3 From 041f777c93bab29565d999a292b9b9b533fe6f5e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 6 Sep 2011 10:23:45 +0100 Subject: ARM: msm: convert SMP platforms to CONFIG_MULTI_IRQ_HANDLER Convert the SMP msm platforms to be using the gic_handle_irq function as their primary interrupt handler. Tested-by: David Brown Acked-by: David Brown Signed-off-by: Marc Zyngier --- arch/arm/mach-msm/Kconfig | 2 ++ arch/arm/mach-msm/board-msm8960.c | 2 ++ arch/arm/mach-msm/board-msm8x60.c | 4 +++ arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 17 ----------- arch/arm/mach-msm/include/mach/entry-macro-vic.S | 37 ----------------------- arch/arm/mach-msm/include/mach/entry-macro.S | 27 ++++++++++++++--- 6 files changed, 31 insertions(+), 58 deletions(-) delete mode 100644 arch/arm/mach-msm/include/mach/entry-macro-qgic.S delete mode 100644 arch/arm/mach-msm/include/mach/entry-macro-vic.S (limited to 'arch/arm') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index ebde97f5d5f..ba36b74881c 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -50,6 +50,7 @@ config ARCH_MSM8X60 select GPIO_MSM_V2 select MSM_GPIOMUX select MSM_SCM if SMP + select MULTI_IRQ_HANDLER config ARCH_MSM8960 bool "MSM8960" @@ -60,6 +61,7 @@ config ARCH_MSM8960 select MSM_V2_TLMM select MSM_GPIOMUX select MSM_SCM if SMP + select MULTI_IRQ_HANDLER endchoice diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c index 6dc1cbd2a59..ed359812853 100644 --- a/arch/arm/mach-msm/board-msm8960.c +++ b/arch/arm/mach-msm/board-msm8960.c @@ -99,6 +99,7 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR") .map_io = msm8960_map_io, .init_irq = msm8960_init_irq, .timer = &msm_timer, + .handle_irq = gic_handle_irq, .init_machine = msm8960_sim_init, MACHINE_END @@ -108,6 +109,7 @@ MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3") .map_io = msm8960_map_io, .init_irq = msm8960_init_irq, .timer = &msm_timer, + .handle_irq = gic_handle_irq, .init_machine = msm8960_rumi3_init, MACHINE_END diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 44bf7168837..0a113424632 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -108,6 +108,7 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3") .reserve = msm8x60_reserve, .map_io = msm8x60_map_io, .init_irq = msm8x60_init_irq, + .handle_irq = gic_handle_irq, .init_machine = msm8x60_init, .timer = &msm_timer, MACHINE_END @@ -117,6 +118,7 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF") .reserve = msm8x60_reserve, .map_io = msm8x60_map_io, .init_irq = msm8x60_init_irq, + .handle_irq = gic_handle_irq, .init_machine = msm8x60_init, .timer = &msm_timer, MACHINE_END @@ -126,6 +128,7 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR") .reserve = msm8x60_reserve, .map_io = msm8x60_map_io, .init_irq = msm8x60_init_irq, + .handle_irq = gic_handle_irq, .init_machine = msm8x60_init, .timer = &msm_timer, MACHINE_END @@ -135,6 +138,7 @@ MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA") .reserve = msm8x60_reserve, .map_io = msm8x60_map_io, .init_irq = msm8x60_init_irq, + .handle_irq = gic_handle_irq, .init_machine = msm8x60_init, .timer = &msm_timer, MACHINE_END diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S deleted file mode 100644 index 717076f3ca7..00000000000 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Low-level IRQ helper macros - * - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-msm/include/mach/entry-macro-vic.S b/arch/arm/mach-msm/include/mach/entry-macro-vic.S deleted file mode 100644 index 70563ed11b3..00000000000 --- a/arch/arm/mach-msm/include/mach/entry-macro-vic.S +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include - - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - @ enable imprecise aborts - cpsie a - mov \base, #MSM_VIC_BASE - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - @ 0xD0 has irq# or old irq# if the irq has been handled - @ 0xD4 has irq# or -1 if none pending *but* if you just - @ read 0xD4 you never get the first irq for some reason - ldr \irqnr, [\base, #0xD0] - ldr \irqnr, [\base, #0xD4] - cmp \irqnr, #0xffffffff - .endm diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S index b16f082eeb6..41f7003ef34 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro.S +++ b/arch/arm/mach-msm/include/mach/entry-macro.S @@ -16,8 +16,27 @@ * */ -#if defined(CONFIG_ARM_GIC) -#include -#else -#include + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + +#if !defined(CONFIG_ARM_GIC) +#include + + .macro get_irqnr_preamble, base, tmp + @ enable imprecise aborts + cpsie a + mov \base, #MSM_VIC_BASE + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + @ 0xD0 has irq# or old irq# if the irq has been handled + @ 0xD4 has irq# or -1 if none pending *but* if you just + @ read 0xD4 you never get the first irq for some reason + ldr \irqnr, [\base, #0xD0] + ldr \irqnr, [\base, #0xD4] + cmp \irqnr, #0xffffffff + .endm #endif -- cgit v1.2.3 From 4e44d2cb95bd93abe16a131dbcd4c052ae36665f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 30 May 2011 11:04:53 +0100 Subject: ARM: exynos4: convert to CONFIG_MULTI_IRQ_HANDLER Convert the Exynos4 platforms to be using the gic_handle_irq function as their primary interrupt handler. Cc: Ben Dooks Cc: Kukjin Kim Signed-off-by: Marc Zyngier --- arch/arm/Kconfig | 1 + arch/arm/mach-exynos/cpu.c | 4 +- arch/arm/mach-exynos/include/mach/entry-macro.S | 75 ------------------------- arch/arm/mach-exynos/mach-armlex4210.c | 2 + arch/arm/mach-exynos/mach-nuri.c | 2 + arch/arm/mach-exynos/mach-origen.c | 2 + arch/arm/mach-exynos/mach-smdk4x12.c | 3 + arch/arm/mach-exynos/mach-smdkv310.c | 3 + arch/arm/mach-exynos/mach-universal_c210.c | 4 +- 9 files changed, 18 insertions(+), 78 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8f39263c076..d897255bcdf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -854,6 +854,7 @@ config ARCH_EXYNOS select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select NEED_MACH_MEMORY_H + select MULTI_IRQ_HANDLER help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c index e92e464bdbb..6e34485caa3 100644 --- a/arch/arm/mach-exynos/cpu.c +++ b/arch/arm/mach-exynos/cpu.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -33,8 +34,6 @@ #include #include -unsigned int gic_bank_offset __read_mostly; - extern int combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start); extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); @@ -210,6 +209,7 @@ void __init exynos4_init_clocks(int xtal) void __init exynos4_init_irq(void) { int irq; + unsigned int bank_offset; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; diff --git a/arch/arm/mach-exynos/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S index f5e9fd8e37b..3ba4f547534 100644 --- a/arch/arm/mach-exynos/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos/include/mach/entry-macro.S @@ -9,83 +9,8 @@ * warranty of any kind, whether express or implied. */ -#include -#include -#include - .macro disable_fiq .endm - .macro get_irqnr_preamble, base, tmp - mov \tmp, #0 - - mrc p15, 0, \base, c0, c0, 5 - and \base, \base, #3 - cmp \base, #0 - beq 1f - - ldr \tmp, =gic_bank_offset - ldr \tmp, [\tmp] - cmp \base, #1 - beq 1f - - cmp \base, #2 - addeq \tmp, \tmp, \tmp - addne \tmp, \tmp, \tmp, LSL #1 - -1: ldr \base, =gic_cpu_base_addr - ldr \base, [\base] - add \base, \base, \tmp - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm - - /* - * The interrupt numbering scheme is defined in the - * interrupt controller spec. To wit: - * - * Interrupts 0-15 are IPI - * 16-28 are reserved - * 29-31 are local. We allow 30 to be used for the watchdog. - * 32-1020 are global - * 1021-1022 are reserved - * 1023 is "spurious" (no interrupt) - * - * For now, we ignore all local interrupts so only return an interrupt if it's - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. - * - * A simple read from the controller will tell us the number of the highest - * priority enabled interrupt. We then just need to check whether it is in the - * valid range for an IRQ (30-1020 inclusive). - */ - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - - ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ - - ldr \tmp, =1021 - - bic \irqnr, \irqstat, #0x1c00 - - cmp \irqnr, #15 - cmpcc \irqnr, \irqnr - cmpne \irqnr, \tmp - cmpcs \irqnr, \irqnr - addne \irqnr, \irqnr, #32 - - .endm - - /* We assume that irqstat (the raw value of the IRQ acknowledge - * register) is preserved from the macro above. - * If there is an IPI, we immediately signal end of interrupt on the - * controller, since this requires the original irqstat value which - * we won't easily be able to recreate later. - */ - - .macro test_for_ipi, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - cmp \irqnr, #16 - strcc \irqstat, [\base, #GIC_CPU_EOI] - cmpcs \irqnr, \irqnr - .endm diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c index f0ca6c157d2..49da3089249 100644 --- a/arch/arm/mach-exynos/mach-armlex4210.c +++ b/arch/arm/mach-exynos/mach-armlex4210.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -210,6 +211,7 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = armlex4210_map_io, + .handle_irq = gic_handle_irq, .init_machine = armlex4210_machine_init, .timer = &exynos4_timer, MACHINE_END diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index 236bbe18716..5acec11821a 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -1333,6 +1334,7 @@ MACHINE_START(NURI, "NURI") .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = nuri_map_io, + .handle_irq = gic_handle_irq, .init_machine = nuri_machine_init, .timer = &exynos4_timer, .reserve = &nuri_reserve, diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index f80b563f2be..5561b06c38e 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -22,6 +22,7 @@ #include #include +#include #include #include