[PATCH v3 02/12] gpio: pxa: avoid to use global irq base

Linus Walleij linus.walleij at linaro.org
Thu Feb 21 13:50:19 EST 2013


On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang at linaro.org> wrote:

> Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
> pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
> MMP_GPIO_TO_IRQ().
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang at linaro.org>
(...)
> +++ b/drivers/gpio/gpio-pxa.c
(...)
> -static int irq_base;

Nice!

>  #ifdef CONFIG_OF
> -static struct irq_domain *domain;

Nice!

>  static struct device_node *pxa_gpio_of_node;
>  #endif
>
>  struct pxa_gpio_chip {
>         struct gpio_chip chip;
>         void __iomem    *regbase;
> +       unsigned int    irq_base;

I don't get this.

Just put a struct irq_domain *irqdomain here
instead and let that keep track of the irq_base for you.

> -static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> +static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>  {
> -       return chip->base + offset + irq_base;
> +       struct pxa_gpio_chip *chip = NULL;
> +
> +       chip = container_of(gc, struct pxa_gpio_chip, chip);
> +       return chip->irq_base + offset;

No. Use return irq_create_mapping(chip->irqdomain, offset);

> -int pxa_irq_to_gpio(int irq)
> +int pxa_irq_to_gpio(struct irq_data *d)
>  {
> -       return irq - irq_base;
> +       struct pxa_gpio_chip *chip;
> +       int gpio;
> +
> +       chip = (struct pxa_gpio_chip *)d->domain->host_data;
> +       gpio = d->irq - chip->irq_base + chip->chip.base;

Just d->hwirq + chip->chip.base;

> +static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
> +                             int (*set_wake)(unsigned int, unsigned int))
> +{
> +       int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
> +       struct pxa_gpio_chip *chips;
> +
> +       chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
> +       if (chips == NULL) {
> +               pr_err("%s: failed to allocate GPIO chips\n", __func__);
> +               return -ENOMEM;
> +       }
> +
> +       for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> +               struct gpio_chip *c = &chips[i].chip;
> +
> +               sprintf(chips[i].label, "gpio-%d", i);
> +               chips[i].regbase = gpio_reg_base + BANK_OFF(i);
> +               chips[i].set_wake = set_wake;
> +
> +               c->base  = gpio;
> +               c->label = chips[i].label;
> +
> +               c->direction_input  = pxa_gpio_direction_input;
> +               c->direction_output = pxa_gpio_direction_output;
> +               c->get = pxa_gpio_get;
> +               c->set = pxa_gpio_set;
> +               c->to_irq = pxa_gpio_to_irq;
> +#ifdef CONFIG_OF_GPIO
> +               c->of_node = pxa_gpio_of_node;
> +               c->of_xlate = pxa_gpio_of_xlate;
> +               c->of_gpio_n_cells = 2;
> +#endif
> +
> +               /* number of GPIOs on last bank may be less than 32 */
> +               c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> +
> +               chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
> +               if (chips[i].irq_base < 0)
> +                       return -EINVAL;
> +               if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
> +                                          chips[i].irq_base, 0,
> +                                          &pxa_irq_domain_ops, &chips[i]))

Don't throw irqdomains away! They are for using.
That is why I ask you to store it in the pxa state struct.

Since you obviously do not care which IRQ descriptors you get
from this, just use irq_domain_add_linear(). The descriptors will
then be allocated dynamically when you call irq_create_mapping().

This is not the first time I see irqdomains being created and then
just thrown away, please don't do this.

Yours,
Linus Walleij



More information about the linux-arm-kernel mailing list