> Signed-off-by: John David Anglin <dave.ang...@bell.net> > --- > drivers/net/dsa/mv88e6xxx/chip.c | 28 ++++++++++++++++++++++------ > 1 file changed, 22 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/dsa/mv88e6xxx/chip.c > b/drivers/net/dsa/mv88e6xxx/chip.c > index 8dca2c949e73..12fd7ce3f1ff 100644 > --- a/drivers/net/dsa/mv88e6xxx/chip.c > +++ b/drivers/net/dsa/mv88e6xxx/chip.c > @@ -261,6 +261,7 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct > mv88e6xxx_chip *chip) > unsigned int sub_irq; > unsigned int n; > u16 reg; > + u16 ctl1; > int err; > > mutex_lock(&chip->reg_lock); > @@ -270,13 +271,28 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct > mv88e6xxx_chip *chip) > if (err) > goto out; > > - for (n = 0; n < chip->g1_irq.nirqs; ++n) { > - if (reg & (1 << n)) { > - sub_irq = irq_find_mapping(chip->g1_irq.domain, n); > - handle_nested_irq(sub_irq); > - ++nhandled; > + do { > + for (n = 0; n < chip->g1_irq.nirqs; ++n) { > + if (reg & (1 << n)) { > + sub_irq = irq_find_mapping(chip->g1_irq.domain, > + n); > + handle_nested_irq(sub_irq); > + ++nhandled; > + } > } > - } > + > + mutex_lock(&chip->reg_lock); > + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1); > + if (err) > + goto unlock; > + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); > +unlock: > + mutex_unlock(&chip->reg_lock); > + if (err) > + goto out; > + ctl1 &= GENMASK(chip->g1_irq.nirqs, 0); > + } while (reg & ctl1);
Hi David I just tested this on one of my boards. It loops endlessly: [ 47.173396] mv88e6xxx_g1_irq_thread_work: c881 a8 80 [ 47.182108] mv88e6xxx_g1_irq_thread_work: c881 a8 80 [ 47.190820] mv88e6xxx_g1_irq_thread_work: c881 a8 80 [ 47.199535] mv88e6xxx_g1_irq_thread_work: c881 a8 80 [ 47.208254] mv88e6xxx_g1_irq_thread_work: c881 a8 80 These are reg, ctl1, reg & ctl1. So there is an unhandled device interrupt. I think this is because device interrupts are not masked before installing the interrupt handler. But i've not fully got to the bottom of this yet. Andrew