int pxa_last_gpio;
 static int irq_base;
 
-#ifdef CONFIG_OF
-static struct irq_domain *domain;
-static struct device_node *pxa_gpio_of_node;
-#endif
-
 struct pxa_gpio_bank {
        void __iomem    *regbase;
        unsigned long   irq_mask;
        struct device *dev;
        struct gpio_chip chip;
        struct pxa_gpio_bank *banks;
+       struct irq_domain *irqdomain;
 
        int irq0;
        int irq1;
        return ret;
 }
 
-static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+int pxa_irq_to_gpio(int irq)
 {
-       return offset + irq_base;
+       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
+       int irq_gpio0;
+
+       irq_gpio0 = irq_find_mapping(pchip->irqdomain, 0);
+       if (irq_gpio0 > 0)
+               return irq - irq_gpio0;
+
+       return irq_gpio0;
 }
 
-int pxa_irq_to_gpio(int irq)
+static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-       return irq - irq_base;
+       struct pxa_gpio_chip *pchip = chip_to_pxachip(chip);
+
+       return irq_find_mapping(pchip->irqdomain, offset);
 }
 
 static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 #endif
 
 static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio,
-                             void __iomem *regbase)
+                             struct device_node *np, void __iomem *regbase)
 {
        int i, gpio, nbanks = DIV_ROUND_UP(ngpio, 32);
        struct pxa_gpio_bank *bank;
        pchip->chip.to_irq = pxa_gpio_to_irq;
        pchip->chip.ngpio = ngpio;
 #ifdef CONFIG_OF_GPIO
-       pchip->chip.of_node = pxa_gpio_of_node;
+       pchip->chip.of_node = np;
        pchip->chip.of_xlate = pxa_gpio_of_xlate;
        pchip->chip.of_gpio_n_cells = 2;
 #endif
 
 static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
-       int gpio = pxa_irq_to_gpio(d->irq);
+       struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irqd_to_hwirq(d);
        struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio);
        unsigned long gpdr, mask = GPIO_bit(gpio);
 
        return 0;
 }
 
-static void pxa_gpio_demux_handler(struct irq_desc *desc)
+static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d)
 {
        int loop, gpio, n, handled = 0;
        unsigned long gedr;
-       struct irq_chip *chip = irq_desc_get_chip(desc);
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
+       struct pxa_gpio_chip *pchip = d;
        struct pxa_gpio_bank *c;
 
-       chained_irq_enter(chip, desc);
-
        do {
                loop = 0;
                for_each_gpio_bank(gpio, c, pchip) {
                                generic_handle_irq(gpio_to_irq(gpio + n));
                        }
                }
+               handled += loop;
        } while (loop);
 
-       chained_irq_exit(chip, desc);
+       return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d)
+{
+       struct pxa_gpio_chip *pchip = d;
+
+       if (in_irq == pchip->irq0) {
+               generic_handle_irq(gpio_to_irq(0));
+       } else if (in_irq == pchip->irq1) {
+               generic_handle_irq(gpio_to_irq(1));
+       } else {
+               pr_err("%s() unknown irq %d\n", __func__, in_irq);
+               return IRQ_NONE;
+       }
+       return IRQ_HANDLED;
 }
 
 static void pxa_ack_muxed_gpio(struct irq_data *d)
 {
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
-       int gpio = pxa_irq_to_gpio(d->irq);
+       struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irqd_to_hwirq(d);
        void __iomem *base = gpio_bank_base(&pchip->chip, gpio);
 
        writel_relaxed(GPIO_bit(gpio), base + GEDR_OFFSET);
 
 static void pxa_mask_muxed_gpio(struct irq_data *d)
 {
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
-       int gpio = pxa_irq_to_gpio(d->irq);
+       struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irqd_to_hwirq(d);
        struct pxa_gpio_bank *b = gpio_to_pxabank(&pchip->chip, gpio);
        void __iomem *base = gpio_bank_base(&pchip->chip, gpio);
        uint32_t grer, gfer;
 
 static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 {
-       int gpio = pxa_irq_to_gpio(d->irq);
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
+       struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irqd_to_hwirq(d);
 
        if (pchip->set_wake)
                return pchip->set_wake(gpio, on);
 
 static void pxa_unmask_muxed_gpio(struct irq_data *d)
 {
-       struct pxa_gpio_chip *pchip = pxa_gpio_chip;
-       int gpio = pxa_irq_to_gpio(d->irq);
+       struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irqd_to_hwirq(d);
        struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio);
 
        c->irq_mask |= GPIO_bit(gpio);
 {
        irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
                                 handle_edge_irq);
+       irq_set_chip_data(irq, d->host_data);
        irq_set_noprobe(irq);
        return 0;
 }
                             struct pxa_gpio_chip *pchip)
 {
        int nr_gpios;
-       struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *of_id =
                                of_match_device(pxa_gpio_dt_ids, &pdev->dev);
        const struct pxa_gpio_id *gpio_id;
                dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
                return irq_base;
        }
-       domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
-                                      &pxa_irq_domain_ops, pchip);
-       pxa_gpio_of_node = np;
-       return 0;
+       return irq_base;
 }
 #else
 #define pxa_gpio_probe_dt(pdev, pchip)         (-1)
        struct clk *clk;
        struct pxa_gpio_platform_data *info;
        void __iomem *gpio_reg_base;
-       int gpio, irq, ret, use_of = 0;
+       int gpio, ret;
        int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
        pchip = devm_kzalloc(&pdev->dev, sizeof(*pchip), GFP_KERNEL);
                pxa_last_gpio = pxa_gpio_nums(pdev);
                pchip->set_wake = info->gpio_set_wake;
        } else {
-               irq_base = 0;
-               use_of = 1;
-               ret = pxa_gpio_probe_dt(pdev, pchip);
-               if (ret < 0)
+               irq_base = pxa_gpio_probe_dt(pdev, pchip);
+               if (irq_base < 0)
                        return -EINVAL;
        }
 
        if (!pxa_last_gpio)
                return -EINVAL;
 
+       pchip->irqdomain = irq_domain_add_legacy(pdev->dev.of_node,
+                                                pxa_last_gpio + 1, irq_base,
+                                                0, &pxa_irq_domain_ops, pchip);
+       if (IS_ERR(pchip->irqdomain))
+               return PTR_ERR(pchip->irqdomain);
+
        irq0 = platform_get_irq_byname(pdev, "gpio0");
        irq1 = platform_get_irq_byname(pdev, "gpio1");
        irq_mux = platform_get_irq_byname(pdev, "gpio_mux");
        if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0)
                || (irq_mux <= 0))
                return -EINVAL;
+
+       pchip->irq0 = irq0;
+       pchip->irq1 = irq1;
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        gpio_reg_base = devm_ioremap(&pdev->dev, res->start,
                                     resource_size(res));
        }
 
        /* Initialize GPIO chips */
-       ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, gpio_reg_base);
+       ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, pdev->dev.of_node,
+                                gpio_reg_base);
        if (ret) {
                clk_put(clk);
                return ret;
                        writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
        }
 
-       if (!use_of) {
-               if (irq0 > 0) {
-                       irq = gpio_to_irq(0);
-                       irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-                                                handle_edge_irq);
-                       irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
-               }
-               if (irq1 > 0) {
-                       irq = gpio_to_irq(1);
-                       irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-                                                handle_edge_irq);
-                       irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
-               }
-
-               for (irq  = gpio_to_irq(gpio_offset);
-                       irq <= gpio_to_irq(pxa_last_gpio); irq++) {
-                       irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-                                                handle_edge_irq);
-                       irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
-               }
+       if (irq0 > 0) {
+               ret = devm_request_irq(&pdev->dev,
+                                      irq0, pxa_gpio_direct_handler, 0,
+                                      "gpio-0", pchip);
+               if (ret)
+                       dev_err(&pdev->dev, "request of gpio0 irq failed: %d\n",
+                               ret);
        }
+       if (irq1 > 0) {
+               ret = devm_request_irq(&pdev->dev,
+                                      irq1, pxa_gpio_direct_handler, 0,
+                                      "gpio-1", pchip);
+               if (ret)
+                       dev_err(&pdev->dev, "request of gpio1 irq failed: %d\n",
+                               ret);
+       }
+       ret = devm_request_irq(&pdev->dev,
+                              irq_mux, pxa_gpio_demux_handler, 0,
+                                      "gpio-mux", pchip);
+       if (ret)
+               dev_err(&pdev->dev, "request of gpio-mux irq failed: %d\n",
+                               ret);
 
-       if (irq0 > 0)
-               irq_set_chained_handler(irq0, pxa_gpio_demux_handler);
-       if (irq1 > 0)
-               irq_set_chained_handler(irq1, pxa_gpio_demux_handler);
        pxa_gpio_chip = pchip;
 
-       irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
        return 0;
 }