blob: ce751d849a77b03ed477b17bda565dc6028628d2 [file] [log] [blame]
From 0c30e56aca8110ba0017063f1d22358d74621a79 Mon Sep 17 00:00:00 2001
From: Russell King <>
Date: Fri, 28 Feb 2020 19:39:41 +0000
Subject: [PATCH] net: dsa: mv88e6xxx: fix lockup on warm boot
commit 0395823b8d9a4d87bd1bf74359123461c2ae801b upstream.
If the switch is not hardware reset on a warm boot, interrupts can be
left enabled, and possibly pending. This will cause us to enter an
infinite loop trying to service an interrupt we are unable to handle,
thereby preventing the kernel from booting.
Ensure that the global 2 interrupt sources are disabled before we claim
the parent interrupt.
Observed on the ZII development revision B and C platforms with
reworked serdes support, and using reboot -f to reboot the platform.
Fixes: dc30c35be720 ("net: dsa: mv88e6xxx: Implement interrupt support.")
Signed-off-by: Russell King <>
Reviewed-by: Andrew Lunn <>
Signed-off-by: David S. Miller <>
[PG: use old mutex lock names - v5.2 doesn't have c9acece064e3.]
Signed-off-by: Paul Gortmaker <>
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 1546171210a1..d70f08cfcaf8 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -1043,6 +1043,13 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
int err, irq, virq;
+ chip->g2_irq.masked = ~0;
+ mutex_lock(&chip->reg_lock);
+ err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
+ mutex_unlock(&chip->reg_lock);
+ if (err)
+ return err;
chip->g2_irq.domain = irq_domain_add_simple(
chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
if (!chip->g2_irq.domain)
@@ -1052,7 +1059,6 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
irq_create_mapping(chip->g2_irq.domain, irq);
chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
- chip->g2_irq.masked = ~0;
chip->device_irq = irq_find_mapping(chip->g1_irq.domain,