Merge branch 'irqchip/gic' into irqchip/core
This commit is contained in:
commit
ce92bfe88b
@ -74,20 +74,22 @@ void __init gic_dist_config(void __iomem *base, int gic_irqs,
|
|||||||
* Set all global interrupts to be level triggered, active low.
|
* Set all global interrupts to be level triggered, active low.
|
||||||
*/
|
*/
|
||||||
for (i = 32; i < gic_irqs; i += 16)
|
for (i = 32; i < gic_irqs; i += 16)
|
||||||
writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4);
|
writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
|
||||||
|
base + GIC_DIST_CONFIG + i / 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set priority on all global interrupts.
|
* Set priority on all global interrupts.
|
||||||
*/
|
*/
|
||||||
for (i = 32; i < gic_irqs; i += 4)
|
for (i = 32; i < gic_irqs; i += 4)
|
||||||
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i);
|
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable all interrupts. Leave the PPI and SGIs alone
|
* Disable all interrupts. Leave the PPI and SGIs alone
|
||||||
* as they are enabled by redistributor registers.
|
* as they are enabled by redistributor registers.
|
||||||
*/
|
*/
|
||||||
for (i = 32; i < gic_irqs; i += 32)
|
for (i = 32; i < gic_irqs; i += 32)
|
||||||
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8);
|
writel_relaxed(GICD_INT_EN_CLR_X32,
|
||||||
|
base + GIC_DIST_ENABLE_CLEAR + i / 8);
|
||||||
|
|
||||||
if (sync_access)
|
if (sync_access)
|
||||||
sync_access();
|
sync_access();
|
||||||
@ -101,14 +103,15 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
|
|||||||
* Deal with the banked PPI and SGI interrupts - disable all
|
* Deal with the banked PPI and SGI interrupts - disable all
|
||||||
* PPI interrupts, ensure all SGI interrupts are enabled.
|
* PPI interrupts, ensure all SGI interrupts are enabled.
|
||||||
*/
|
*/
|
||||||
writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR);
|
writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR);
|
||||||
writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET);
|
writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set priority on PPI and SGI interrupts
|
* Set priority on PPI and SGI interrupts
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 32; i += 4)
|
for (i = 0; i < 32; i += 4)
|
||||||
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
|
writel_relaxed(GICD_INT_DEF_PRI_X4,
|
||||||
|
base + GIC_DIST_PRI + i * 4 / 4);
|
||||||
|
|
||||||
if (sync_access)
|
if (sync_access)
|
||||||
sync_access();
|
sync_access();
|
||||||
|
@ -298,8 +298,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
|
|||||||
status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
|
status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
|
||||||
raw_spin_unlock(&irq_controller_lock);
|
raw_spin_unlock(&irq_controller_lock);
|
||||||
|
|
||||||
gic_irq = (status & 0x3ff);
|
gic_irq = (status & GICC_IAR_INT_ID_MASK);
|
||||||
if (gic_irq == 1023)
|
if (gic_irq == GICC_INT_SPURIOUS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
|
cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
|
||||||
@ -353,6 +353,21 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
|
|||||||
return mask;
|
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)
|
static void __init gic_dist_init(struct gic_chip_data *gic)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -360,7 +375,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
|
|||||||
unsigned int gic_irqs = gic->gic_irqs;
|
unsigned int gic_irqs = gic->gic_irqs;
|
||||||
void __iomem *base = gic_data_dist_base(gic);
|
void __iomem *base = gic_data_dist_base(gic);
|
||||||
|
|
||||||
writel_relaxed(0, base + GIC_DIST_CTRL);
|
writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set all global interrupts to this CPU only.
|
* Set all global interrupts to this CPU only.
|
||||||
@ -373,7 +388,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
|
|||||||
|
|
||||||
gic_dist_config(base, gic_irqs, NULL);
|
gic_dist_config(base, gic_irqs, NULL);
|
||||||
|
|
||||||
writel_relaxed(1, base + GIC_DIST_CTRL);
|
writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gic_cpu_init(struct gic_chip_data *gic)
|
static void gic_cpu_init(struct gic_chip_data *gic)
|
||||||
@ -400,14 +415,18 @@ static void gic_cpu_init(struct gic_chip_data *gic)
|
|||||||
|
|
||||||
gic_cpu_config(dist_base, NULL);
|
gic_cpu_config(dist_base, NULL);
|
||||||
|
|
||||||
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
|
writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
|
||||||
writel_relaxed(1, base + GIC_CPU_CTRL);
|
gic_cpu_if_up();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gic_cpu_if_down(void)
|
void gic_cpu_if_down(void)
|
||||||
{
|
{
|
||||||
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
|
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
|
#ifdef CONFIG_CPU_PM
|
||||||
@ -467,14 +486,14 @@ static void gic_dist_restore(unsigned int gic_nr)
|
|||||||
if (!dist_base)
|
if (!dist_base)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writel_relaxed(0, dist_base + GIC_DIST_CTRL);
|
writel_relaxed(GICD_DISABLE, dist_base + GIC_DIST_CTRL);
|
||||||
|
|
||||||
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
|
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
|
||||||
writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
|
writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
|
||||||
dist_base + GIC_DIST_CONFIG + i * 4);
|
dist_base + GIC_DIST_CONFIG + i * 4);
|
||||||
|
|
||||||
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
|
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
|
||||||
writel_relaxed(0xa0a0a0a0,
|
writel_relaxed(GICD_INT_DEF_PRI_X4,
|
||||||
dist_base + GIC_DIST_PRI + i * 4);
|
dist_base + GIC_DIST_PRI + i * 4);
|
||||||
|
|
||||||
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
|
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
|
||||||
@ -485,7 +504,7 @@ static void gic_dist_restore(unsigned int gic_nr)
|
|||||||
writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
|
writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
|
||||||
dist_base + GIC_DIST_ENABLE_SET + i * 4);
|
dist_base + GIC_DIST_ENABLE_SET + i * 4);
|
||||||
|
|
||||||
writel_relaxed(1, dist_base + GIC_DIST_CTRL);
|
writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gic_cpu_save(unsigned int gic_nr)
|
static void gic_cpu_save(unsigned int gic_nr)
|
||||||
@ -539,10 +558,11 @@ static void gic_cpu_restore(unsigned int gic_nr)
|
|||||||
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
|
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
|
||||||
|
|
||||||
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
|
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
|
||||||
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
|
writel_relaxed(GICD_INT_DEF_PRI_X4,
|
||||||
|
dist_base + GIC_DIST_PRI + i * 4);
|
||||||
|
|
||||||
writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
|
writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
|
||||||
writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
|
gic_cpu_if_up();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
|
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
|
||||||
|
@ -21,7 +21,11 @@
|
|||||||
#define GIC_CPU_ACTIVEPRIO 0xd0
|
#define GIC_CPU_ACTIVEPRIO 0xd0
|
||||||
#define GIC_CPU_IDENT 0xfc
|
#define GIC_CPU_IDENT 0xfc
|
||||||
|
|
||||||
|
#define GICC_ENABLE 0x1
|
||||||
|
#define GICC_INT_PRI_THRESHOLD 0xf0
|
||||||
#define GICC_IAR_INT_ID_MASK 0x3ff
|
#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_CTRL 0x000
|
||||||
#define GIC_DIST_CTR 0x004
|
#define GIC_DIST_CTR 0x004
|
||||||
@ -39,6 +43,18 @@
|
|||||||
#define GIC_DIST_SGI_PENDING_CLEAR 0xf10
|
#define GIC_DIST_SGI_PENDING_CLEAR 0xf10
|
||||||
#define GIC_DIST_SGI_PENDING_SET 0xf20
|
#define GIC_DIST_SGI_PENDING_SET 0xf20
|
||||||
|
|
||||||
|
#define GICD_ENABLE 0x1
|
||||||
|
#define GICD_DISABLE 0x0
|
||||||
|
#define GICD_INT_ACTLOW_LVLTRIG 0x0
|
||||||
|
#define GICD_INT_EN_CLR_X32 0xffffffff
|
||||||
|
#define GICD_INT_EN_SET_SGI 0x0000ffff
|
||||||
|
#define GICD_INT_EN_CLR_PPI 0xffff0000
|
||||||
|
#define GICD_INT_DEF_PRI 0xa0
|
||||||
|
#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
|
||||||
|
(GICD_INT_DEF_PRI << 16) |\
|
||||||
|
(GICD_INT_DEF_PRI << 8) |\
|
||||||
|
GICD_INT_DEF_PRI)
|
||||||
|
|
||||||
#define GICH_HCR 0x0
|
#define GICH_HCR 0x0
|
||||||
#define GICH_VTR 0x4
|
#define GICH_VTR 0x4
|
||||||
#define GICH_VMCR 0x8
|
#define GICH_VMCR 0x8
|
||||||
|
Loading…
Reference in New Issue
Block a user