Hello Nikita, On Wed, 2021-01-27 at 13:46 +0300, Nikita Shubin wrote: > Separate IRQ's setup for port A,B,F. Somehow I don't feel that moving "FIXME" code around makes much sense. Maybe the anticipated conversion to hierarhical IRQ chip will result in a cleanup automatically? > Signed-off-by: Nikita Shubin <nikita.shubin@xxxxxxxxxxx> > --- > drivers/gpio/gpio-ep93xx.c | 104 +++++++++++++++++++++++------------ > -- > 1 file changed, 64 insertions(+), 40 deletions(-) > > diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c > index e4270b4e5f26..b212c007240e 100644 > --- a/drivers/gpio/gpio-ep93xx.c > +++ b/drivers/gpio/gpio-ep93xx.c > @@ -353,6 +353,64 @@ static void ep93xx_init_irq_chips(struct > ep93xx_gpio *epg) > } > } > > +static int ep93xx_gpio_add_ab_irq_chip(struct platform_device *pdev, > + struct gpio_irq_chip *girq, > + unsigned int irq_base) > +{ > + struct device *dev = &pdev->dev; > + int ab_parent_irq = platform_get_irq(pdev, 0); > + > + girq->parent_handler = ep93xx_gpio_ab_irq_handler; > + girq->num_parents = 1; > + girq->parents = devm_kcalloc(dev, girq->num_parents, > + sizeof(*girq->parents), > + GFP_KERNEL); > + if (!girq->parents) > + return -ENOMEM; > + girq->default_type = IRQ_TYPE_NONE; > + girq->handler = handle_level_irq; > + girq->parents[0] = ab_parent_irq; > + girq->first = irq_base; > + > + return 0; > +} > + > +static int ep93xx_gpio_add_f_irq_chip(struct platform_device *pdev, > + struct gpio_irq_chip *girq, > + unsigned int irq_base) > +{ > + int gpio_irq; > + int i; > + struct device *dev = &pdev->dev; > + > + /* > + * FIXME: convert this to use hierarchical IRQ support! > + * this requires fixing the root irqchip to be hierarchical. > + */ > + girq->parent_handler = ep93xx_gpio_f_irq_handler; > + girq->num_parents = 8; > + girq->parents = devm_kcalloc(dev, girq->num_parents, > + sizeof(*girq->parents), > + GFP_KERNEL); > + if (!girq->parents) > + return -ENOMEM; > + /* Pick resources 1..8 for these IRQs */ > + for (i = 0; i < ARRAY_SIZE(girq->parents); i++) { > + girq->parents[i] = platform_get_irq(pdev, i + 1); > + gpio_irq = irq_base + i; > + irq_set_chip_data(gpio_irq, &epg->gc[5]); > + irq_set_chip_and_handler(gpio_irq, > + &ep93xx_gpio_irq_chip, > + handle_level_irq); > + irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); > + } > + girq->default_type = IRQ_TYPE_NONE; > + girq->handler = handle_level_irq; > + girq->first = irq_base; > + > + return 0; > +} > + > static int ep93xx_gpio_add_bank(struct gpio_chip *gc, > struct platform_device *pdev, > struct ep93xx_gpio *epg, > @@ -380,50 +438,16 @@ static int ep93xx_gpio_add_bank(struct > gpio_chip *gc, > } > > if (bank->has_irq) { > - int ab_parent_irq = platform_get_irq(pdev, 0); > - > - girq->parent_handler = ep93xx_gpio_ab_irq_handler; > - girq->num_parents = 1; > - girq->parents = devm_kcalloc(dev, girq->num_parents, > - sizeof(*girq->parents), > - GFP_KERNEL); > - if (!girq->parents) > - return -ENOMEM; > - girq->default_type = IRQ_TYPE_NONE; > - girq->handler = handle_level_irq; > - girq->parents[0] = ab_parent_irq; > - girq->first = bank->irq_base; > + err = ep93xx_gpio_add_ab_irq_chip(pdev, girq, bank- > >irq_base); > + if (err) > + return err; > } > > /* Only bank F has especially funky IRQ handling */ > if (bank->has_hierarchical_irq) { > - int gpio_irq; > - int i; > - > - /* > - * FIXME: convert this to use hierarchical IRQ > support! > - * this requires fixing the root irqchip to be > hierarchical. > - */ > - girq->parent_handler = ep93xx_gpio_f_irq_handler; > - girq->num_parents = 8; > - girq->parents = devm_kcalloc(dev, girq->num_parents, > - sizeof(*girq->parents), > - GFP_KERNEL); > - if (!girq->parents) > - return -ENOMEM; > - /* Pick resources 1..8 for these IRQs */ > - for (i = 0; i < ARRAY_SIZE(girq->parents); i++) { > - girq->parents[i] = platform_get_irq(pdev, i + > 1); > - gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i; > - irq_set_chip_data(gpio_irq, &epg->gc[5]); > - irq_set_chip_and_handler(gpio_irq, > - > &ep93xx_gpio_irq_chip, > - handle_level_irq); > - irq_clear_status_flags(gpio_irq, > IRQ_NOREQUEST); > - } > - girq->default_type = IRQ_TYPE_NONE; > - girq->handler = handle_level_irq; > - girq->first = EP93XX_GPIO_F_IRQ_BASE; > + err = ep93xx_gpio_add_f_irq_chip(pdev, girq, > EP93XX_GPIO_F_IRQ_BASE); > + if (err) > + return err; > } > > return devm_gpiochip_add_data(dev, gc, epg); -- Alexander Sverdlin.