@@ -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 */
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(-)