diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-03-18 13:19:08 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2014-04-01 05:54:57 -0400 |
commit | 9fac1d1ab8e66816c40a235a238357b1f1fc4dee (patch) | |
tree | d277fa95c6ae7a6c3566d06d7b242c20dd9abebf /drivers/net/can/c_can/c_can.c | |
parent | 130a5171dad06c6d89fd5568260fbb0c4b34bd74 (diff) |
can: c_can: Wait for CONTROL_INIT to be cleared
According to the documentation the CPU must wait for CONTROL_INIT to
be cleared before writing to the baudrate registers.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/c_can/c_can.c')
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 68839380086d..4d08a32f27ac 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -566,6 +566,21 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, | |||
566 | return NETDEV_TX_OK; | 566 | return NETDEV_TX_OK; |
567 | } | 567 | } |
568 | 568 | ||
569 | static int c_can_wait_for_ctrl_init(struct net_device *dev, | ||
570 | struct c_can_priv *priv, u32 init) | ||
571 | { | ||
572 | int retry = 0; | ||
573 | |||
574 | while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) { | ||
575 | udelay(10); | ||
576 | if (retry++ > 1000) { | ||
577 | netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n"); | ||
578 | return -EIO; | ||
579 | } | ||
580 | } | ||
581 | return 0; | ||
582 | } | ||
583 | |||
569 | static int c_can_set_bittiming(struct net_device *dev) | 584 | static int c_can_set_bittiming(struct net_device *dev) |
570 | { | 585 | { |
571 | unsigned int reg_btr, reg_brpe, ctrl_save; | 586 | unsigned int reg_btr, reg_brpe, ctrl_save; |
@@ -573,6 +588,7 @@ static int c_can_set_bittiming(struct net_device *dev) | |||
573 | u32 ten_bit_brp; | 588 | u32 ten_bit_brp; |
574 | struct c_can_priv *priv = netdev_priv(dev); | 589 | struct c_can_priv *priv = netdev_priv(dev); |
575 | const struct can_bittiming *bt = &priv->can.bittiming; | 590 | const struct can_bittiming *bt = &priv->can.bittiming; |
591 | int res; | ||
576 | 592 | ||
577 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ | 593 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ |
578 | ten_bit_brp = bt->brp - 1; | 594 | ten_bit_brp = bt->brp - 1; |
@@ -590,13 +606,17 @@ static int c_can_set_bittiming(struct net_device *dev) | |||
590 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); | 606 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); |
591 | 607 | ||
592 | ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); | 608 | ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); |
593 | priv->write_reg(priv, C_CAN_CTRL_REG, | 609 | ctrl_save &= ~CONTROL_INIT; |
594 | ctrl_save | CONTROL_CCE | CONTROL_INIT); | 610 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT); |
611 | res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT); | ||
612 | if (res) | ||
613 | return res; | ||
614 | |||
595 | priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); | 615 | priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); |
596 | priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); | 616 | priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); |
597 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); | 617 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); |
598 | 618 | ||
599 | return 0; | 619 | return c_can_wait_for_ctrl_init(dev, priv, 0); |
600 | } | 620 | } |
601 | 621 | ||
602 | /* | 622 | /* |