summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen Hofstee <jhofstee@victronenergy.com>2019-09-24 18:46:06 +0000
committerMarc Kleine-Budde <mkl@pengutronix.de>2019-11-04 21:47:23 +0100
commitb5018be6d5dd9dd257bf8236298daac8b1262750 (patch)
tree83d646903cc4d99828d0d891de9c7205fa767095
parent3b2d652da21450aba19d299a75fe3a6f5d4003ff (diff)
downloadlinux-b5018be6d5dd9dd257bf8236298daac8b1262750.tar.bz2
can: ti_hecc: add missing state changes
While the ti_hecc has interrupts to report when the error counters increase to a certain level and which change state it doesn't handle the case that the error counters go down again, so the reported state can actually be wrong. Since there is no interrupt for that, do update state based on the error counters, when the state is not error active and goes down again. Signed-off-by: Jeroen Hofstee <jhofstee@victronenergy.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--drivers/net/can/ti_hecc.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 4c6d3ce0e8c4..31ad364a89bb 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -711,6 +711,23 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
can_bus_off(ndev);
ti_hecc_change_state(ndev, rx_state, tx_state);
}
+ } else if (unlikely(priv->can.state != CAN_STATE_ERROR_ACTIVE)) {
+ enum can_state new_state, tx_state, rx_state;
+ u32 rec = hecc_read(priv, HECC_CANREC);
+ u32 tec = hecc_read(priv, HECC_CANTEC);
+
+ if (rec >= 128 || tec >= 128)
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ else if (rec >= 96 || tec >= 96)
+ new_state = CAN_STATE_ERROR_WARNING;
+ else
+ new_state = CAN_STATE_ERROR_ACTIVE;
+
+ if (new_state < priv->can.state) {
+ rx_state = rec >= tec ? new_state : 0;
+ tx_state = rec <= tec ? new_state : 0;
+ ti_hecc_change_state(ndev, rx_state, tx_state);
+ }
}
if (int_status & HECC_CANGIF_GMIF) {