Skip to content

Commit 28355f8

Browse files
tomeuvlinusw
authored andcommitted
gpio: defer probe if pinctrl cannot be found
When an OF node has a pin range for its GPIOs, return -EPROBE_DEFER if the pin controller isn't available. Otherwise, the GPIO range wouldn't be set at all unless the pin controller probed always before the GPIO chip. With this change, the probe of the GPIO chip will be deferred and will be retried at a later point, hopefully once the pin controller has been registered and probed already. Signed-off-by: Tomeu Vizoso <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 23393d4 commit 28355f8

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

drivers/gpio/gpiolib-of.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc)
335335
EXPORT_SYMBOL(of_mm_gpiochip_remove);
336336

337337
#ifdef CONFIG_PINCTRL
338-
static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
338+
static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
339339
{
340340
struct device_node *np = chip->of_node;
341341
struct of_phandle_args pinspec;
@@ -346,7 +346,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
346346
struct property *group_names;
347347

348348
if (!np)
349-
return;
349+
return 0;
350350

351351
group_names = of_find_property(np, group_names_propname, NULL);
352352

@@ -358,7 +358,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
358358

359359
pctldev = of_pinctrl_get(pinspec.np);
360360
if (!pctldev)
361-
break;
361+
return -EPROBE_DEFER;
362362

363363
if (pinspec.args[2]) {
364364
if (group_names) {
@@ -378,7 +378,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
378378
pinspec.args[1],
379379
pinspec.args[2]);
380380
if (ret)
381-
break;
381+
return ret;
382382
} else {
383383
/* npins == 0: special range */
384384
if (pinspec.args[1]) {
@@ -408,32 +408,41 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
408408
ret = gpiochip_add_pingroup_range(chip, pctldev,
409409
pinspec.args[0], name);
410410
if (ret)
411-
break;
411+
return ret;
412412
}
413413
}
414+
415+
return 0;
414416
}
415417

416418
#else
417-
static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {}
419+
static int of_gpiochip_add_pin_range(struct gpio_chip *chip) { return 0; }
418420
#endif
419421

420-
void of_gpiochip_add(struct gpio_chip *chip)
422+
int of_gpiochip_add(struct gpio_chip *chip)
421423
{
424+
int status;
425+
422426
if ((!chip->of_node) && (chip->dev))
423427
chip->of_node = chip->dev->of_node;
424428

425429
if (!chip->of_node)
426-
return;
430+
return 0;
427431

428432
if (!chip->of_xlate) {
429433
chip->of_gpio_n_cells = 2;
430434
chip->of_xlate = of_gpio_simple_xlate;
431435
}
432436

433-
of_gpiochip_add_pin_range(chip);
437+
status = of_gpiochip_add_pin_range(chip);
438+
if (status)
439+
return status;
440+
434441
of_node_get(chip->of_node);
435442

436443
of_gpiochip_scan_hogs(chip);
444+
445+
return 0;
437446
}
438447

439448
void of_gpiochip_remove(struct gpio_chip *chip)

drivers/gpio/gpiolib.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,10 @@ int gpiochip_add(struct gpio_chip *chip)
290290
if (!chip->owner && chip->dev && chip->dev->driver)
291291
chip->owner = chip->dev->driver->owner;
292292

293-
of_gpiochip_add(chip);
293+
status = of_gpiochip_add(chip);
294+
if (status)
295+
goto err_remove_chip;
296+
294297
acpi_gpiochip_add(chip);
295298

296299
status = gpiochip_sysfs_register(chip);

include/linux/of_gpio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extern int of_mm_gpiochip_add(struct device_node *np,
5454
struct of_mm_gpio_chip *mm_gc);
5555
extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc);
5656

57-
extern void of_gpiochip_add(struct gpio_chip *gc);
57+
extern int of_gpiochip_add(struct gpio_chip *gc);
5858
extern void of_gpiochip_remove(struct gpio_chip *gc);
5959
extern int of_gpio_simple_xlate(struct gpio_chip *gc,
6060
const struct of_phandle_args *gpiospec,
@@ -76,7 +76,7 @@ static inline int of_gpio_simple_xlate(struct gpio_chip *gc,
7676
return -ENOSYS;
7777
}
7878

79-
static inline void of_gpiochip_add(struct gpio_chip *gc) { }
79+
static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
8080
static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
8181

8282
#endif /* CONFIG_OF_GPIO */

0 commit comments

Comments
 (0)