Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpiolib: let gpio_chip reference its descriptors

Add a pointer to the gpio_chip structure that references the array of
GPIO descriptors belonging to the chip, and update gpiolib code to use
this pointer instead of the global gpio_desc[] array. This is another
step towards the removal of the gpio_desc[] global array.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.orh>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

authored by

Alexandre Courbot and committed by
Grant Likely
6c0b4e6c 372e722e

+26 -16
+23 -16
drivers/gpio/gpiolib.c
··· 72 72 }; 73 73 static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; 74 74 75 + #define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio) 76 + 75 77 static LIST_HEAD(gpio_chips); 76 78 77 79 #ifdef CONFIG_GPIO_SYSFS ··· 114 112 */ 115 113 static int gpio_chip_hwgpio(const struct gpio_desc *desc) 116 114 { 117 - return (desc - &gpio_desc[0]) - desc->chip->base; 115 + return desc - &desc->chip->desc[0]; 118 116 } 119 117 120 118 /** ··· 135 133 */ 136 134 static int desc_to_gpio(const struct gpio_desc *desc) 137 135 { 138 - return desc - &gpio_desc[0]; 136 + return desc->chip->base + gpio_chip_hwgpio(desc); 139 137 } 140 138 141 139 ··· 1009 1007 unsigned gpio; 1010 1008 1011 1009 spin_lock_irqsave(&gpio_lock, flags); 1012 - gpio = chip->base; 1013 - while (gpio_desc[gpio].chip == chip) 1014 - gpio_desc[gpio++].chip = NULL; 1010 + gpio = 0; 1011 + while (gpio < chip->ngpio) 1012 + chip->desc[gpio++].chip = NULL; 1015 1013 spin_unlock_irqrestore(&gpio_lock, flags); 1016 1014 1017 1015 pr_debug("%s: chip %s status %d\n", __func__, ··· 1188 1186 status = gpiochip_add_to_list(chip); 1189 1187 1190 1188 if (status == 0) { 1191 - for (id = base; id < base + chip->ngpio; id++) { 1192 - gpio_desc[id].chip = chip; 1189 + chip->desc = &gpio_desc[chip->base]; 1190 + 1191 + for (id = 0; id < chip->ngpio; id++) { 1192 + struct gpio_desc *desc = &chip->desc[id]; 1193 + desc->chip = chip; 1193 1194 1194 1195 /* REVISIT: most hardware initializes GPIOs as 1195 1196 * inputs (often with pullups enabled) so power ··· 1201 1196 * and in case chip->get_direction is not set, 1202 1197 * we may expose the wrong direction in sysfs. 1203 1198 */ 1204 - gpio_desc[id].flags = !chip->direction_input 1199 + desc->flags = !chip->direction_input 1205 1200 ? (1 << FLAG_IS_OUT) 1206 1201 : 0; 1207 1202 } ··· 1254 1249 gpiochip_remove_pin_ranges(chip); 1255 1250 of_gpiochip_remove(chip); 1256 1251 1257 - for (id = chip->base; id < chip->base + chip->ngpio; id++) { 1258 - if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { 1252 + for (id = 0; id < chip->ngpio; id++) { 1253 + if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) { 1259 1254 status = -EBUSY; 1260 1255 break; 1261 1256 } 1262 1257 } 1263 1258 if (status == 0) { 1264 - for (id = chip->base; id < chip->base + chip->ngpio; id++) 1265 - gpio_desc[id].chip = NULL; 1259 + for (id = 0; id < chip->ngpio; id++) 1260 + chip->desc[id].chip = NULL; 1266 1261 1267 1262 list_del(&chip->list); 1268 1263 } ··· 1587 1582 */ 1588 1583 const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) 1589 1584 { 1590 - unsigned gpio = chip->base + offset; 1591 - struct gpio_desc *desc = &gpio_desc[gpio]; 1585 + struct gpio_desc *desc; 1592 1586 1593 - if (!gpio_is_valid(gpio) || desc->chip != chip) 1587 + if (!GPIO_OFFSET_VALID(chip, offset)) 1594 1588 return NULL; 1589 + 1590 + desc = &chip->desc[offset]; 1591 + 1595 1592 if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) 1596 1593 return NULL; 1597 1594 #ifdef CONFIG_DEBUG_FS ··· 2032 2025 { 2033 2026 unsigned i; 2034 2027 unsigned gpio = chip->base; 2035 - struct gpio_desc *gdesc = &gpio_desc[gpio]; 2028 + struct gpio_desc *gdesc = &chip->desc[0]; 2036 2029 int is_out; 2037 2030 2038 2031 for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
+3
include/asm-generic/gpio.h
··· 47 47 struct seq_file; 48 48 struct module; 49 49 struct device_node; 50 + struct gpio_desc; 50 51 51 52 /** 52 53 * struct gpio_chip - abstract a GPIO controller ··· 77 76 * negative during registration, requests dynamic ID allocation. 78 77 * @ngpio: the number of GPIOs handled by this controller; the last GPIO 79 78 * handled is (base + ngpio - 1). 79 + * @desc: array of ngpio descriptors. Private. 80 80 * @can_sleep: flag must be set iff get()/set() methods sleep, as they 81 81 * must while accessing GPIO expander chips over I2C or SPI 82 82 * @names: if set, must be an array of strings to use as alternative ··· 128 126 struct gpio_chip *chip); 129 127 int base; 130 128 u16 ngpio; 129 + struct gpio_desc *desc; 131 130 const char *const *names; 132 131 unsigned can_sleep:1; 133 132 unsigned exported:1;