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
8686 struct lock_class_key *lock_key,
8787 struct lock_class_key *request_key);
8888 static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
89+static int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip);
8990 static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip);
9091 static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip);
9192
@@ -1406,6 +1407,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, · 1314 unmodified lines
14061407
14071408 machine_gpiochip_add(chip);
14081409
1410+ ret = gpiochip_irqchip_init_hw(chip);
1411+ if (ret)
1412+ goto err_remove_acpi_chip;
1413+
14091414 ret = gpiochip_irqchip_init_valid_mask(chip);
14101415 if (ret)
14111416 goto err_remove_acpi_chip;
@@ -1622,6 +1627,16 @@ static struct gpio_chip *find_chip_by_name(const char *name) · 210 unmodified lines
16221627 * The following is irqchip helper code for gpiochips.
16231628 */
16241629
1630+static 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+
16251640 static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc)
16261641 {
16271642 struct gpio_irq_chip *girq = &gc->irq;
@@ -2446,8 +2461,13 @@ static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 818 unmodified lines
24462461 {
24472462 return 0;
24482463 }
2449−
24502464 static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {}
2465+
2466+static inline int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip)
2467+{
2468+ return 0;
2469+}
2470+
24512471 static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
24522472 {
24532473 return 0;
include/linux/gpio/driver.h+8−0
@@ -201,6 +201,14 @@ struct gpio_irq_chip { · 200 unmodified lines
201201 */
202202 bool threaded;
203203
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+
204212 /**
205213 * @init_valid_mask: optional routine to initialize @valid_mask, to be
206214 * 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