Commit 386aa051 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-v3.12-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull gpio fixes from Linus Walleij:
 "Three GPIO fixes for the v3.12 series:
   - A fix to the Lynxpoint IRQ handler
   - Two late fixes to fallout from the gpiod refactoring"

* tag 'gpio-v3.12-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpiolib: let gpiod_request() return -EPROBE_DEFER
  gpiolib: safer implementation of desc_to_gpio()
  gpio/lynxpoint: check if the interrupt is enabled in IRQ handler
parents 34ec4de4 0204df47
...@@ -248,14 +248,15 @@ static void lp_gpio_irq_handler(unsigned irq, struct irq_desc *desc) ...@@ -248,14 +248,15 @@ static void lp_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
struct lp_gpio *lg = irq_data_get_irq_handler_data(data); struct lp_gpio *lg = irq_data_get_irq_handler_data(data);
struct irq_chip *chip = irq_data_get_irq_chip(data); struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, pin, mask; u32 base, pin, mask;
unsigned long reg, pending; unsigned long reg, ena, pending;
unsigned virq; unsigned virq;
/* check from GPIO controller which pin triggered the interrupt */ /* check from GPIO controller which pin triggered the interrupt */
for (base = 0; base < lg->chip.ngpio; base += 32) { for (base = 0; base < lg->chip.ngpio; base += 32) {
reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
while ((pending = inl(reg))) { while ((pending = (inl(reg) & inl(ena)))) {
pin = __ffs(pending); pin = __ffs(pending);
mask = BIT(pin); mask = BIT(pin);
/* Clear before handling so we don't lose an edge */ /* Clear before handling so we don't lose an edge */
......
...@@ -136,7 +136,7 @@ static struct gpio_desc *gpio_to_desc(unsigned gpio) ...@@ -136,7 +136,7 @@ static struct gpio_desc *gpio_to_desc(unsigned gpio)
*/ */
static int desc_to_gpio(const struct gpio_desc *desc) static int desc_to_gpio(const struct gpio_desc *desc)
{ {
return desc->chip->base + gpio_chip_hwgpio(desc); return desc - &gpio_desc[0];
} }
...@@ -1398,7 +1398,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) ...@@ -1398,7 +1398,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
int status = -EPROBE_DEFER; int status = -EPROBE_DEFER;
unsigned long flags; unsigned long flags;
if (!desc || !desc->chip) { if (!desc) {
pr_warn("%s: invalid GPIO\n", __func__); pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -1406,6 +1406,8 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) ...@@ -1406,6 +1406,8 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
chip = desc->chip; chip = desc->chip;
if (chip == NULL)
goto done;
if (!try_module_get(chip->owner)) if (!try_module_get(chip->owner))
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment