net: ethernet: ti: cpsw: enable cpts irq
authorGrygorii Strashko <grygorii.strashko@ti.com>
Thu, 23 Apr 2020 14:20:22 +0000 (17:20 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 Apr 2020 19:50:21 +0000 (12:50 -0700)
The CPSW misc IRQ need be enabled for CPTS event_pend IRQs processing. This
patch adds corresponding support to CPSW driver.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpsw_new.c
drivers/net/ethernet/ti/cpsw_priv.c
drivers/net/ethernet/ti/cpsw_priv.h

index c2c5bf8..09f98fa 100644 (file)
@@ -1569,6 +1569,12 @@ static int cpsw_probe(struct platform_device *pdev)
                return irq;
        cpsw->irqs_table[1] = irq;
 
+       /* get misc irq*/
+       irq = platform_get_irq(pdev, 3);
+       if (irq <= 0)
+               return irq;
+       cpsw->misc_irq = irq;
+
        /*
         * This may be required here for child devices.
         */
@@ -1703,6 +1709,21 @@ static int cpsw_probe(struct platform_device *pdev)
                goto clean_unregister_netdev_ret;
        }
 
+       if (!cpsw->cpts)
+               goto skip_cpts;
+
+       ret = devm_request_irq(&pdev->dev, cpsw->misc_irq, cpsw_misc_interrupt,
+                              0, dev_name(&pdev->dev), cpsw);
+       if (ret < 0) {
+               dev_err(dev, "error attaching misc irq (%d)\n", ret);
+               goto clean_unregister_netdev_ret;
+       }
+
+       /* Enable misc CPTS evnt_pend IRQ */
+       cpts_set_irqpoll(cpsw->cpts, false);
+       writel(0x10, &cpsw->wr_regs->misc_en);
+
+skip_cpts:
        cpsw_notice(priv, probe,
                    "initialized device (regs %pa, irq %d, pool size %d)\n",
                    &ss_res->start, cpsw->irqs_table[0], descs_pool_size);
index 9209e61..33c8dd6 100644 (file)
@@ -1896,6 +1896,11 @@ static int cpsw_probe(struct platform_device *pdev)
                return irq;
        cpsw->irqs_table[1] = irq;
 
+       irq = platform_get_irq_byname(pdev, "misc");
+       if (irq <= 0)
+               return irq;
+       cpsw->misc_irq = irq;
+
        platform_set_drvdata(pdev, cpsw);
        /* This may be required here for child devices. */
        pm_runtime_enable(dev);
@@ -1975,6 +1980,21 @@ static int cpsw_probe(struct platform_device *pdev)
                goto clean_unregister_netdev;
        }
 
+       if (!cpsw->cpts)
+               goto skip_cpts;
+
+       ret = devm_request_irq(dev, cpsw->misc_irq, cpsw_misc_interrupt,
+                              0, dev_name(&pdev->dev), cpsw);
+       if (ret < 0) {
+               dev_err(dev, "error attaching misc irq (%d)\n", ret);
+               goto clean_unregister_netdev;
+       }
+
+       /* Enable misc CPTS evnt_pend IRQ */
+       cpts_set_irqpoll(cpsw->cpts, false);
+       writel(0x10, &cpsw->wr_regs->misc_en);
+
+skip_cpts:
        ret = cpsw_register_notifiers(cpsw);
        if (ret)
                goto clean_unregister_netdev;
index 0992089..9d098c8 100644 (file)
@@ -114,6 +114,18 @@ irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+irqreturn_t cpsw_misc_interrupt(int irq, void *dev_id)
+{
+       struct cpsw_common *cpsw = dev_id;
+
+       writel(0, &cpsw->wr_regs->misc_en);
+       cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_MISC);
+       cpts_misc_interrupt(cpsw->cpts);
+       writel(0x10, &cpsw->wr_regs->misc_en);
+
+       return IRQ_HANDLED;
+}
+
 int cpsw_tx_mq_poll(struct napi_struct *napi_tx, int budget)
 {
        struct cpsw_common      *cpsw = napi_to_cpsw(napi_tx);
index b8d7b92..bf4e179 100644 (file)
@@ -350,6 +350,7 @@ struct cpsw_common {
        bool                            rx_irq_disabled;
        bool                            tx_irq_disabled;
        u32 irqs_table[IRQ_NUM];
+       int misc_irq;
        struct cpts                     *cpts;
        struct devlink *devlink;
        int                             rx_ch_num, tx_ch_num;
@@ -442,6 +443,7 @@ int cpsw_run_xdp(struct cpsw_priv *priv, int ch, struct xdp_buff *xdp,
                 struct page *page, int port);
 irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id);
 irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id);
+irqreturn_t cpsw_misc_interrupt(int irq, void *dev_id);
 int cpsw_tx_mq_poll(struct napi_struct *napi_tx, int budget);
 int cpsw_tx_poll(struct napi_struct *napi_tx, int budget);
 int cpsw_rx_mq_poll(struct napi_struct *napi_rx, int budget);