diff options
-rw-r--r-- | drivers/net/can/flexcan.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 886905db1396..d0b8e8ed275b 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -145,6 +145,8 @@ #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) +#define FLEXCAN_TIMEOUT_US 50 + /* Structure of the message buffer */ struct flexcan_mb { u32 can_ctrl; @@ -249,23 +251,38 @@ static inline void flexcan_exit_stop(struct flexcan_priv *priv) static inline void flexcan_chip_enable(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->base; + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; u32 reg; reg = readl(®s->mcr); reg &= ~FLEXCAN_MCR_MDIS; writel(reg, ®s->mcr); - udelay(10); + while (timeout-- && (readl(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + usleep_range(10, 20); + + if (readl(®s->mcr) & FLEXCAN_MCR_LPM_ACK) + dev_err(priv->dev->dev.parent, + "flexcan_chip_disable timed out\n"); } static inline void flexcan_chip_disable(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->base; + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; u32 reg; reg = readl(®s->mcr); reg |= FLEXCAN_MCR_MDIS; writel(reg, ®s->mcr); + + + while (timeout-- && !(readl(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + usleep_range(10, 20); + + if (!(readl(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + dev_err(priv->dev->dev.parent, + "flexcan_chip_disable timed out\n"); } static int flexcan_get_berr_counter(const struct net_device *dev, |