diff mbox series

gpio: xilinx: Check if interrupt is present

Message ID 20180420131223.4854-1-renner@efe-gmbh.de
State New
Headers show
Series gpio: xilinx: Check if interrupt is present | expand

Commit Message

Jens Renner April 20, 2018, 1:12 p.m. UTC
So far, if no interrupt is present, xgpio_irq_setup() was called
nonetheless and did not evaluate a negative return value of
of_irq_to_resource(). This patch checks the DT property
"xlnx,interrupt-present". If no interrupt output exists, do not call the
function xgpio_irq_setup(). Additionally, if of_irq_to_resource() returns
-EINVAL because no valid interrupt resource was found in the device node,
treat it like no IRQ is connected. This way, it will neither try to
allocate a non-existing IRQ, nor fail to register the GPIO because of it.

Signed-off-by: Jens Renner <renner@efe-gmbh.de>
---
 drivers/gpio/gpio-xilinx.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 9ecd7a78f..bcdfde1b1 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -433,11 +433,15 @@  static int xgpio_irq_setup(struct device_node *np, struct xgpio_instance *chip)
 	u32 pin_num;
 	struct resource res;
 
+	/* Returns 0 or -EINVAL if no valid interrupt resource exists. */
 	int ret = of_irq_to_resource(np, 0, &res);
 
-	if (!ret) {
-		pr_info("GPIO IRQ not connected\n");
+	if (!ret || (ret == -EINVAL)) {
+		pr_warn("GPIO IRQ not connected: %d\n", ret);
 		return 0;
+	} else if (ret < 0) {
+		pr_err("Couldn't get IRQ resource\n");
+		return ret;
 	}
 
 	chip->mmchip.gc.to_irq = xgpio_to_irq;
@@ -586,6 +590,7 @@  static int xgpio_of_probe(struct platform_device *pdev)
 	const u32 *tree_info;
 	u32 ngpio;
 	u32 cells = 2;
+	bool has_int = false;
 
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
@@ -663,11 +668,17 @@  static int xgpio_of_probe(struct platform_device *pdev)
 		goto err_pm_put;
 	}
 
-	status = xgpio_irq_setup(np, chip);
-	if (status) {
-		pr_err("%s: GPIO IRQ initialization failed %d\n",
-		       np->full_name, status);
-		goto err_pm_put;
+	/* Check if interrupt output is present. */
+	tree_info = of_get_property(np, "xlnx,interrupt-present", NULL);
+	has_int = (tree_info && be32_to_cpup(tree_info));
+
+	if (has_int) {
+		status = xgpio_irq_setup(np, chip);
+		if (status) {
+			pr_err("%s: GPIO IRQ initialization failed %d\n",
+			       np->full_name, status);
+			goto err_pm_put;
+		}
 	}
 
 	pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
@@ -716,11 +727,13 @@  static int xgpio_of_probe(struct platform_device *pdev)
 
 		chip->mmchip.save_regs = xgpio_save_regs;
 
-		status = xgpio_irq_setup(np, chip);
-		if (status) {
-			pr_err("%s: GPIO IRQ initialization failed %d\n",
-			      np->full_name, status);
-			goto err_pm_put;
+		if (has_int) {
+			status = xgpio_irq_setup(np, chip);
+			if (status) {
+				pr_err("%s: GPIO IRQ initialization failed %d\n",
+				       np->full_name, status);
+				goto err_pm_put;
+			}
 		}
 
 		/* Call the OF gpio helper to setup and register the GPIO dev */