diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2013-02-02 11:29:30 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2013-02-11 17:21:28 -0500 |
commit | 6c0b4e6c85d085bd92966bc2b8da73e2d7f35929 (patch) | |
tree | c04b9c20083445195cade9fbcd11265632585525 /drivers/gpio/gpiolib.c | |
parent | 372e722ea4dd4ca11c3d04845e11cbc15f32144c (diff) |
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>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 866431f674c3..5050693dcc35 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -72,6 +72,8 @@ struct gpio_desc { | |||
72 | }; | 72 | }; |
73 | static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; | 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 | static LIST_HEAD(gpio_chips); | 77 | static LIST_HEAD(gpio_chips); |
76 | 78 | ||
77 | #ifdef CONFIG_GPIO_SYSFS | 79 | #ifdef CONFIG_GPIO_SYSFS |
@@ -112,7 +114,7 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) | |||
112 | */ | 114 | */ |
113 | static int gpio_chip_hwgpio(const struct gpio_desc *desc) | 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 @@ static struct gpio_desc *gpio_to_desc(unsigned gpio) | |||
133 | */ | 135 | */ |
134 | static int desc_to_gpio(const struct gpio_desc *desc) | 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 @@ static int gpiochip_export(struct gpio_chip *chip) | |||
1007 | unsigned gpio; | 1009 | unsigned gpio; |
1008 | 1010 | ||
1009 | spin_lock_irqsave(&gpio_lock, flags); | 1011 | spin_lock_irqsave(&gpio_lock, flags); |
1010 | gpio = chip->base; | 1012 | gpio = 0; |
1011 | while (gpio_desc[gpio].chip == chip) | 1013 | while (gpio < chip->ngpio) |
1012 | gpio_desc[gpio++].chip = NULL; | 1014 | chip->desc[gpio++].chip = NULL; |
1013 | spin_unlock_irqrestore(&gpio_lock, flags); | 1015 | spin_unlock_irqrestore(&gpio_lock, flags); |
1014 | 1016 | ||
1015 | pr_debug("%s: chip %s status %d\n", __func__, | 1017 | pr_debug("%s: chip %s status %d\n", __func__, |
@@ -1186,8 +1188,11 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1186 | status = gpiochip_add_to_list(chip); | 1188 | status = gpiochip_add_to_list(chip); |
1187 | 1189 | ||
1188 | if (status == 0) { | 1190 | if (status == 0) { |
1189 | for (id = base; id < base + chip->ngpio; id++) { | 1191 | chip->desc = &gpio_desc[chip->base]; |
1190 | gpio_desc[id].chip = chip; | 1192 | |
1193 | for (id = 0; id < chip->ngpio; id++) { | ||
1194 | struct gpio_desc *desc = &chip->desc[id]; | ||
1195 | desc->chip = chip; | ||
1191 | 1196 | ||
1192 | /* REVISIT: most hardware initializes GPIOs as | 1197 | /* REVISIT: most hardware initializes GPIOs as |
1193 | * inputs (often with pullups enabled) so power | 1198 | * inputs (often with pullups enabled) so power |
@@ -1196,7 +1201,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1196 | * and in case chip->get_direction is not set, | 1201 | * and in case chip->get_direction is not set, |
1197 | * we may expose the wrong direction in sysfs. | 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 | ? (1 << FLAG_IS_OUT) | 1205 | ? (1 << FLAG_IS_OUT) |
1201 | : 0; | 1206 | : 0; |
1202 | } | 1207 | } |
@@ -1249,15 +1254,15 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1249 | gpiochip_remove_pin_ranges(chip); | 1254 | gpiochip_remove_pin_ranges(chip); |
1250 | of_gpiochip_remove(chip); | 1255 | of_gpiochip_remove(chip); |
1251 | 1256 | ||
1252 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1257 | for (id = 0; id < chip->ngpio; id++) { |
1253 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { | 1258 | if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) { |
1254 | status = -EBUSY; | 1259 | status = -EBUSY; |
1255 | break; | 1260 | break; |
1256 | } | 1261 | } |
1257 | } | 1262 | } |
1258 | if (status == 0) { | 1263 | if (status == 0) { |
1259 | for (id = chip->base; id < chip->base + chip->ngpio; id++) | 1264 | for (id = 0; id < chip->ngpio; id++) |
1260 | gpio_desc[id].chip = NULL; | 1265 | chip->desc[id].chip = NULL; |
1261 | 1266 | ||
1262 | list_del(&chip->list); | 1267 | list_del(&chip->list); |
1263 | } | 1268 | } |
@@ -1582,11 +1587,13 @@ EXPORT_SYMBOL_GPL(gpio_free_array); | |||
1582 | */ | 1587 | */ |
1583 | const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) | 1588 | const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) |
1584 | { | 1589 | { |
1585 | unsigned gpio = chip->base + offset; | 1590 | struct gpio_desc *desc; |
1586 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
1587 | 1591 | ||
1588 | if (!gpio_is_valid(gpio) || desc->chip != chip) | 1592 | if (!GPIO_OFFSET_VALID(chip, offset)) |
1589 | return NULL; | 1593 | return NULL; |
1594 | |||
1595 | desc = &chip->desc[offset]; | ||
1596 | |||
1590 | if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) | 1597 | if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) |
1591 | return NULL; | 1598 | return NULL; |
1592 | #ifdef CONFIG_DEBUG_FS | 1599 | #ifdef CONFIG_DEBUG_FS |
@@ -2025,7 +2032,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
2025 | { | 2032 | { |
2026 | unsigned i; | 2033 | unsigned i; |
2027 | unsigned gpio = chip->base; | 2034 | unsigned gpio = chip->base; |
2028 | struct gpio_desc *gdesc = &gpio_desc[gpio]; | 2035 | struct gpio_desc *gdesc = &chip->desc[0]; |
2029 | int is_out; | 2036 | int is_out; |
2030 | 2037 | ||
2031 | for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) { | 2038 | for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) { |