From e49f886ed1e99f52d026c0d4e0acc94477dd1ad9 Mon Sep 17 00:00:00 2001
From: Grygorii Strashko <grygorii.strashko@ti.com>
Date: Thu, 29 Apr 2021 18:13:37 +0300
Subject: [PATCH] net: ethernet: ti: icss_iep: request cmp_cap irq from probe

The current INTC design allows to define IEP cmp_cap IRQ explicitly for IEP
device, so it can be requested from probe and do not have dependencies from
FW any more.

So move IEP cmp_cap IRQ request in probe.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/net/ethernet/ti/icss_iep.c | 42 ++++++++++++++----------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c
index 8bad9c86775a..df74b5fd17e9 100644
--- a/drivers/net/ethernet/ti/icss_iep.c
+++ b/drivers/net/ethernet/ti/icss_iep.c
@@ -759,7 +759,6 @@ struct icss_iep *icss_iep_get(struct device_node *np)
 	struct platform_device *pdev;
 	struct device_node *iep_np;
 	struct icss_iep *iep;
-	int ret;
 
 	iep_np = of_parse_phandle(np, "iep", 0);
 	if (!iep_np || !of_device_is_available(iep_np))
@@ -787,20 +786,6 @@ struct icss_iep *icss_iep_get(struct device_node *np)
 	device_unlock(iep->dev);
 	get_device(iep->dev);
 
-	iep->cap_cmp_irq = of_irq_get_byname(np, "iep_cap_cmp");
-	if (iep->cap_cmp_irq < 0) {
-		iep->cap_cmp_irq = 0;
-	} else {
-		ret = request_irq(iep->cap_cmp_irq, icss_iep_cap_cmp_handler, IRQF_TRIGGER_HIGH,
-				  "iep_cap_cmp", iep);
-		if (ret) {
-			dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret);
-			goto put_iep_device;
-		}
-		hrtimer_init(&iep->sync_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-		iep->sync_timer.function = icss_iep_sync0_work;
-	}
-
 	iep->ptp_info = icss_iep_ptp_info;
 
 
@@ -818,11 +803,6 @@ struct icss_iep *icss_iep_get(struct device_node *np)
 
 exit:
 	return iep;
-
-put_iep_device:
-	put_device(iep->dev);
-
-	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(icss_iep_get);
 
@@ -832,10 +812,8 @@ void icss_iep_put(struct icss_iep *iep)
 	iep->client_np = NULL;
 	device_unlock(iep->dev);
 	put_device(iep->dev);
-	if (iep->cap_cmp_irq) {
-		free_irq(iep->cap_cmp_irq, iep);
+	if (iep->cap_cmp_irq)
 		hrtimer_cancel(&iep->sync_timer);
-	}
 }
 EXPORT_SYMBOL_GPL(icss_iep_put);
 
@@ -901,6 +879,7 @@ static int icss_iep_probe(struct platform_device *pdev)
 	struct icss_iep *iep;
 	struct resource *res;
 	struct clk *iep_clk;
+	int ret;
 
 	iep = devm_kzalloc(dev, sizeof(*iep), GFP_KERNEL);
 	if (!iep)
@@ -912,6 +891,23 @@ static int icss_iep_probe(struct platform_device *pdev)
 	if (IS_ERR(iep->base))
 		return -ENODEV;
 
+	iep->cap_cmp_irq = platform_get_irq_byname_optional(pdev, "iep_cap_cmp");
+	if (iep->cap_cmp_irq < 0) {
+		if (iep->cap_cmp_irq == -EPROBE_DEFER)
+			return iep->cap_cmp_irq;
+		iep->cap_cmp_irq = 0;
+	} else {
+		ret = devm_request_irq(dev, iep->cap_cmp_irq,
+				       icss_iep_cap_cmp_handler, IRQF_TRIGGER_HIGH,
+				       "iep_cap_cmp", iep);
+		if (ret) {
+			dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret);
+			return ret;
+		}
+		hrtimer_init(&iep->sync_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		iep->sync_timer.function = icss_iep_sync0_work;
+	}
+
 	iep_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(iep_clk))
 		return PTR_ERR(iep_clk);
