]> Pileus Git - ~andy/linux/blobdiff - drivers/net/can/flexcan.c
can: flexcan: flexcan_open(): fix error path if flexcan_chip_start() fails
[~andy/linux] / drivers / net / can / flexcan.c
index aaed97bee4711d1cb2e8b1eb514fc3e343ad21e0..30af702a07ad37121dc3b8154177d979c92a7647 100644 (file)
@@ -235,9 +235,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
 };
 
 /*
- * Abstract off the read/write for arm versus ppc.
+ * Abstract off the read/write for arm versus ppc. This
+ * assumes that PPC uses big-endian registers and everything
+ * else uses little-endian registers, independent of CPU
+ * endianess.
  */
-#if defined(__BIG_ENDIAN)
+#if defined(CONFIG_PPC)
 static inline u32 flexcan_read(void __iomem *addr)
 {
        return in_be32(addr);
@@ -824,14 +827,16 @@ static void flexcan_chip_stop(struct net_device *dev)
        struct flexcan_regs __iomem *regs = priv->base;
        u32 reg;
 
-       /* Disable all interrupts */
-       flexcan_write(0, &regs->imask1);
-
        /* Disable + halt module */
        reg = flexcan_read(&regs->mcr);
        reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
        flexcan_write(reg, &regs->mcr);
 
+       /* Disable all interrupts */
+       flexcan_write(0, &regs->imask1);
+       flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+                     &regs->ctrl);
+
        if (priv->reg_xceiver)
                regulator_disable(priv->reg_xceiver);
        priv->can.state = CAN_STATE_STOPPED;
@@ -863,7 +868,7 @@ static int flexcan_open(struct net_device *dev)
        /* start chip and queuing */
        err = flexcan_chip_start(dev);
        if (err)
-               goto out_close;
+               goto out_free_irq;
 
        can_led_event(dev, CAN_LED_EVENT_OPEN);
 
@@ -872,6 +877,8 @@ static int flexcan_open(struct net_device *dev)
 
        return 0;
 
+ out_free_irq:
+       free_irq(dev->irq, dev);
  out_close:
        close_candev(dev);
  out_disable_per: