--- linux-4.9.37/drivers/gpio/gpio-pl061.c 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/gpio/gpio-pl061.c 2021-06-07 13:01:33.000000000 +0300 @@ -208,6 +208,25 @@ return 0; } +#ifdef CONFIG_ARCH_GOKE +static irqreturn_t pl061_irq_handler(int irq, void *data) +{ + unsigned long pending; + int offset; + struct gpio_chip *gc = data; + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); + + pending = readb(chip->base + GPIOMIS); + writeb(pending, chip->base + GPIOIC); + if (pending) { + for_each_set_bit(offset, &pending, PL061_GPIO_NR) + generic_handle_irq(irq_find_mapping(gc->irqdomain, + offset)); + } + + return IRQ_HANDLED; +} +#else static void pl061_irq_handler(struct irq_desc *desc) { unsigned long pending; @@ -227,6 +246,7 @@ chained_irq_exit(irqchip, desc); } +#endif static void pl061_irq_mask(struct irq_data *d) { @@ -308,7 +328,17 @@ return -ENODEV; } } else { +#ifdef CONFIG_ARCH_GOKE + if (dev->of_node) { + i = of_alias_get_id(dev->of_node, "gpio"); + chip->gc.base = i * PL061_GPIO_NR; + } + + if (chip->gc.base < 0) + chip->gc.base = -1; +#else chip->gc.base = -1; +#endif irq_base = 0; } @@ -353,8 +383,21 @@ dev_info(&adev->dev, "could not add irqchip\n"); return ret; } +#ifdef CONFIG_ARCH_GOKE + ret = devm_request_irq(dev, irq, pl061_irq_handler, IRQF_SHARED, + dev_name(dev), &chip->gc); + if (ret) { + dev_info(dev, "request irq failed: %d\n", ret); + return ret; + } + + /* Set the parent IRQ for all affected IRQs */ + for (i = 0; i < chip->gc.ngpio; i++) + irq_set_parent(irq_find_mapping(chip->gc.irqdomain, i), irq); +#else gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip, irq, pl061_irq_handler); +#endif for (i = 0; i < PL061_GPIO_NR; i++) { if (pdata) {