Message ID | 20230331084014.1144597-1-gustav.ekelund@axis.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 089b91a0155c4de1209a07ff2a7dd299ff3ece47 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net,v2] net: dsa: mv88e6xxx: Reset mv88e6393x force WD event bit | expand |
On Fri, Mar 31, 2023 at 10:40:13AM +0200, Gustav Ekelund wrote: > From: Gustav Ekelund <gustaek@axis.com> > > The force watchdog event bit is not cleared during SW reset in the > mv88e6393x switch. This is a different behavior compared to mv886390 which > clears the force WD event bit as advertised. This causes a force WD event > to be handled over and over again as the SW reset following the event never > clears the force WD event bit. > > Explicitly clear the watchdog event register to 0 in irq_action when > handling an event to prevent the switch from sending continuous interrupts. > Marvell aren't aware of any other stuck bits apart from the force WD > bit. > > Signed-off-by: Gustav Ekelund <gustaek@axis.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Andrew
On 3/31/2023 1:40 AM, Gustav Ekelund wrote: > From: Gustav Ekelund <gustaek@axis.com> > > The force watchdog event bit is not cleared during SW reset in the > mv88e6393x switch. This is a different behavior compared to mv886390 which > clears the force WD event bit as advertised. This causes a force WD event > to be handled over and over again as the SW reset following the event never > clears the force WD event bit. > > Explicitly clear the watchdog event register to 0 in irq_action when > handling an event to prevent the switch from sending continuous interrupts. > Marvell aren't aware of any other stuck bits apart from the force WD > bit. > > Signed-off-by: Gustav Ekelund <gustaek@axis.com> Would that deserve: Fixes: de776d0d316f ("net: dsa: mv88e6xxx: add support for mv88e6393x family") Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Hello: This patch was applied to netdev/net.git (main) by David S. Miller <davem@davemloft.net>: On Fri, 31 Mar 2023 10:40:13 +0200 you wrote: > From: Gustav Ekelund <gustaek@axis.com> > > The force watchdog event bit is not cleared during SW reset in the > mv88e6393x switch. This is a different behavior compared to mv886390 which > clears the force WD event bit as advertised. This causes a force WD event > to be handled over and over again as the SW reset following the event never > clears the force WD event bit. > > [...] Here is the summary with links: - [net,v2] net: dsa: mv88e6xxx: Reset mv88e6393x force WD event bit https://git.kernel.org/netdev/net/c/089b91a0155c You are awesome, thank you!
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 30383c4f8fd0..ee22d4785e9e 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -5596,7 +5596,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = { * .port_set_upstream_port method. */ .set_egress_port = mv88e6393x_set_egress_port, - .watchdog_ops = &mv88e6390_watchdog_ops, + .watchdog_ops = &mv88e6393x_watchdog_ops, .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c index ed3b2f88e783..a7af3cebae97 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.c +++ b/drivers/net/dsa/mv88e6xxx/global2.c @@ -943,6 +943,26 @@ const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = { .irq_free = mv88e6390_watchdog_free, }; +static int mv88e6393x_watchdog_action(struct mv88e6xxx_chip *chip, int irq) +{ + mv88e6390_watchdog_action(chip, irq); + + /* Fix for clearing the force WD event bit. + * Unreleased erratum on mv88e6393x. + */ + mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL, + MV88E6390_G2_WDOG_CTL_UPDATE | + MV88E6390_G2_WDOG_CTL_PTR_EVENT); + + return IRQ_HANDLED; +} + +const struct mv88e6xxx_irq_ops mv88e6393x_watchdog_ops = { + .irq_action = mv88e6393x_watchdog_action, + .irq_setup = mv88e6390_watchdog_setup, + .irq_free = mv88e6390_watchdog_free, +}; + static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id) { struct mv88e6xxx_chip *chip = dev_id; diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h index e973114d6890..7e091965582b 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.h +++ b/drivers/net/dsa/mv88e6xxx/global2.h @@ -369,6 +369,7 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops; +extern const struct mv88e6xxx_irq_ops mv88e6393x_watchdog_ops; extern const struct mv88e6xxx_avb_ops mv88e6165_avb_ops; extern const struct mv88e6xxx_avb_ops mv88e6352_avb_ops;