History

gpiolib: Initialize the hardware with a callback

After changing the drivers to use GPIO core to add an IRQ chip it appears that some of them requires a hardware initialization before adding the IRQ chip. Add an optional callback ->init_hw() to allow that drivers to initialize hardware if needed. This change is a part of the fix NULL pointer dereference brought to the several drivers recently.

Andy Shevchenko committed 7 years ago

Commit 9411e3a1 parent 6658f872 files · +29 −1Browse files

Unified · Split

2 files
  1. drivers/gpio/gpiolib.c +21 −1
  2. include/linux/gpio/driver.h +8 −0
drivers/gpio/gpiolib.c+21−1
@@ -86,6 +86,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 85 unmodified lines
86 struct lock_class_key *lock_key,86 struct lock_class_key *lock_key,
87 struct lock_class_key *request_key);87 struct lock_class_key *request_key);
88static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);88static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
89static int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip);
89static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip);90static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip);
90static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip);91static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip);
91 92
@@ -1406,6 +1407,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, · 1314 unmodified lines
1406 1407
1407 machine_gpiochip_add(chip);1408 machine_gpiochip_add(chip);
1408 1409
1410 ret = gpiochip_irqchip_init_hw(chip);
1411 if (ret)
1412 goto err_remove_acpi_chip;
1413
1409 ret = gpiochip_irqchip_init_valid_mask(chip);1414 ret = gpiochip_irqchip_init_valid_mask(chip);
1410 if (ret)1415 if (ret)
1411 goto err_remove_acpi_chip;1416 goto err_remove_acpi_chip;
@@ -1622,6 +1627,16 @@ static struct gpio_chip *find_chip_by_name(const char *name) · 210 unmodified lines
1622 * The following is irqchip helper code for gpiochips.1627 * The following is irqchip helper code for gpiochips.
1623 */1628 */
1624 1629
1630static int gpiochip_irqchip_init_hw(struct gpio_chip *gc)
1631{
1632 struct gpio_irq_chip *girq = &gc->irq;
1633
1634 if (!girq->init_hw)
1635 return 0;
1636
1637 return girq->init_hw(gc);
1638}
1639
1625static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc)1640static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc)
1626{1641{
1627 struct gpio_irq_chip *girq = &gc->irq;1642 struct gpio_irq_chip *girq = &gc->irq;
@@ -2446,8 +2461,13 @@ static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 818 unmodified lines
2446{2461{
2447 return 0;2462 return 0;
2448}2463}
2449
2450static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {}2464static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {}
2465
2466static inline int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip)
2467{
2468 return 0;
2469}
2470
2451static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)2471static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
2452{2472{
2453 return 0;2473 return 0;
include/linux/gpio/driver.h+8−0
@@ -201,6 +201,14 @@ struct gpio_irq_chip { · 200 unmodified lines
201 */201 */
202 bool threaded;202 bool threaded;
203 203
204 /**
205 * @init_hw: optional routine to initialize hardware before
206 * an IRQ chip will be added. This is quite useful when
207 * a particular driver wants to clear IRQ related registers
208 * in order to avoid undesired events.
209 */
210 int (*init_hw)(struct gpio_chip *chip);
211
204 /**212 /**
205 * @init_valid_mask: optional routine to initialize @valid_mask, to be213 * @init_valid_mask: optional routine to initialize @valid_mask, to be
206 * used if not all GPIO lines are valid interrupts. Sometimes some214 * used if not all GPIO lines are valid interrupts. Sometimes some

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t