R-Car has a combined interrupt line, ch22 = Line0_DiA | Line1_A | Line2_A. RZ/V2M has separate interrupt lines for each of these, so add a feature that allows the driver to get these interrupts and call the common handler. Signed-off-by: Phil Edworthy <phil.edworthy@xxxxxxxxxxx> Reviewed-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx> ------ v2: - Move err_mgmt_irqs code under multi_irqs - Use dia, line3 irq names instead of ch22, ch24 when using err_mgmt_irqs --- drivers/net/ethernet/renesas/ravb.h | 3 ++ drivers/net/ethernet/renesas/ravb_main.c | 56 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index 0ec8256f7eef..4832beb0bddc 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -1028,6 +1028,7 @@ struct ravb_hw_info { unsigned carrier_counters:1; /* E-MAC has carrier counters */ unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */ unsigned irq_en_dis_regs:1; /* Has separate irq enable and disable regs */ + unsigned err_mgmt_irqs:1; /* Line1 (Err) and Line2 (Mgmt) irqs are separate */ unsigned gptp:1; /* AVB-DMAC has gPTP support */ unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */ unsigned nc_queues:1; /* AVB-DMAC has RX and TX NC queues */ @@ -1078,6 +1079,8 @@ struct ravb_private { int msg_enable; int speed; int emac_irq; + int erra_irq; + int mgmta_irq; int rx_irqs[NUM_RX_QUEUE]; int tx_irqs[NUM_TX_QUEUE]; diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 5f45c8d68f11..d1e1ced33a08 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1798,12 +1798,23 @@ static int ravb_open(struct net_device *ndev) ndev, dev, "ch19:tx_nc"); if (error) goto out_free_irq_nc_rx; + + if (info->err_mgmt_irqs) { + error = ravb_hook_irq(priv->erra_irq, ravb_multi_interrupt, + ndev, dev, "err_a"); + if (error) + goto out_free_irq_nc_tx; + error = ravb_hook_irq(priv->mgmta_irq, ravb_multi_interrupt, + ndev, dev, "mgmt_a"); + if (error) + goto out_free_irq_erra; + } } /* Device init */ error = ravb_dmac_init(ndev); if (error) - goto out_free_irq_nc_tx; + goto out_free_irq_mgmta; ravb_emac_init(ndev); /* Initialise PTP Clock driver */ @@ -1823,9 +1834,15 @@ static int ravb_open(struct net_device *ndev) /* Stop PTP Clock driver */ if (info->gptp) ravb_ptp_stop(ndev); -out_free_irq_nc_tx: +out_free_irq_mgmta: if (!info->multi_irqs) goto out_free_irq; + if (info->err_mgmt_irqs) + free_irq(priv->mgmta_irq, ndev); +out_free_irq_erra: + if (info->err_mgmt_irqs) + free_irq(priv->erra_irq, ndev); +out_free_irq_nc_tx: free_irq(priv->tx_irqs[RAVB_NC], ndev); out_free_irq_nc_rx: free_irq(priv->rx_irqs[RAVB_NC], ndev); @@ -2166,6 +2183,10 @@ static int ravb_close(struct net_device *ndev) free_irq(priv->tx_irqs[RAVB_BE], ndev); free_irq(priv->rx_irqs[RAVB_BE], ndev); free_irq(priv->emac_irq, ndev); + if (info->err_mgmt_irqs) { + free_irq(priv->erra_irq, ndev); + free_irq(priv->mgmta_irq, ndev); + } } free_irq(ndev->irq, ndev); @@ -2595,10 +2616,14 @@ static int ravb_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - if (info->multi_irqs) - irq = platform_get_irq_byname(pdev, "ch22"); - else + if (info->multi_irqs) { + if (info->err_mgmt_irqs) + irq = platform_get_irq_byname(pdev, "dia"); + else + irq = platform_get_irq_byname(pdev, "ch22"); + } else { irq = platform_get_irq(pdev, 0); + } if (irq < 0) { error = irq; goto out_release; @@ -2640,7 +2665,10 @@ static int ravb_probe(struct platform_device *pdev) of_property_read_bool(np, "renesas,ether-link-active-low"); if (info->multi_irqs) { - irq = platform_get_irq_byname(pdev, "ch24"); + if (info->err_mgmt_irqs) + irq = platform_get_irq_byname(pdev, "line3"); + else + irq = platform_get_irq_byname(pdev, "ch24"); if (irq < 0) { error = irq; goto out_release; @@ -2662,6 +2690,22 @@ static int ravb_probe(struct platform_device *pdev) } priv->tx_irqs[i] = irq; } + + if (info->err_mgmt_irqs) { + irq = platform_get_irq_byname(pdev, "err_a"); + if (irq < 0) { + error = irq; + goto out_release; + } + priv->erra_irq = irq; + + irq = platform_get_irq_byname(pdev, "mgmt_a"); + if (irq < 0) { + error = irq; + goto out_release; + } + priv->mgmta_irq = irq; + } } priv->clk = devm_clk_get(&pdev->dev, NULL); -- 2.32.0