diff options
author | Tejun Heo <tj@kernel.org> | 2014-09-24 13:00:21 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-09-24 13:00:21 -0400 |
commit | d06efebf0c37d438fcf07057be00dd40fcfce08d (patch) | |
tree | 31a0786d132aadf4cbb9725f3f444ef6e1052128 /drivers/net/can | |
parent | bb2e226b3bef596dd56be97df655d857b4603923 (diff) | |
parent | 0a30288da1aec914e158c2d7a3482a85f632750f (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block into for-3.18
This is to receive 0a30288da1ae ("blk-mq, percpu_ref: implement a
kludge for SCSI blk-mq stall during probe") which implements
__percpu_ref_kill_expedited() to work around SCSI blk-mq stall. The
commit reverted and patches to implement proper fix will be added.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Kent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/at91_can.c | 8 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can_platform.c | 6 | ||||
-rw-r--r-- | drivers/net/can/flexcan.c | 62 | ||||
-rw-r--r-- | drivers/net/can/sja1000/peak_pci.c | 6 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 62 |
5 files changed, 99 insertions, 45 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index f07fa89b5fd5..05e1aa090add 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1123,7 +1123,9 @@ static int at91_open(struct net_device *dev) struct at91_priv *priv = netdev_priv(dev); int err; - clk_enable(priv->clk); + err = clk_prepare_enable(priv->clk); + if (err) + return err; /* check or determine and set bittime */ err = open_candev(dev); @@ -1149,7 +1151,7 @@ static int at91_open(struct net_device *dev) out_close: close_candev(dev); out: - clk_disable(priv->clk); + clk_disable_unprepare(priv->clk); return err; } @@ -1166,7 +1168,7 @@ static int at91_close(struct net_device *dev) at91_chip_stop(dev, CAN_STATE_STOPPED); free_irq(dev->irq, dev); - clk_disable(priv->clk); + clk_disable_unprepare(priv->clk); close_candev(dev); diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 5dede6e64376..fb279d6ae484 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -97,14 +97,14 @@ static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable) ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); writel(ctrl, priv->raminit_ctrlreg); ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance); - c_can_hw_raminit_wait_ti(priv, ctrl, mask); + c_can_hw_raminit_wait_ti(priv, mask, ctrl); if (enable) { /* Set start bit and wait for the done bit. */ ctrl |= CAN_RAMINIT_START_MASK(priv->instance); writel(ctrl, priv->raminit_ctrlreg); ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); - c_can_hw_raminit_wait_ti(priv, ctrl, mask); + c_can_hw_raminit_wait_ti(priv, mask, ctrl); } spin_unlock(&raminit_lock); } @@ -280,7 +280,7 @@ static int c_can_plat_probe(struct platform_device *pdev) priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) + if (!priv->raminit_ctrlreg || priv->instance < 0) dev_info(&pdev->dev, "control memory is not used for raminit\n"); else priv->raminit = c_can_hw_raminit_ti; diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index f425ec2c7839..6586309329e6 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -62,7 +62,7 @@ #define FLEXCAN_MCR_BCC BIT(16) #define FLEXCAN_MCR_LPRIO_EN BIT(13) #define FLEXCAN_MCR_AEN BIT(12) -#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) +#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f) #define FLEXCAN_MCR_IDAM_A (0 << 8) #define FLEXCAN_MCR_IDAM_B (1 << 8) #define FLEXCAN_MCR_IDAM_C (2 << 8) @@ -125,7 +125,9 @@ FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) /* FLEXCAN interrupt flag register (IFLAG) bits */ -#define FLEXCAN_TX_BUF_ID 8 +/* Errata ERR005829 step7: Reserve first valid MB */ +#define FLEXCAN_TX_BUF_RESERVED 8 +#define FLEXCAN_TX_BUF_ID 9 #define FLEXCAN_IFLAG_BUF(x) BIT(x) #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) @@ -136,6 +138,17 @@ /* FLEXCAN message buffers */ #define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) +#define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24) +#define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24) +#define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24) +#define FLEXCAN_MB_CODE_RX_OVERRRUN (0x6 << 24) +#define FLEXCAN_MB_CODE_RX_RANSWER (0xa << 24) + +#define FLEXCAN_MB_CODE_TX_INACTIVE (0x8 << 24) +#define FLEXCAN_MB_CODE_TX_ABORT (0x9 << 24) +#define FLEXCAN_MB_CODE_TX_DATA (0xc << 24) +#define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24) + #define FLEXCAN_MB_CNT_SRR BIT(22) #define FLEXCAN_MB_CNT_IDE BIT(21) #define FLEXCAN_MB_CNT_RTR BIT(20) @@ -298,7 +311,7 @@ static int flexcan_chip_enable(struct flexcan_priv *priv) flexcan_write(reg, ®s->mcr); while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) - usleep_range(10, 20); + udelay(10); if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) return -ETIMEDOUT; @@ -317,7 +330,7 @@ static int flexcan_chip_disable(struct flexcan_priv *priv) flexcan_write(reg, ®s->mcr); while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) - usleep_range(10, 20); + udelay(10); if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) return -ETIMEDOUT; @@ -336,7 +349,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv) flexcan_write(reg, ®s->mcr); while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) - usleep_range(100, 200); + udelay(100); if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) return -ETIMEDOUT; @@ -355,7 +368,7 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv) flexcan_write(reg, ®s->mcr); while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) - usleep_range(10, 20); + udelay(10); if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) return -ETIMEDOUT; @@ -370,7 +383,7 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv) flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) - usleep_range(10, 20); + udelay(10); if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) return -ETIMEDOUT; @@ -428,6 +441,14 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); + /* Errata ERR005829 step8: + * Write twice INACTIVE(0x8) code to first MB. + */ + flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, + ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl); + flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, + ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl); + return NETDEV_TX_OK; } @@ -549,6 +570,13 @@ static void do_state(struct net_device *dev, /* process state changes depending on the new state */ switch (new_state) { + case CAN_STATE_ERROR_WARNING: + netdev_dbg(dev, "Error Warning\n"); + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = (bec.txerr > bec.rxerr) ? + CAN_ERR_CRTL_TX_WARNING : + CAN_ERR_CRTL_RX_WARNING; + break; case CAN_STATE_ERROR_ACTIVE: netdev_dbg(dev, "Error Active\n"); cf->can_id |= CAN_ERR_PROT; @@ -737,6 +765,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) stats->tx_bytes += can_get_echo_skb(dev, 0); stats->tx_packets++; can_led_event(dev, CAN_LED_EVENT_TX); + /* after sending a RTR frame mailbox is in RX mode */ + flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, + ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); netif_wake_queue(dev); } @@ -794,6 +825,7 @@ static int flexcan_chip_start(struct net_device *dev) struct flexcan_regs __iomem *regs = priv->base; int err; u32 reg_mcr, reg_ctrl; + int i; /* enable module */ err = flexcan_chip_enable(priv); @@ -852,14 +884,26 @@ static int flexcan_chip_start(struct net_device *dev) if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; + else + reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK; /* save for later use */ priv->reg_ctrl_default = reg_ctrl; netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); flexcan_write(reg_ctrl, ®s->ctrl); - /* Abort any pending TX, mark Mailbox as INACTIVE */ - flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), + /* clear and invalidate all mailboxes first */ + for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->cantxfg); i++) { + flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE, + ®s->cantxfg[i].can_ctrl); + } + + /* Errata ERR005829: mark first TX mailbox as INACTIVE */ + flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, + ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl); + + /* mark TX mailbox as INACTIVE */ + flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); /* acceptance mask/acceptance code (accept everything) */ diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index 7a85590fefb9..e5fac368068a 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c @@ -70,6 +70,8 @@ struct peak_pci_chan { #define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */ #define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */ #define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */ +#define PEAK_PCIE_OEM_ID 0x0009 /* PCAN-PCI Express OEM */ +#define PEAK_PCIEC34_DEVICE_ID 0x000A /* PCAN-PCI Express 34 (one channel) */ #define PEAK_PCI_CHAN_MAX 4 @@ -87,6 +89,7 @@ static const struct pci_device_id peak_pci_tbl[] = { {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, #ifdef CONFIG_CAN_PEAK_PCIEC {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PEAK_PCIEC34_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, #endif {0,} }; @@ -653,7 +656,8 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * This must be done *before* register_sja1000dev() but * *after* devices linkage */ - if (pdev->device == PEAK_PCIEC_DEVICE_ID) { + if (pdev->device == PEAK_PCIEC_DEVICE_ID || + pdev->device == PEAK_PCIEC34_DEVICE_ID) { err = peak_pciec_probe(pdev, dev); if (err) { dev_err(&pdev->dev, diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index d1692154ed1b..b27ac6074afb 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev) netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); } +/* + * initialize SJA1000 chip: + * - reset chip + * - set output mode + * - set baudrate + * - enable interrupts + * - start operating mode + */ +static void chipset_init(struct net_device *dev) +{ + struct sja1000_priv *priv = netdev_priv(dev); + + /* set clock divider and output control register */ + priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); + + /* set acceptance filter (accept all) */ + priv->write_reg(priv, SJA1000_ACCC0, 0x00); + priv->write_reg(priv, SJA1000_ACCC1, 0x00); + priv->write_reg(priv, SJA1000_ACCC2, 0x00); + priv->write_reg(priv, SJA1000_ACCC3, 0x00); + + priv->write_reg(priv, SJA1000_ACCM0, 0xFF); + priv->write_reg(priv, SJA1000_ACCM1, 0xFF); + priv->write_reg(priv, SJA1000_ACCM2, 0xFF); + priv->write_reg(priv, SJA1000_ACCM3, 0xFF); + + priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); +} + static void sja1000_start(struct net_device *dev) { struct sja1000_priv *priv = netdev_priv(dev); @@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev) if (priv->can.state != CAN_STATE_STOPPED) set_reset_mode(dev); + /* Initialize chip if uninitialized at this stage */ + if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN)) + chipset_init(dev); + /* Clear error counters and error code capture */ priv->write_reg(priv, SJA1000_TXERR, 0x0); priv->write_reg(priv, SJA1000_RXERR, 0x0); @@ -237,35 +270,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev, } /* - * initialize SJA1000 chip: - * - reset chip - * - set output mode - * - set baudrate - * - enable interrupts - * - start operating mode - */ -static void chipset_init(struct net_device *dev) -{ - struct sja1000_priv *priv = netdev_priv(dev); - - /* set clock divider and output control register */ - priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); - - /* set acceptance filter (accept all) */ - priv->write_reg(priv, SJA1000_ACCC0, 0x00); - priv->write_reg(priv, SJA1000_ACCC1, 0x00); - priv->write_reg(priv, SJA1000_ACCC2, 0x00); - priv->write_reg(priv, SJA1000_ACCC3, 0x00); - - priv->write_reg(priv, SJA1000_ACCM0, 0xFF); - priv->write_reg(priv, SJA1000_ACCM1, 0xFF); - priv->write_reg(priv, SJA1000_ACCM2, 0xFF); - priv->write_reg(priv, SJA1000_ACCM3, 0xFF); - - priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); -} - -/* * transmit a CAN message * message layout in the sk_buff should be like this: * xx xx xx xx ff ll 00 11 22 33 44 55 66 77 |