Message ID | 1403163973-48239-1-git-send-email-B45475@freescale.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On 06/19/2014 09:46 AM, Zhao Qiang wrote: > when flexcan is not physically linked, command 'cantest' will > trigger an err_irq, add err_irq handler for it. > > Signed-off-by: Zhao Qiang <B45475@freescale.com> > --- > drivers/net/can/flexcan.c | 31 ++++++++++++++++++++++++++++++- > 1 file changed, 30 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c > index aaed97b..e3c6cfd 100644 > --- a/drivers/net/can/flexcan.c > +++ b/drivers/net/can/flexcan.c > @@ -206,6 +206,7 @@ struct flexcan_priv { > void __iomem *base; > u32 reg_esr; > u32 reg_ctrl_default; > + unsigned int err_irq; Please use a space instead of a tab before err_irq. > > struct clk *clk_ipg; > struct clk *clk_per; > @@ -654,6 +655,23 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) > return IRQ_HANDLED; > } > > +static irqreturn_t flexcan_err_irq(int irq, void *dev_id) > +{ > + struct net_device *dev = dev_id; > + struct flexcan_priv *priv = netdev_priv(dev); > + struct flexcan_regs __iomem *regs = priv->base; > + u32 reg_ctrl, reg_esr; > + > + reg_esr = flexcan_read(®s->esr); > + reg_ctrl = flexcan_read(®s->ctrl); > + if (reg_esr & FLEXCAN_ESR_TX_WRN) { > + flexcan_write(reg_esr & ~FLEXCAN_ESR_TX_WRN, ®s->esr); > + flexcan_write(reg_ctrl & ~FLEXCAN_CTRL_ERR_MSK, ®s->ctrl); > + netdev_err(dev, "No physical link!\n"); A warning IRQ does not imply that you have no physical link. I suggest to make use of the existing flexcan_poll_state() function. > + } > + return IRQ_HANDLED; > +} > + > static void flexcan_set_bittiming(struct net_device *dev) > { > const struct flexcan_priv *priv = netdev_priv(dev); > @@ -860,6 +878,12 @@ static int flexcan_open(struct net_device *dev) > if (err) > goto out_close; > > + if (priv->err_irq) > + err = request_irq(priv->err_irq, flexcan_err_irq, IRQF_SHARED, > + dev->name, dev); > + if (err) > + goto out_close; > + > /* start chip and queuing */ > err = flexcan_chip_start(dev); > if (err) > @@ -1007,7 +1031,7 @@ static int flexcan_probe(struct platform_device *pdev) > struct resource *mem; > struct clk *clk_ipg = NULL, *clk_per = NULL; > void __iomem *base; > - int err, irq; > + int err, irq, err_irq; > u32 clock_freq = 0; > > if (pdev->dev.of_node) > @@ -1034,6 +1058,10 @@ static int flexcan_probe(struct platform_device *pdev) > if (irq <= 0) > return -ENODEV; > > + err_irq = platform_get_irq(pdev, 1); > + if (err_irq <= 0) > + err_irq = 0; > + > base = devm_ioremap_resource(&pdev->dev, mem); > if (IS_ERR(base)) > return PTR_ERR(base); > @@ -1057,6 +1085,7 @@ static int flexcan_probe(struct platform_device *pdev) > dev->flags |= IFF_ECHO; > > priv = netdev_priv(dev); > + priv->err_irq = err_irq; > priv->can.clock.freq = clock_freq; > priv->can.bittiming_const = &flexcan_bittiming_const; > priv->can.do_set_mode = flexcan_set_mode; > Marc
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index aaed97b..e3c6cfd 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -206,6 +206,7 @@ struct flexcan_priv { void __iomem *base; u32 reg_esr; u32 reg_ctrl_default; + unsigned int err_irq; struct clk *clk_ipg; struct clk *clk_per; @@ -654,6 +655,23 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static irqreturn_t flexcan_err_irq(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->base; + u32 reg_ctrl, reg_esr; + + reg_esr = flexcan_read(®s->esr); + reg_ctrl = flexcan_read(®s->ctrl); + if (reg_esr & FLEXCAN_ESR_TX_WRN) { + flexcan_write(reg_esr & ~FLEXCAN_ESR_TX_WRN, ®s->esr); + flexcan_write(reg_ctrl & ~FLEXCAN_CTRL_ERR_MSK, ®s->ctrl); + netdev_err(dev, "No physical link!\n"); + } + return IRQ_HANDLED; +} + static void flexcan_set_bittiming(struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); @@ -860,6 +878,12 @@ static int flexcan_open(struct net_device *dev) if (err) goto out_close; + if (priv->err_irq) + err = request_irq(priv->err_irq, flexcan_err_irq, IRQF_SHARED, + dev->name, dev); + if (err) + goto out_close; + /* start chip and queuing */ err = flexcan_chip_start(dev); if (err) @@ -1007,7 +1031,7 @@ static int flexcan_probe(struct platform_device *pdev) struct resource *mem; struct clk *clk_ipg = NULL, *clk_per = NULL; void __iomem *base; - int err, irq; + int err, irq, err_irq; u32 clock_freq = 0; if (pdev->dev.of_node) @@ -1034,6 +1058,10 @@ static int flexcan_probe(struct platform_device *pdev) if (irq <= 0) return -ENODEV; + err_irq = platform_get_irq(pdev, 1); + if (err_irq <= 0) + err_irq = 0; + base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(base)) return PTR_ERR(base); @@ -1057,6 +1085,7 @@ static int flexcan_probe(struct platform_device *pdev) dev->flags |= IFF_ECHO; priv = netdev_priv(dev); + priv->err_irq = err_irq; priv->can.clock.freq = clock_freq; priv->can.bittiming_const = &flexcan_bittiming_const; priv->can.do_set_mode = flexcan_set_mode;
when flexcan is not physically linked, command 'cantest' will trigger an err_irq, add err_irq handler for it. Signed-off-by: Zhao Qiang <B45475@freescale.com> --- drivers/net/can/flexcan.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)