Commit 63021182 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 3258943d 739e6f59
Loading
Loading
Loading
Loading
+9 −9
Original line number Original line Diff line number Diff line
@@ -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
 * @gpiochip: the gpiochip to add the irqchip to
 * @irqchip: the irqchip to add to the gpiochip
 * @irqchip: the irqchip to add to the gpiochip
 * @first_irq: if not dynamically assigned, the base (first) IRQ to
 * @first_irq: if not dynamically assigned, the base (first) IRQ to
@@ -1749,7 +1749,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
 * the pins on the gpiochip can generate a unique IRQ. Everything else
 * the pins on the gpiochip can generate a unique IRQ. Everything else
 * need to be open coded.
 * need to be open coded.
 */
 */
int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
			     struct irq_chip *irqchip,
			     struct irq_chip *irqchip,
			     unsigned int first_irq,
			     unsigned int first_irq,
			     irq_flow_handler_t handler,
			     irq_flow_handler_t handler,
@@ -1840,7 +1840,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,


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


#else /* CONFIG_GPIOLIB_IRQCHIP */
#else /* CONFIG_GPIOLIB_IRQCHIP */


+50 −20
Original line number Original line Diff line number Diff line
@@ -274,7 +274,7 @@ void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
		struct irq_chip *irqchip,
		struct irq_chip *irqchip,
		int parent_irq);
		int parent_irq);


int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
			     struct irq_chip *irqchip,
			     struct irq_chip *irqchip,
			     unsigned int first_irq,
			     unsigned int first_irq,
			     irq_flow_handler_t handler,
			     irq_flow_handler_t handler,
@@ -282,29 +282,59 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
			     bool nested,
			     bool nested,
			     struct lock_class_key *lock_key);
			     struct lock_class_key *lock_key);


/* FIXME: I assume threaded IRQchips do not have the lockdep problem */
#ifdef CONFIG_LOCKDEP
static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,

/*
 * 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,
				       struct irq_chip *irqchip,
				       unsigned int first_irq,
				       unsigned int first_irq,
				       irq_flow_handler_t handler,
				       irq_flow_handler_t handler,
				       unsigned int type)
				       unsigned int type)
{
{
	return _gpiochip_irqchip_add(gpiochip, irqchip, first_irq,
	static struct lock_class_key key;
				     handler, type, true, NULL);

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


#ifdef CONFIG_LOCKDEP
static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,
#define gpiochip_irqchip_add(...)				\
			  struct irq_chip *irqchip,
(								\
			  unsigned int first_irq,
	({							\
			  irq_flow_handler_t handler,
		static struct lock_class_key _key;		\
			  unsigned int type)
		_gpiochip_irqchip_add(__VA_ARGS__, false, &_key); \
{
	})							\

)
	static struct lock_class_key key;

	return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
					handler, type, true, &key);
}
#else
#else
#define gpiochip_irqchip_add(...)				\
static inline int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
	_gpiochip_irqchip_add(__VA_ARGS__, false, NULL)
				       struct irq_chip *irqchip,
#endif
				       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);
}

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_key(gpiochip, irqchip, first_irq,
					handler, type, true, NULL);
}
#endif /* CONFIG_LOCKDEP */


#endif /* CONFIG_GPIOLIB_IRQCHIP */
#endif /* CONFIG_GPIOLIB_IRQCHIP */