2014-04-24 5:16 GMT+08:00 Linus Walleij <linus.wall...@linaro.org>: > This rewrites the SIRF pinctrl driver to allocate a state container > for the GPIO chip, just as is done for the pin controller, and > use the gpiochip_add_pin_range() to add the range from the gpiochip > side rather than adding the range from the pinctrl side. > > All resulting changes are done in order to pass around a state > container rather than refer to a static global object. > > Signed-off-by: Linus Walleij <linus.wall...@linaro.org>
Linus, thanks! but this breaks prima2 pinctrl subsystem, do you have an idea? otherwise i will do a debug to find the reason. [ 1.371699] ------------[ cut here ]------------ [ 1.376028] WARNING: CPU: 0 PID: 1 at drivers/gpio/gpiolib.c:159 gpio_to_desc+0x38/0x40() [ 1.388395] invalid GPIO -517 [ 1.391239] Modules linked in: [ 1.394284] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 3.14.0 #4 [ 1.401153] [<c0015c7c>] (unwind_backtrace) from [<c0011da8>] (show_stack+0x10/0x14) [ 1.408899] [<c0011da8>] (show_stack) from [<c0378920>] (dump_stack+0x98/0xd0) [ 1.416105] [<c0378920>] (dump_stack) from [<c0021ee4>] (warn_slowpath_common+0x6c/0x88) [ 1.424157] [<c0021ee4>] (warn_slowpath_common) from [<c0021f30>] (warn_slowpath_fmt+0x30/0x40) [ 1.432804] [<c0021f30>] (warn_slowpath_fmt) from [<c01d2b00>] (gpio_to_desc+0x38/0x40) [ 1.440812] [<c01d2b00>] (gpio_to_desc) from [<c01d4f9c>] (gpio_request_one+0xc/0xc8) [ 1.448614] [<c01d4f9c>] (gpio_request_one) from [<c01d28b4>] (devm_gpio_request_one+0x40/0x78) [ 1.457289] [<c01d28b4>] (devm_gpio_request_one) from [<c02b3e54>] (gpio_extcon_probe+0xa4/0x1d4) [ 1.466138] [<c02b3e54>] (gpio_extcon_probe) from [<c023f8b8>] (platform_drv_probe+0x18/0x48) [ 1.474637] [<c023f8b8>] (platform_drv_probe) from [<c023e004>] (driver_probe_device+0x120/0x238) [ 1.483465] [<c023e004>] (driver_probe_device) from [<c023c6d0>] (bus_for_each_drv+0x58/0x8c) [ 1.491987] [<c023c6d0>] (bus_for_each_drv) from [<c023deb0>] (device_attach+0x74/0x88) [ 1.499967] [<c023deb0>] (device_attach) from [<c023d55c>] (bus_probe_device+0x84/0xa8) [ 1.507948] [<c023d55c>] (bus_probe_device) from [<c023bae0>] (device_add+0x440/0x520) [ 1.515840] [<c023bae0>] (device_add) from [<c023f630>] (platform_device_add+0xb4/0x214) [ 1.523886] [<c023f630>] (platform_device_add) from [<c023fbd4>] (platform_device_register_full+0xb8/0xdc) [ 1.533538] [<c023fbd4>] (platform_device_register_full) from [<c04cad00>] (sirfsoc_init_late+0xec/0xf4) [ 1.542996] [<c04cad00>] (sirfsoc_init_late) from [<c04c649c>] (init_machine_late+0x20/0x28) [ 1.551412] [<c04c649c>] (init_machine_late) from [<c000895c>] (do_one_initcall+0xf8/0x144) [ 1.559737] [<c000895c>] (do_one_initcall) from [<c04c4c54>] (kernel_init_freeable+0x13c/0x1dc) [ 1.568414] [<c04c4c54>] (kernel_init_freeable) from [<c0373a5c>] (kernel_init+0xc/0xe8) [ 1.576483] [<c0373a5c>] (kernel_init) from [<c000e4f8>] (ret_from_fork+0x14/0x3c) [ 1.584038] ---[ end trace c66a899979023402 ]--- [ 1.588591] gpiod_request: invalid GPIO [ 1.592425] extcon-gpio: probe of extcon-gpio failed with error -22 > --- > drivers/pinctrl/sirf/pinctrl-sirf.c | 216 > ++++++++++++++++++++---------------- > 1 file changed, 122 insertions(+), 94 deletions(-) > > diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c > b/drivers/pinctrl/sirf/pinctrl-sirf.c > index c03dcc7729eb..0613e0c77e8a 100644 > --- a/drivers/pinctrl/sirf/pinctrl-sirf.c > +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c > @@ -42,7 +42,6 @@ struct sirfsoc_gpio_chip { > struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; > }; > > -static struct sirfsoc_gpio_chip sgpio_chip; > static DEFINE_SPINLOCK(sgpio_lock); > > static struct sirfsoc_pin_group *sirfsoc_pin_groups; > @@ -255,17 +254,6 @@ static struct pinctrl_desc sirfsoc_pinmux_desc = { > .owner = THIS_MODULE, > }; > > -/* > - * Todo: bind irq_chip to every pinctrl_gpio_range > - */ > -static struct pinctrl_gpio_range sirfsoc_gpio_ranges = { > - .name = "sirfsoc-gpio*", > - .id = 0, > - .base = 0, > - .pin_base = 0, > - .npins = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS, > -}; > - > static void __iomem *sirfsoc_rsc_of_iomap(void) > { > const struct of_device_id rsc_ids[] = { > @@ -289,9 +277,6 @@ static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, > if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * > SIRFSOC_GPIO_BANK_SIZE) > return -EINVAL; > > - if (gc != &sgpio_chip.chip.gc) > - return -EINVAL; > - > if (flags) > *flags = gpiospec->args[1]; > > @@ -354,9 +339,6 @@ static int sirfsoc_pinmux_probe(struct platform_device > *pdev) > goto out_no_pmx; > } > > - sirfsoc_gpio_ranges.gc = &sgpio_chip.chip.gc; > - pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges); > - > dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); > > return 0; > @@ -441,20 +423,28 @@ static int __init sirfsoc_pinmux_init(void) > } > arch_initcall(sirfsoc_pinmux_init); > > -static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int > gpio) > +static inline struct sirfsoc_gpio_chip *to_sirfsoc_gpio(struct gpio_chip *gc) > { > - return &sgpio_chip.sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; > + return container_of(gc, struct sirfsoc_gpio_chip, chip.gc); > } > > -static inline int sirfsoc_gpio_to_bankoff(unsigned int gpio) > +static inline struct sirfsoc_gpio_bank * > +sirfsoc_gpio_to_bank(struct sirfsoc_gpio_chip *sgpio, unsigned int offset) > { > - return gpio % SIRFSOC_GPIO_BANK_SIZE; > + return &sgpio->sgpio_bank[offset / SIRFSOC_GPIO_BANK_SIZE]; > +} > + > +static inline int sirfsoc_gpio_to_bankoff(unsigned int offset) > +{ > + return offset % SIRFSOC_GPIO_BANK_SIZE; > } > > static void sirfsoc_gpio_irq_ack(struct irq_data *d) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); > - int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; > + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, > d->hwirq); > + int idx = sirfsoc_gpio_to_bankoff(d->hwirq); > u32 val, offset; > unsigned long flags; > > @@ -462,14 +452,16 @@ static void sirfsoc_gpio_irq_ack(struct irq_data *d) > > spin_lock_irqsave(&sgpio_lock, flags); > > - val = readl(sgpio_chip.chip.regs + offset); > + val = readl(sgpio->chip.regs + offset); > > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > > spin_unlock_irqrestore(&sgpio_lock, flags); > } > > -static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_bank *bank, int idx) > +static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, > + struct sirfsoc_gpio_bank *bank, > + int idx) > { > u32 val, offset; > unsigned long flags; > @@ -478,25 +470,29 @@ static void __sirfsoc_gpio_irq_mask(struct > sirfsoc_gpio_bank *bank, int idx) > > spin_lock_irqsave(&sgpio_lock, flags); > > - val = readl(sgpio_chip.chip.regs + offset); > + val = readl(sgpio->chip.regs + offset); > val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; > val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > > spin_unlock_irqrestore(&sgpio_lock, flags); > } > > static void sirfsoc_gpio_irq_mask(struct irq_data *d) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); > + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, > d->hwirq); > > - __sirfsoc_gpio_irq_mask(bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); > + __sirfsoc_gpio_irq_mask(sgpio, bank, d->hwirq % > SIRFSOC_GPIO_BANK_SIZE); > } > > static void sirfsoc_gpio_irq_unmask(struct irq_data *d) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); > - int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; > + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, > d->hwirq); > + int idx = sirfsoc_gpio_to_bankoff(d->hwirq); > u32 val, offset; > unsigned long flags; > > @@ -504,18 +500,20 @@ static void sirfsoc_gpio_irq_unmask(struct irq_data *d) > > spin_lock_irqsave(&sgpio_lock, flags); > > - val = readl(sgpio_chip.chip.regs + offset); > + val = readl(sgpio->chip.regs + offset); > val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; > val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > > spin_unlock_irqrestore(&sgpio_lock, flags); > } > > static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); > - int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; > + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, > d->hwirq); > + int idx = sirfsoc_gpio_to_bankoff(d->hwirq); > u32 val, offset; > unsigned long flags; > > @@ -523,7 +521,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, > unsigned type) > > spin_lock_irqsave(&sgpio_lock, flags); > > - val = readl(sgpio_chip.chip.regs + offset); > + val = readl(sgpio->chip.regs + offset); > val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | > SIRFSOC_GPIO_CTL_OUT_EN_MASK); > > switch (type) { > @@ -551,7 +549,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, > unsigned type) > break; > } > > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > > spin_unlock_irqrestore(&sgpio_lock, flags); > > @@ -568,6 +566,8 @@ static struct irq_chip sirfsoc_irq_chip = { > > static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) > { > + struct gpio_chip *gc = irq_desc_get_handler_data(desc); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); > struct sirfsoc_gpio_bank *bank; > u32 status, ctrl; > int idx = 0; > @@ -575,7 +575,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, > struct irq_desc *desc) > int i; > > for (i = 0; i < SIRFSOC_GPIO_BANK_SIZE; i++) { > - bank = &sgpio_chip.sgpio_bank[i]; > + bank = &sgpio->sgpio_bank[i]; > if (bank->parent_irq == irq) > break; > } > @@ -583,7 +583,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, > struct irq_desc *desc) > > chained_irq_enter(chip, desc); > > - status = readl(sgpio_chip.chip.regs + > SIRFSOC_GPIO_INT_STATUS(bank->id)); > + status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); > if (!status) { > printk(KERN_WARNING > "%s: gpio id %d status %#x no interrupt is flaged\n", > @@ -593,7 +593,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, > struct irq_desc *desc) > } > > while (status) { > - ctrl = readl(sgpio_chip.chip.regs + > SIRFSOC_GPIO_CTRL(bank->id, idx)); > + ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, > idx)); > > /* > * Here we must check whether the corresponding GPIO's > interrupt > @@ -602,7 +602,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, > struct irq_desc *desc) > if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) > { > pr_debug("%s: gpio id %d idx %d happens\n", > __func__, bank->id, idx); > - > generic_handle_irq(irq_find_mapping(sgpio_chip.chip.gc.irqdomain, idx + > + generic_handle_irq(irq_find_mapping(gc->irqdomain, > idx + > bank->id * SIRFSOC_GPIO_BANK_SIZE)); > } > > @@ -613,18 +613,20 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, > struct irq_desc *desc) > chained_irq_exit(chip, desc); > } > > -static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, > unsigned ctrl_offset) > +static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_chip *sgpio, > + unsigned ctrl_offset) > { > u32 val; > > - val = readl(sgpio_chip.chip.regs + ctrl_offset); > + val = readl(sgpio->chip.regs + ctrl_offset); > val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK; > - writel(val, sgpio_chip.chip.regs + ctrl_offset); > + writel(val, sgpio->chip.regs + ctrl_offset); > } > > static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); > unsigned long flags; > > if (pinctrl_request_gpio(chip->base + offset)) > @@ -636,8 +638,8 @@ static int sirfsoc_gpio_request(struct gpio_chip *chip, > unsigned offset) > * default status: > * set direction as input and mask irq > */ > - sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset)); > - __sirfsoc_gpio_irq_mask(bank, offset); > + sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); > + __sirfsoc_gpio_irq_mask(sgpio, bank, offset); > > spin_unlock_irqrestore(&bank->lock, flags); > > @@ -646,13 +648,14 @@ static int sirfsoc_gpio_request(struct gpio_chip *chip, > unsigned offset) > > static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); > unsigned long flags; > > spin_lock_irqsave(&bank->lock, flags); > > - __sirfsoc_gpio_irq_mask(bank, offset); > - sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset)); > + __sirfsoc_gpio_irq_mask(sgpio, bank, offset); > + sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); > > spin_unlock_irqrestore(&bank->lock, flags); > > @@ -661,7 +664,8 @@ static void sirfsoc_gpio_free(struct gpio_chip *chip, > unsigned offset) > > static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned > gpio) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); > int idx = sirfsoc_gpio_to_bankoff(gpio); > unsigned long flags; > unsigned offset; > @@ -670,22 +674,24 @@ static int sirfsoc_gpio_direction_input(struct > gpio_chip *chip, unsigned gpio) > > spin_lock_irqsave(&bank->lock, flags); > > - sirfsoc_gpio_set_input(bank, offset); > + sirfsoc_gpio_set_input(sgpio, offset); > > spin_unlock_irqrestore(&bank->lock, flags); > > return 0; > } > > -static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_bank *bank, > unsigned offset, > - int value) > +static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_chip *sgpio, > + struct sirfsoc_gpio_bank *bank, > + unsigned offset, > + int value) > { > u32 out_ctrl; > unsigned long flags; > > spin_lock_irqsave(&bank->lock, flags); > > - out_ctrl = readl(sgpio_chip.chip.regs + offset); > + out_ctrl = readl(sgpio->chip.regs + offset); > if (value) > out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; > else > @@ -693,14 +699,15 @@ static inline void sirfsoc_gpio_set_output(struct > sirfsoc_gpio_bank *bank, unsig > > out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; > out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK; > - writel(out_ctrl, sgpio_chip.chip.regs + offset); > + writel(out_ctrl, sgpio->chip.regs + offset); > > spin_unlock_irqrestore(&bank->lock, flags); > } > > static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned > gpio, int value) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); > int idx = sirfsoc_gpio_to_bankoff(gpio); > u32 offset; > unsigned long flags; > @@ -709,7 +716,7 @@ static int sirfsoc_gpio_direction_output(struct gpio_chip > *chip, unsigned gpio, > > spin_lock_irqsave(&sgpio_lock, flags); > > - sirfsoc_gpio_set_output(bank, offset, value); > + sirfsoc_gpio_set_output(sgpio, bank, offset, value); > > spin_unlock_irqrestore(&sgpio_lock, flags); > > @@ -718,13 +725,14 @@ static int sirfsoc_gpio_direction_output(struct > gpio_chip *chip, unsigned gpio, > > static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); > u32 val; > unsigned long flags; > > spin_lock_irqsave(&bank->lock, flags); > > - val = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, > offset)); > + val = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); > > spin_unlock_irqrestore(&bank->lock, flags); > > @@ -734,23 +742,25 @@ static int sirfsoc_gpio_get_value(struct gpio_chip > *chip, unsigned offset) > static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, > int value) > { > - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); > + struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); > + struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); > u32 ctrl; > unsigned long flags; > > spin_lock_irqsave(&bank->lock, flags); > > - ctrl = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, > offset)); > + ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); > if (value) > ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; > else > ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; > - writel(ctrl, sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, > offset)); > + writel(ctrl, sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); > > spin_unlock_irqrestore(&bank->lock, flags); > } > > -static void sirfsoc_gpio_set_pullup(const u32 *pullups) > +static void sirfsoc_gpio_set_pullup(struct sirfsoc_gpio_chip *sgpio, > + const u32 *pullups) > { > int i, n; > const unsigned long *p = (const unsigned long *)pullups; > @@ -758,15 +768,16 @@ static void sirfsoc_gpio_set_pullup(const u32 *pullups) > for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { > for_each_set_bit(n, p + i, BITS_PER_LONG) { > u32 offset = SIRFSOC_GPIO_CTRL(i, n); > - u32 val = readl(sgpio_chip.chip.regs + offset); > + u32 val = readl(sgpio->chip.regs + offset); > val |= SIRFSOC_GPIO_CTL_PULL_MASK; > val |= SIRFSOC_GPIO_CTL_PULL_HIGH; > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > } > } > } > > -static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns) > +static void sirfsoc_gpio_set_pulldown(struct sirfsoc_gpio_chip *sgpio, > + const u32 *pulldowns) > { > int i, n; > const unsigned long *p = (const unsigned long *)pulldowns; > @@ -774,10 +785,10 @@ static void sirfsoc_gpio_set_pulldown(const u32 > *pulldowns) > for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { > for_each_set_bit(n, p + i, BITS_PER_LONG) { > u32 offset = SIRFSOC_GPIO_CTRL(i, n); > - u32 val = readl(sgpio_chip.chip.regs + offset); > + u32 val = readl(sgpio->chip.regs + offset); > val |= SIRFSOC_GPIO_CTL_PULL_MASK; > val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; > - writel(val, sgpio_chip.chip.regs + offset); > + writel(val, sgpio->chip.regs + offset); > } > } > } > @@ -785,6 +796,7 @@ static void sirfsoc_gpio_set_pulldown(const u32 > *pulldowns) > static int sirfsoc_gpio_probe(struct device_node *np) > { > int i, err = 0; > + static struct sirfsoc_gpio_chip *sgpio; > struct sirfsoc_gpio_bank *bank; > void __iomem *regs; > struct platform_device *pdev; > @@ -796,6 +808,10 @@ static int sirfsoc_gpio_probe(struct device_node *np) > if (!pdev) > return -ENODEV; > > + sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); > + if (!sgpio) > + return -ENOMEM; > + > regs = of_iomap(np, 0); > if (!regs) > return -ENOMEM; > @@ -803,30 +819,30 @@ static int sirfsoc_gpio_probe(struct device_node *np) > if (of_device_is_compatible(np, "sirf,marco-pinctrl")) > is_marco = 1; > > - sgpio_chip.chip.gc.request = sirfsoc_gpio_request; > - sgpio_chip.chip.gc.free = sirfsoc_gpio_free; > - sgpio_chip.chip.gc.direction_input = sirfsoc_gpio_direction_input; > - sgpio_chip.chip.gc.get = sirfsoc_gpio_get_value; > - sgpio_chip.chip.gc.direction_output = sirfsoc_gpio_direction_output; > - sgpio_chip.chip.gc.set = sirfsoc_gpio_set_value; > - sgpio_chip.chip.gc.base = 0; > - sgpio_chip.chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * > SIRFSOC_GPIO_NO_OF_BANKS; > - sgpio_chip.chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); > - sgpio_chip.chip.gc.of_node = np; > - sgpio_chip.chip.gc.of_xlate = sirfsoc_gpio_of_xlate; > - sgpio_chip.chip.gc.of_gpio_n_cells = 2; > - sgpio_chip.chip.gc.dev = &pdev->dev; > - sgpio_chip.chip.regs = regs; > - sgpio_chip.is_marco = is_marco; > - > - err = gpiochip_add(&sgpio_chip.chip.gc); > + sgpio->chip.gc.request = sirfsoc_gpio_request; > + sgpio->chip.gc.free = sirfsoc_gpio_free; > + sgpio->chip.gc.direction_input = sirfsoc_gpio_direction_input; > + sgpio->chip.gc.get = sirfsoc_gpio_get_value; > + sgpio->chip.gc.direction_output = sirfsoc_gpio_direction_output; > + sgpio->chip.gc.set = sirfsoc_gpio_set_value; > + sgpio->chip.gc.base = 0; > + sgpio->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * > SIRFSOC_GPIO_NO_OF_BANKS; > + sgpio->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); > + sgpio->chip.gc.of_node = np; > + sgpio->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; > + sgpio->chip.gc.of_gpio_n_cells = 2; > + sgpio->chip.gc.dev = &pdev->dev; > + sgpio->chip.regs = regs; > + sgpio->is_marco = is_marco; > + > + err = gpiochip_add(&sgpio->chip.gc); > if (err) { > dev_err(&pdev->dev, "%s: error in probe function with status > %d\n", > np->full_name, err); > goto out; > } > > - err = gpiochip_irqchip_add(&sgpio_chip.chip.gc, > + err = gpiochip_irqchip_add(&sgpio->chip.gc, > &sirfsoc_irq_chip, > 0, handle_level_irq, > IRQ_TYPE_NONE); > @@ -837,30 +853,42 @@ static int sirfsoc_gpio_probe(struct device_node *np) > } > > for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { > - bank = &sgpio_chip.sgpio_bank[i]; > + bank = &sgpio->sgpio_bank[i]; > spin_lock_init(&bank->lock); > bank->parent_irq = platform_get_irq(pdev, i); > if (bank->parent_irq < 0) { > err = bank->parent_irq; > - goto out; > + goto out_banks; > } > > - gpiochip_set_chained_irqchip(&sgpio_chip.chip.gc, > + gpiochip_set_chained_irqchip(&sgpio->chip.gc, > &sirfsoc_irq_chip, > bank->parent_irq, > sirfsoc_gpio_handle_irq); > } > > + err = gpiochip_add_pin_range(&sgpio->chip.gc, "sirfsoc-gpio*", > + 0, 0, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS); > + if (err) { > + dev_err(&pdev->dev, > + "could not add gpiochip pin range\n"); > + goto out_no_range; > + } > + > if (!of_property_read_u32_array(np, "sirf,pullups", pullups, > SIRFSOC_GPIO_NO_OF_BANKS)) > - sirfsoc_gpio_set_pullup(pullups); > + sirfsoc_gpio_set_pullup(sgpio, pullups); > > if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns, > SIRFSOC_GPIO_NO_OF_BANKS)) > - sirfsoc_gpio_set_pulldown(pulldowns); > + sirfsoc_gpio_set_pulldown(sgpio, pulldowns); > > return 0; > > +out_no_range: > +out_banks: > + if (gpiochip_remove(&sgpio->chip.gc)) > + dev_err(&pdev->dev, "could not remove gpio chip\n"); > out: > iounmap(regs); > return err; > -- > 1.9.0 > -barry -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/