Skip to content

Commit

Permalink
Merge tag 'gpio-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linusw/linux-gpio

Pull GPIO fix from Linus Walleij:
 "A single lockdep fix, nothing else going on. This makes lockdep
  noiseless and work properly with threaded GPIO IRQchips.

  Summary:

  Fix a lockdep issue: the threaded irqchips also need their unique key,
  and take this opportunity to get rid of the horrible macro and replace
  it with a static inline"

* tag 'gpio-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: provide lockdep keys for nested/unnested irqchips
  • Loading branch information
torvalds committed Jan 23, 2017
2 parents 3258943 + 739e6f5 commit 6302118
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 29 deletions.
18 changes: 9 additions & 9 deletions drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
}

/**
* _gpiochip_irqchip_add() - adds an irqchip to a gpiochip
* gpiochip_irqchip_add_key() - adds an irqchip to a gpiochip
* @gpiochip: the gpiochip to add the irqchip to
* @irqchip: the irqchip to add to the gpiochip
* @first_irq: if not dynamically assigned, the base (first) IRQ to
Expand All @@ -1749,13 +1749,13 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
* the pins on the gpiochip can generate a unique IRQ. Everything else
* need to be open coded.
*/
int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type,
bool nested,
struct lock_class_key *lock_key)
int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type,
bool nested,
struct lock_class_key *lock_key)
{
struct device_node *of_node;
bool irq_base_set = false;
Expand Down Expand Up @@ -1840,7 +1840,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,

return 0;
}
EXPORT_SYMBOL_GPL(_gpiochip_irqchip_add);
EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key);

#else /* CONFIG_GPIOLIB_IRQCHIP */

Expand Down
70 changes: 50 additions & 20 deletions include/linux/gpio/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,37 +274,67 @@ void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
int parent_irq);

int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type,
bool nested,
struct lock_class_key *lock_key);

#ifdef CONFIG_LOCKDEP

/*
* Lockdep requires that each irqchip instance be created with a
* unique key so as to avoid unnecessary warnings. This upfront
* boilerplate static inlines provides such a key for each
* unique instance.
*/
static inline int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type)
{
static struct lock_class_key key;

return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
handler, type, false, &key);
}

static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type,
bool nested,
struct lock_class_key *lock_key);
unsigned int type)
{

static struct lock_class_key key;

return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
handler, type, true, &key);
}
#else
static inline int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type)
{
return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
handler, type, false, NULL);
}

/* FIXME: I assume threaded IRQchips do not have the lockdep problem */
static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type)
{
return _gpiochip_irqchip_add(gpiochip, irqchip, first_irq,
handler, type, true, NULL);
return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
handler, type, true, NULL);
}

#ifdef CONFIG_LOCKDEP
#define gpiochip_irqchip_add(...) \
( \
({ \
static struct lock_class_key _key; \
_gpiochip_irqchip_add(__VA_ARGS__, false, &_key); \
}) \
)
#else
#define gpiochip_irqchip_add(...) \
_gpiochip_irqchip_add(__VA_ARGS__, false, NULL)
#endif
#endif /* CONFIG_LOCKDEP */

#endif /* CONFIG_GPIOLIB_IRQCHIP */

Expand Down

0 comments on commit 6302118

Please sign in to comment.