Commit 5af3e93e authored by Paul Burton's avatar Paul Burton Committed by Marc Zyngier

irqchip: mips-gic: Share register writes in gic_set_type()

The gic_set_type() function included writes to the MIPS GIC polarity,
trigger & dual-trigger registers in each case of a switch statement
determining the IRQs type. This is all well & good when we only have a
single cluster & thus a single GIC whose register we want to update. It
will lead to significant duplication once we have multi-cluster support
& multiple GICs to update.

Refactor this such that we determine values for the polarity, trigger &
dual-trigger registers and then have a single set of register writes
following the switch statement. This will allow us to write the same
values to each GIC in a multi-cluster system in a later patch, rather
than needing to duplicate more register writes in each case.
Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 82857688
...@@ -199,46 +199,46 @@ static void gic_ack_irq(struct irq_data *d) ...@@ -199,46 +199,46 @@ static void gic_ack_irq(struct irq_data *d)
static int gic_set_type(struct irq_data *d, unsigned int type) static int gic_set_type(struct irq_data *d, unsigned int type)
{ {
unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int irq, pol, trig, dual;
unsigned long flags; unsigned long flags;
bool is_edge;
irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
spin_lock_irqsave(&gic_lock, flags); spin_lock_irqsave(&gic_lock, flags);
switch (type & IRQ_TYPE_SENSE_MASK) { switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_FALLING:
change_gic_pol(irq, GIC_POL_FALLING_EDGE); pol = GIC_POL_FALLING_EDGE;
change_gic_trig(irq, GIC_TRIG_EDGE); trig = GIC_TRIG_EDGE;
change_gic_dual(irq, GIC_DUAL_SINGLE); dual = GIC_DUAL_SINGLE;
is_edge = true;
break; break;
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
change_gic_pol(irq, GIC_POL_RISING_EDGE); pol = GIC_POL_RISING_EDGE;
change_gic_trig(irq, GIC_TRIG_EDGE); trig = GIC_TRIG_EDGE;
change_gic_dual(irq, GIC_DUAL_SINGLE); dual = GIC_DUAL_SINGLE;
is_edge = true;
break; break;
case IRQ_TYPE_EDGE_BOTH: case IRQ_TYPE_EDGE_BOTH:
/* polarity is irrelevant in this case */ pol = 0; /* Doesn't matter */
change_gic_trig(irq, GIC_TRIG_EDGE); trig = GIC_TRIG_EDGE;
change_gic_dual(irq, GIC_DUAL_DUAL); dual = GIC_DUAL_DUAL;
is_edge = true;
break; break;
case IRQ_TYPE_LEVEL_LOW: case IRQ_TYPE_LEVEL_LOW:
change_gic_pol(irq, GIC_POL_ACTIVE_LOW); pol = GIC_POL_ACTIVE_LOW;
change_gic_trig(irq, GIC_TRIG_LEVEL); trig = GIC_TRIG_LEVEL;
change_gic_dual(irq, GIC_DUAL_SINGLE); dual = GIC_DUAL_SINGLE;
is_edge = false;
break; break;
case IRQ_TYPE_LEVEL_HIGH: case IRQ_TYPE_LEVEL_HIGH:
default: default:
change_gic_pol(irq, GIC_POL_ACTIVE_HIGH); pol = GIC_POL_ACTIVE_HIGH;
change_gic_trig(irq, GIC_TRIG_LEVEL); trig = GIC_TRIG_LEVEL;
change_gic_dual(irq, GIC_DUAL_SINGLE); dual = GIC_DUAL_SINGLE;
is_edge = false;
break; break;
} }
if (is_edge) change_gic_pol(irq, pol);
change_gic_trig(irq, trig);
change_gic_dual(irq, dual);
if (trig == GIC_TRIG_EDGE)
irq_set_chip_handler_name_locked(d, &gic_edge_irq_controller, irq_set_chip_handler_name_locked(d, &gic_edge_irq_controller,
handle_edge_irq, NULL); handle_edge_irq, NULL);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment