[PATCH 09/11] pinctrl: at91: make deep-probe compatible

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



GPIO banks are probed independently from pinctrl parent device as it's
simple-bus compatible. The pinctrl driver needs access to the GPIO
banks though for applying a pin configuration. This has two problems:

  - When we have a pinctrl hog, we can't apply it if GPIOs weren't
    probed before

  - In a deep probe system, pinctrl may be used before GPIO was probed

Fix this for deep probe systems by probing relevant GPIO banks on
demand. We wrap this in a deep_probe_is_supported() check to avoid
increasing code size for the configurations that use non-DT enabled
barebox proper as first stage bootloader.

Tested on SAMA5D4.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 drivers/pinctrl/pinctrl-at91.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 0295d928cf61..4b71d181d483 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -16,6 +16,7 @@
 #include <init.h>
 #include <driver.h>
 #include <getopt.h>
+#include <deep-probe.h>
 
 #include <mach/at91_pio.h>
 #include <mach/gpio.h>
@@ -47,17 +48,25 @@ struct at91_gpio_chip {
 #define DEBOUNCE_VAL_SHIFT      17
 #define DEBOUNCE_VAL    (0x3fff << DEBOUNCE_VAL_SHIFT)
 
-static int gpio_banks;
-
 static struct at91_gpio_chip gpio_chip[MAX_GPIO_BANKS];
 
 static inline struct at91_gpio_chip *pin_to_controller(unsigned pin)
 {
+	struct at91_gpio_chip *chip;
+
 	pin /= MAX_NB_GPIO_PER_BANK;
-	if (likely(pin < gpio_banks))
-		return &gpio_chip[pin];
+	if (unlikely(pin >= MAX_GPIO_BANKS))
+		return NULL;
+
+	chip = &gpio_chip[pin];
+
+	if (!chip->regbase && deep_probe_is_supported()) {
+		char alias[] = "gpioX";
+		scnprintf(alias, sizeof(alias), "gpio%u", pin);
+		of_device_ensure_probed_by_alias(alias);
+	}
 
-	return NULL;
+	return chip;
 }
 
 /**
@@ -652,7 +661,6 @@ static int at91_gpio_probe(struct device_d *dev)
 		return ret;
 	}
 
-	gpio_banks = max(gpio_banks, alias_idx + 1);
 	at91_gpio->regbase = dev_request_mem_region_err_null(dev, 0);
 	if (!at91_gpio->regbase)
 		return -ENOENT;
-- 
2.30.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux