diff options
Diffstat (limited to 'drivers/net/can/c_can/c_can.c')
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index e5180dfddba..2282b1ae976 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -233,6 +233,12 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv) pm_runtime_put_sync(priv->device); } +static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) +{ + if (priv->raminit) + priv->raminit(priv, enable); +} + static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) { return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + @@ -482,8 +488,12 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface, priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), IFX_WRITE_LOW_16BIT(mask)); + + /* According to C_CAN documentation, the reserved bit + * in IFx_MASK2 register is fixed 1 + */ priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), - IFX_WRITE_HIGH_16BIT(mask)); + IFX_WRITE_HIGH_16BIT(mask) | BIT(13)); priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), IFX_WRITE_LOW_16BIT(id)); @@ -954,7 +964,7 @@ static int c_can_handle_bus_err(struct net_device *dev, break; case LEC_ACK_ERROR: netdev_dbg(dev, "ack error\n"); - cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | + cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | CAN_ERR_PROT_LOC_ACK_DEL); break; case LEC_BIT1_ERROR: @@ -967,7 +977,7 @@ static int c_can_handle_bus_err(struct net_device *dev, break; case LEC_CRC_ERROR: netdev_dbg(dev, "CRC error\n"); - cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | + cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | CAN_ERR_PROT_LOC_CRC_DEL); break; default: @@ -1090,6 +1100,7 @@ static int c_can_open(struct net_device *dev) struct c_can_priv *priv = netdev_priv(dev); c_can_pm_runtime_get_sync(priv); + c_can_reset_ram(priv, true); /* open the can device */ err = open_candev(dev); @@ -1118,6 +1129,7 @@ static int c_can_open(struct net_device *dev) exit_irq_fail: close_candev(dev); exit_open_fail: + c_can_reset_ram(priv, false); c_can_pm_runtime_put_sync(priv); return err; } @@ -1131,6 +1143,8 @@ static int c_can_close(struct net_device *dev) c_can_stop(dev); free_irq(dev->irq, dev); close_candev(dev); + + c_can_reset_ram(priv, false); c_can_pm_runtime_put_sync(priv); return 0; @@ -1188,6 +1202,7 @@ int c_can_power_down(struct net_device *dev) c_can_stop(dev); + c_can_reset_ram(priv, false); c_can_pm_runtime_put_sync(priv); return 0; @@ -1206,6 +1221,7 @@ int c_can_power_up(struct net_device *dev) WARN_ON(priv->type != BOSCH_D_CAN); c_can_pm_runtime_get_sync(priv); + c_can_reset_ram(priv, true); /* Clear PDR and INIT bits */ val = priv->read_reg(priv, C_CAN_CTRL_EX_REG); |