Skip to content

Commit 4c2880b

Browse files
jonhunterKAGA-KOKO
authored andcommitted
irqchip/gic: Ensure gic_cpu_if_up/down() programs correct GIC instance
Commit 3228950 ("irqchip: gic: Preserve gic V2 bypass bits in cpu ctrl register") added a new function, gic_cpu_if_up(), to program the GIC CPU_CTRL register. This function assumes that there is only one GIC instance present and hence always uses the chip data for the primary GIC controller. Although it is not common for there to be a secondary, some devices do support a secondary. Therefore, fix this by passing gic_cpu_if_up() a pointer to the appropriate chip data structure. Similarly, the function gic_cpu_if_down() only assumes that there is a single GIC instance present. Update this function so that an instance number is passed for the appropriate GIC and return an error code on failure. The vexpress TC2 (which has a single GIC) is currently the only user of this function and so update it accordingly. Note that because the TC2 only has a single GIC, the call to gic_cpu_if_down() should always be successful. Signed-off-by: Jon Hunter <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Cc: <[email protected]> Cc: Russell King <[email protected]> Cc: Nicolas Pitre <[email protected]> Cc: Jason Cooper <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent 567e5a0 commit 4c2880b

File tree

3 files changed

+14
-8
lines changed

3 files changed

+14
-8
lines changed

arch/arm/mach-vexpress/tc2_pm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
8080
* to the CPU by disabling the GIC CPU IF to prevent wfi
8181
* from completing execution behind power controller back
8282
*/
83-
gic_cpu_if_down();
83+
gic_cpu_if_down(0);
8484
}
8585

8686
static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster)

drivers/irqchip/irq-gic.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,9 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
356356
return mask;
357357
}
358358

359-
static void gic_cpu_if_up(void)
359+
static void gic_cpu_if_up(struct gic_chip_data *gic)
360360
{
361-
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
361+
void __iomem *cpu_base = gic_data_cpu_base(gic);
362362
u32 bypass = 0;
363363

364364
/*
@@ -426,17 +426,23 @@ static void gic_cpu_init(struct gic_chip_data *gic)
426426
gic_cpu_config(dist_base, NULL);
427427

428428
writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
429-
gic_cpu_if_up();
429+
gic_cpu_if_up(gic);
430430
}
431431

432-
void gic_cpu_if_down(void)
432+
int gic_cpu_if_down(unsigned int gic_nr)
433433
{
434-
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
434+
void __iomem *cpu_base;
435435
u32 val = 0;
436436

437+
if (gic_nr >= MAX_GIC_NR)
438+
return -EINVAL;
439+
440+
cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
437441
val = readl(cpu_base + GIC_CPU_CTRL);
438442
val &= ~GICC_ENABLE;
439443
writel_relaxed(val, cpu_base + GIC_CPU_CTRL);
444+
445+
return 0;
440446
}
441447

442448
#ifdef CONFIG_CPU_PM
@@ -572,7 +578,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
572578
dist_base + GIC_DIST_PRI + i * 4);
573579

574580
writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
575-
gic_cpu_if_up();
581+
gic_cpu_if_up(&gic_data[gic_nr]);
576582
}
577583

578584
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)

include/linux/irqchip/arm-gic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct device_node;
9898
void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
9999
u32 offset, struct device_node *);
100100
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
101-
void gic_cpu_if_down(void);
101+
int gic_cpu_if_down(unsigned int gic_nr);
102102

103103
static inline void gic_init(unsigned int nr, int start,
104104
void __iomem *dist , void __iomem *cpu)

0 commit comments

Comments
 (0)