Skip to content

Commit

Permalink
irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
Browse files Browse the repository at this point in the history
gic_configure_irq is currently passed the (re)distributor address,
to which it applies an a fixed offset to get to the configuration
registers. This offset is constant across all GICs, or rather it was
until to v3.1...

An easy way out is for the individual drivers to pass the base
address of the configuration register for the considered interrupt.
At the same time, move part of the error handling back to the
individual drivers, as things are about to change on that front.

Signed-off-by: Marc Zyngier <maz@kernel.org>
  • Loading branch information
Marc Zyngier committed Aug 20, 2019
1 parent b977fcf commit 13d22e2
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
14 changes: 5 additions & 9 deletions drivers/irqchip/irq-gic-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
* for "irq", depending on "type".
*/
raw_spin_lock_irqsave(&irq_controller_lock, flags);
val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
val = oldval = readl_relaxed(base + confoff);
if (type & IRQ_TYPE_LEVEL_MASK)
val &= ~confmask;
else if (type & IRQ_TYPE_EDGE_BOTH)
Expand All @@ -83,14 +83,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
* does not allow us to set the configuration or we are in a
* non-secure mode, and hence it may not be catastrophic.
*/
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
if (WARN_ON(irq >= 32))
ret = -EINVAL;
else
pr_warn("GIC: PPI%d is secure or misconfigured\n",
irq - 16);
}
writel_relaxed(val, base + confoff);
if (readl_relaxed(base + confoff) != val)
ret = -EINVAL;

raw_spin_unlock_irqrestore(&irq_controller_lock, flags);

if (sync_access)
Expand Down
11 changes: 10 additions & 1 deletion drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
unsigned int irq = gic_irq(d);
void (*rwp_wait)(void);
void __iomem *base;
int ret;

/* Interrupt configuration for SGIs can't be changed */
if (irq < 16)
Expand All @@ -425,7 +426,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
rwp_wait = gic_dist_wait_for_rwp;
}

return gic_configure_irq(irq, type, base, rwp_wait);

ret = gic_configure_irq(irq, type, base + GICD_ICFGR, rwp_wait);
if (ret && irq < 32) {
/* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
ret = 0;
}

return ret;
}

static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
Expand Down
10 changes: 9 additions & 1 deletion drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = gic_dist_base(d);
unsigned int gicirq = gic_irq(d);
int ret;

/* Interrupt configuration for SGIs can't be changed */
if (gicirq < 16)
Expand All @@ -301,7 +302,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
type != IRQ_TYPE_EDGE_RISING)
return -EINVAL;

return gic_configure_irq(gicirq, type, base, NULL);
ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
if (ret && gicirq < 32) {
/* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
ret = 0;
}

return ret;
}

static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
Expand Down
7 changes: 6 additions & 1 deletion drivers/irqchip/irq-hip04.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)

raw_spin_lock(&irq_controller_lock);

ret = gic_configure_irq(irq, type, base, NULL);
ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL);
if (ret && irq < 32) {
/* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
ret = 0;
}

raw_spin_unlock(&irq_controller_lock);

Expand Down

0 comments on commit 13d22e2

Please sign in to comment.