Commit 6c0b4e6c85d085bd92966bc2b8da73e2d7f35929

Authored by Alexandre Courbot
Committed by Grant Likely
1 parent 372e722ea4

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>

Showing 2 changed files with 26 additions and 16 deletions Side-by-side Diff

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