irqchip/gic: Pass GIC pointer to save/restore functions

Instead of passing the GIC index to the save/restore functions pass a
pointer to the GIC chip data. This will allow these save/restore
functions to be re-used by a platform driver where the GIC chip data
structure is allocated dynamically and so there is no applicable index
for identifying the GIC.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
Jon Hunter 2016-05-10 16:14:43 +01:00 committed by Marc Zyngier
parent dc9722cc57
commit 6e5b5924d9

View File

@ -529,34 +529,35 @@ int gic_cpu_if_down(unsigned int gic_nr)
* this function, no interrupts will be delivered by the GIC, and another * this function, no interrupts will be delivered by the GIC, and another
* platform-specific wakeup source must be enabled. * platform-specific wakeup source must be enabled.
*/ */
static void gic_dist_save(unsigned int gic_nr) static void gic_dist_save(struct gic_chip_data *gic)
{ {
unsigned int gic_irqs; unsigned int gic_irqs;
void __iomem *dist_base; void __iomem *dist_base;
int i; int i;
BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); if (WARN_ON(!gic))
return;
gic_irqs = gic_data[gic_nr].gic_irqs; gic_irqs = gic->gic_irqs;
dist_base = gic_data_dist_base(&gic_data[gic_nr]); dist_base = gic_data_dist_base(gic);
if (!dist_base) if (!dist_base)
return; return;
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
gic_data[gic_nr].saved_spi_conf[i] = gic->saved_spi_conf[i] =
readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); readl_relaxed(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++)
gic_data[gic_nr].saved_spi_target[i] = gic->saved_spi_target[i] =
readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
gic_data[gic_nr].saved_spi_enable[i] = gic->saved_spi_enable[i] =
readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
gic_data[gic_nr].saved_spi_active[i] = gic->saved_spi_active[i] =
readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4);
} }
@ -567,16 +568,17 @@ static void gic_dist_save(unsigned int gic_nr)
* handled normally, but any edge interrupts that occured will not be seen by * handled normally, but any edge interrupts that occured will not be seen by
* the GIC and need to be handled by the platform-specific wakeup source. * the GIC and need to be handled by the platform-specific wakeup source.
*/ */
static void gic_dist_restore(unsigned int gic_nr) static void gic_dist_restore(struct gic_chip_data *gic)
{ {
unsigned int gic_irqs; unsigned int gic_irqs;
unsigned int i; unsigned int i;
void __iomem *dist_base; void __iomem *dist_base;
BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); if (WARN_ON(!gic))
return;
gic_irqs = gic_data[gic_nr].gic_irqs; gic_irqs = gic->gic_irqs;
dist_base = gic_data_dist_base(&gic_data[gic_nr]); dist_base = gic_data_dist_base(gic);
if (!dist_base) if (!dist_base)
return; return;
@ -584,7 +586,7 @@ static void gic_dist_restore(unsigned int gic_nr)
writel_relaxed(GICD_DISABLE, 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->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++)
@ -592,85 +594,87 @@ static void gic_dist_restore(unsigned int gic_nr)
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++)
writel_relaxed(gic_data[gic_nr].saved_spi_target[i], writel_relaxed(gic->saved_spi_target[i],
dist_base + GIC_DIST_TARGET + i * 4); dist_base + GIC_DIST_TARGET + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) {
writel_relaxed(GICD_INT_EN_CLR_X32, writel_relaxed(GICD_INT_EN_CLR_X32,
dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); dist_base + GIC_DIST_ENABLE_CLEAR + i * 4);
writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], writel_relaxed(gic->saved_spi_enable[i],
dist_base + GIC_DIST_ENABLE_SET + i * 4); dist_base + GIC_DIST_ENABLE_SET + i * 4);
} }
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) {
writel_relaxed(GICD_INT_EN_CLR_X32, writel_relaxed(GICD_INT_EN_CLR_X32,
dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4);
writel_relaxed(gic_data[gic_nr].saved_spi_active[i], writel_relaxed(gic->saved_spi_active[i],
dist_base + GIC_DIST_ACTIVE_SET + i * 4); dist_base + GIC_DIST_ACTIVE_SET + i * 4);
} }
writel_relaxed(GICD_ENABLE, 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(struct gic_chip_data *gic)
{ {
int i; int i;
u32 *ptr; u32 *ptr;
void __iomem *dist_base; void __iomem *dist_base;
void __iomem *cpu_base; void __iomem *cpu_base;
BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); if (WARN_ON(!gic))
return;
dist_base = gic_data_dist_base(&gic_data[gic_nr]); dist_base = gic_data_dist_base(gic);
cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); cpu_base = gic_data_cpu_base(gic);
if (!dist_base || !cpu_base) if (!dist_base || !cpu_base)
return; return;
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); ptr = raw_cpu_ptr(gic->saved_ppi_enable);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++) for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); ptr = raw_cpu_ptr(gic->saved_ppi_active);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++) for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4);
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); ptr = raw_cpu_ptr(gic->saved_ppi_conf);
for (i = 0; i < DIV_ROUND_UP(32, 16); i++) for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
} }
static void gic_cpu_restore(unsigned int gic_nr) static void gic_cpu_restore(struct gic_chip_data *gic)
{ {
int i; int i;
u32 *ptr; u32 *ptr;
void __iomem *dist_base; void __iomem *dist_base;
void __iomem *cpu_base; void __iomem *cpu_base;
BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); if (WARN_ON(!gic))
return;
dist_base = gic_data_dist_base(&gic_data[gic_nr]); dist_base = gic_data_dist_base(gic);
cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); cpu_base = gic_data_cpu_base(gic);
if (!dist_base || !cpu_base) if (!dist_base || !cpu_base)
return; return;
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); ptr = raw_cpu_ptr(gic->saved_ppi_enable);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { for (i = 0; i < DIV_ROUND_UP(32, 32); i++) {
writel_relaxed(GICD_INT_EN_CLR_X32, writel_relaxed(GICD_INT_EN_CLR_X32,
dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); dist_base + GIC_DIST_ENABLE_CLEAR + i * 4);
writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
} }
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); ptr = raw_cpu_ptr(gic->saved_ppi_active);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { for (i = 0; i < DIV_ROUND_UP(32, 32); i++) {
writel_relaxed(GICD_INT_EN_CLR_X32, writel_relaxed(GICD_INT_EN_CLR_X32,
dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4);
writel_relaxed(ptr[i], dist_base + GIC_DIST_ACTIVE_SET + i * 4); writel_relaxed(ptr[i], dist_base + GIC_DIST_ACTIVE_SET + i * 4);
} }
ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); ptr = raw_cpu_ptr(gic->saved_ppi_conf);
for (i = 0; i < DIV_ROUND_UP(32, 16); i++) for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
@ -679,7 +683,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
dist_base + GIC_DIST_PRI + i * 4); dist_base + GIC_DIST_PRI + i * 4);
writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
gic_cpu_if_up(&gic_data[gic_nr]); gic_cpu_if_up(gic);
} }
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)
@ -694,18 +698,18 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
#endif #endif
switch (cmd) { switch (cmd) {
case CPU_PM_ENTER: case CPU_PM_ENTER:
gic_cpu_save(i); gic_cpu_save(&gic_data[i]);
break; break;
case CPU_PM_ENTER_FAILED: case CPU_PM_ENTER_FAILED:
case CPU_PM_EXIT: case CPU_PM_EXIT:
gic_cpu_restore(i); gic_cpu_restore(&gic_data[i]);
break; break;
case CPU_CLUSTER_PM_ENTER: case CPU_CLUSTER_PM_ENTER:
gic_dist_save(i); gic_dist_save(&gic_data[i]);
break; break;
case CPU_CLUSTER_PM_ENTER_FAILED: case CPU_CLUSTER_PM_ENTER_FAILED:
case CPU_CLUSTER_PM_EXIT: case CPU_CLUSTER_PM_EXIT:
gic_dist_restore(i); gic_dist_restore(&gic_data[i]);
break; break;
} }
} }