mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 14:34:27 -05:00 
			
		
		
		
	Fixes the following compilation issue that was introduced with the bump
to 4.14.118:
  CC      drivers/gpio/gpiolib-of.o
drivers/gpio/gpiolib-of.c: In function 'of_gpiochip_add':
drivers/gpio/gpiolib-of.c:510:12: error: too few arguments to function 'of_gpiochip_scan_gpios'
   status = of_gpiochip_scan_gpios(chip);
            ^~~~~~~~~~~~~~~~~~~~~~
drivers/gpio/gpiolib-of.c:247:5: note: declared here
 int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
     ^~~~~~~~~~~~~~~~~~~~~~
scripts/Makefile.build:326: recipe for target 'drivers/gpio/gpiolib-of.o' failed
Fixes: 09050b6fe2 ("kernel: bump 4.14 to 4.14.118")
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
		
	
			
		
			
				
	
	
		
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From e058fa1969019c2f6705c53c4130e364a877d4e6 Mon Sep 17 00:00:00 2001
 | 
						|
From: Jonas Gorski <jonas.gorski@gmail.com>
 | 
						|
Date: Sun, 26 Nov 2017 12:07:31 +0100
 | 
						|
Subject: [PATCH] gpio: fix device tree gpio hogs on dual role gpio/pincontrol
 | 
						|
 controllers
 | 
						|
 | 
						|
For dual role gpio and pincontrol controller, the device registration
 | 
						|
path is often:
 | 
						|
 | 
						|
  pinctrl_register(...);
 | 
						|
  gpiochip_add_data(...);
 | 
						|
  gpiochip_add_pin_range(...);
 | 
						|
 | 
						|
If the device tree node has any gpio-hogs, the code will try to apply them
 | 
						|
in the gpiochip_add_data step, but fail as they cannot be requested, as the
 | 
						|
ranges are missing. But we also cannot first add the pinranges, as the
 | 
						|
appropriate data structures are only initialized in gpiochip_add_data.
 | 
						|
 | 
						|
To fix this, defer gpio-hogs to the time pin ranges get added instead of
 | 
						|
directly at chip request time, if the gpio-chip has a request method.
 | 
						|
 | 
						|
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
 | 
						|
---
 | 
						|
 | 
						|
 drivers/gpio/gpiolib-of.c | 20 +++++++++++++++-----
 | 
						|
 drivers/gpio/gpiolib.c    |  5 +++--
 | 
						|
 drivers/gpio/gpiolib.h    |  8 ++++++++
 | 
						|
 3 files changed, 26 insertions(+), 7 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/gpio/gpiolib-of.c
 | 
						|
+++ b/drivers/gpio/gpiolib-of.c
 | 
						|
@@ -237,12 +237,15 @@ static struct gpio_desc *of_parse_own_gp
 | 
						|
 /**
 | 
						|
  * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
 | 
						|
  * @chip:	gpio chip to act on
 | 
						|
+ * @start:	first gpio to check
 | 
						|
+ * @num:	number of gpios to check
 | 
						|
  *
 | 
						|
- * This is only used by of_gpiochip_add to request/set GPIO initial
 | 
						|
- * configuration.
 | 
						|
+ * This is used by of_gpiochip_add, gpiochip_add_pingroup_range and
 | 
						|
+ * gpiochip_add_pin_range to request/set GPIO initial configuration.
 | 
						|
  * It returns error if it fails otherwise 0 on success.
 | 
						|
  */
 | 
						|
-static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
 | 
						|
+int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
 | 
						|
+			   unsigned int num)
 | 
						|
 {
 | 
						|
 	struct gpio_desc *desc = NULL;
 | 
						|
 	struct device_node *np;
 | 
						|
@@ -250,7 +253,7 @@ static int of_gpiochip_scan_gpios(struct
 | 
						|
 	enum gpio_lookup_flags lflags;
 | 
						|
 	enum gpiod_flags dflags;
 | 
						|
 	unsigned int i;
 | 
						|
-	int ret;
 | 
						|
+	int ret, hwgpio;
 | 
						|
 
 | 
						|
 	for_each_available_child_of_node(chip->of_node, np) {
 | 
						|
 		if (!of_property_read_bool(np, "gpio-hog"))
 | 
						|
@@ -262,6 +265,10 @@ static int of_gpiochip_scan_gpios(struct
 | 
						|
 			if (IS_ERR(desc))
 | 
						|
 				break;
 | 
						|
 
 | 
						|
+			hwgpio = gpio_chip_hwgpio(desc);
 | 
						|
+			if (hwgpio < start || hwgpio >= (start + num))
 | 
						|
+				continue;
 | 
						|
+
 | 
						|
 			ret = gpiod_hog(desc, name, lflags, dflags);
 | 
						|
 			if (ret < 0) {
 | 
						|
 				of_node_put(np);
 | 
						|
@@ -499,12 +506,13 @@ int of_gpiochip_add(struct gpio_chip *ch
 | 
						|
 
 | 
						|
 	of_node_get(chip->of_node);
 | 
						|
 
 | 
						|
-	status = of_gpiochip_scan_gpios(chip);
 | 
						|
-	if (status) {
 | 
						|
-		of_node_put(chip->of_node);
 | 
						|
-		gpiochip_remove_pin_ranges(chip);
 | 
						|
+	if (!chip->request) {
 | 
						|
+		status = of_gpiochip_scan_gpios(chip, 0, chip->ngpio);
 | 
						|
+		if (status) {
 | 
						|
+			of_node_put(chip->of_node);
 | 
						|
+			gpiochip_remove_pin_ranges(chip);
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
-
 | 
						|
 	return status;
 | 
						|
 }
 | 
						|
 
 | 
						|
--- a/drivers/gpio/gpiolib.c
 | 
						|
+++ b/drivers/gpio/gpiolib.c
 | 
						|
@@ -1938,7 +1938,8 @@ int gpiochip_add_pingroup_range(struct g
 | 
						|
 
 | 
						|
 	list_add_tail(&pin_range->node, &gdev->pin_ranges);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return of_gpiochip_scan_gpios(chip, gpio_offset,
 | 
						|
+				      pin_range->range.npins);
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
 | 
						|
 
 | 
						|
@@ -1990,7 +1991,7 @@ int gpiochip_add_pin_range(struct gpio_c
 | 
						|
 
 | 
						|
 	list_add_tail(&pin_range->node, &gdev->pin_ranges);
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return of_gpiochip_scan_gpios(chip, gpio_offset, npins);
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
 | 
						|
 
 | 
						|
--- a/drivers/gpio/gpiolib.h
 | 
						|
+++ b/drivers/gpio/gpiolib.h
 | 
						|
@@ -99,6 +99,8 @@ struct gpio_desc *of_get_named_gpiod_fla
 | 
						|
 		   const char *list_name, int index, enum of_gpio_flags *flags);
 | 
						|
 int of_gpiochip_add(struct gpio_chip *gc);
 | 
						|
 void of_gpiochip_remove(struct gpio_chip *gc);
 | 
						|
+int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
 | 
						|
+			   unsigned int num);
 | 
						|
 #else
 | 
						|
 static inline struct gpio_desc *of_find_gpio(struct device *dev,
 | 
						|
 					     const char *con_id,
 | 
						|
@@ -114,6 +116,12 @@ static inline struct gpio_desc *of_get_n
 | 
						|
 }
 | 
						|
 static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
 | 
						|
 static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 | 
						|
+static inline int of_gpiochip_scan_gpios(struct gpio_chip *chip,
 | 
						|
+					 unsigned int start,
 | 
						|
+					 unsigned int num)
 | 
						|
+{
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
 #endif /* CONFIG_OF_GPIO */
 | 
						|
 
 | 
						|
 #ifdef CONFIG_ACPI
 |