[net-next,v4,3/3] net: stmmac: Add driver support for DWMAC5 safety IRQ Support
Commit Message
Add IRQ support to listen HW safety IRQ like ECC,DPP,FSM
fault and print the fault information in the kernel
log.
Signed-off-by: Suraj Jaiswal <quic_jsuraj@quicinc.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 ++
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++++++++++
.../ethernet/stmicro/stmmac/stmmac_platform.c | 9 +++++++++
4 files changed, 30 insertions(+)
@@ -347,6 +347,7 @@ enum request_irq_err {
REQ_IRQ_ERR_SFTY_UE,
REQ_IRQ_ERR_SFTY_CE,
REQ_IRQ_ERR_LPI,
+ REQ_IRQ_ERR_SAFETY,
REQ_IRQ_ERR_WOL,
REQ_IRQ_ERR_MAC,
REQ_IRQ_ERR_NO,
@@ -33,6 +33,7 @@ struct stmmac_resources {
int irq;
int sfty_ce_irq;
int sfty_ue_irq;
+ int safety_common_irq;
int rx_irq[MTL_MAX_RX_QUEUES];
int tx_irq[MTL_MAX_TX_QUEUES];
};
@@ -299,6 +300,7 @@ struct stmmac_priv {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
int sfty_ce_irq;
int sfty_ue_irq;
+ int safety_common_irq;
int rx_irq[MTL_MAX_RX_QUEUES];
int tx_irq[MTL_MAX_TX_QUEUES];
/*irq name */
@@ -3592,6 +3592,10 @@ static void stmmac_free_irq(struct net_device *dev,
if (priv->wol_irq > 0 && priv->wol_irq != dev->irq)
free_irq(priv->wol_irq, dev);
fallthrough;
+ case REQ_IRQ_ERR_SAFETY:
+ if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq)
+ free_irq(priv->safety_common_irq, dev);
+ fallthrough;
case REQ_IRQ_ERR_WOL:
free_irq(dev->irq, dev);
fallthrough;
@@ -3798,6 +3802,18 @@ static int stmmac_request_irq_single(struct net_device *dev)
}
}
+ if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq) {
+ ret = request_irq(priv->safety_common_irq, stmmac_safety_interrupt,
+ 0, "safety", dev);
+ if (unlikely(ret < 0)) {
+ netdev_err(priv->dev,
+ "%s: alloc safety failed %d (error: %d)\n",
+ __func__, priv->safety_common_irq, ret);
+ irq_err = REQ_IRQ_ERR_SAFETY;
+ goto irq_error;
+ }
+ }
+
return 0;
irq_error:
@@ -7464,6 +7480,8 @@ int stmmac_dvr_probe(struct device *device,
priv->lpi_irq = res->lpi_irq;
priv->sfty_ce_irq = res->sfty_ce_irq;
priv->sfty_ue_irq = res->sfty_ue_irq;
+ priv->safety_common_irq = res->safety_common_irq;
+
for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
priv->rx_irq[i] = res->rx_irq[i];
for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
@@ -726,6 +726,15 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
}
+ stmmac_res->safety_common_irq =
+ platform_get_irq_byname_optional(pdev, "safety");
+
+ if (stmmac_res->safety_common_irq < 0) {
+ if (stmmac_res->safety_common_irq == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(&pdev->dev, "IRQ safety IRQ not found\n");
+ }
+
stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
return PTR_ERR_OR_ZERO(stmmac_res->addr);