Skip to content

Commit

Permalink
irqchip: gic: Preserve gic V2 bypass bits in cpu ctrl register
Browse files Browse the repository at this point in the history
This change is made to preserve the GIC v2 bypass bits in the
GIC_CPU_CTRL register (also known as the GICC_CTLR register in spec).
This code will preserve all bits configured by the bootloader regarding
v2 bypass group bits. In the X-Gene platform, the bypass functionality
is not used and bypass bits should not be changed by the kernel gic
code as it could lead to incorrect behavior.

Signed-off-by: Feng Kan <fkan@apm.com>
Reviewed-by: Vinayak Kale <vkale@apm.com>
Reviewed-by: Anup Patel <apatel@apm.com>
Link: https://lkml.kernel.org/r/1406757419-18729-3-git-send-email-fkan@apm.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
  • Loading branch information
Feng Kan authored and Jason Cooper committed Aug 19, 2014
1 parent e5f8153 commit 3228950
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
25 changes: 22 additions & 3 deletions drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,21 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
return mask;
}

static void gic_cpu_if_up(void)
{
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
u32 bypass = 0;

/*
* Preserve bypass disable bits to be written back later
*/
bypass = readl(cpu_base + GIC_CPU_CTRL);
bypass &= GICC_DIS_BYPASS_MASK;

writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
}


static void __init gic_dist_init(struct gic_chip_data *gic)
{
unsigned int i;
Expand Down Expand Up @@ -401,13 +416,17 @@ static void gic_cpu_init(struct gic_chip_data *gic)
gic_cpu_config(dist_base, NULL);

writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
writel_relaxed(GICC_ENABLE, base + GIC_CPU_CTRL);
gic_cpu_if_up();
}

void gic_cpu_if_down(void)
{
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
writel_relaxed(0, cpu_base + GIC_CPU_CTRL);
u32 val = 0;

val = readl(cpu_base + GIC_CPU_CTRL);
val &= ~GICC_ENABLE;
writel_relaxed(val, cpu_base + GIC_CPU_CTRL);
}

#ifdef CONFIG_CPU_PM
Expand Down Expand Up @@ -543,7 +562,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
dist_base + GIC_DIST_PRI + i * 4);

writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
writel_relaxed(GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
gic_cpu_if_up();
}

static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
Expand Down
1 change: 1 addition & 0 deletions include/linux/irqchip/arm-gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define GICC_INT_PRI_THRESHOLD 0xf0
#define GICC_IAR_INT_ID_MASK 0x3ff
#define GICC_INT_SPURIOUS 1023
#define GICC_DIS_BYPASS_MASK 0x1e0

#define GIC_DIST_CTRL 0x000
#define GIC_DIST_CTR 0x004
Expand Down

0 comments on commit 3228950

Please sign in to comment.