aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-02-02 11:29:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-11 17:21:28 -0500
commit6c0b4e6c85d085bd92966bc2b8da73e2d7f35929 (patch)
treec04b9c20083445195cade9fbcd11265632585525 /drivers/gpio/gpiolib.c
parent372e722ea4dd4ca11c3d04845e11cbc15f32144c (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.c39
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};
73static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; 73static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
74 74
75#define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio)
76
75static LIST_HEAD(gpio_chips); 77static 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 */
113static int gpio_chip_hwgpio(const struct gpio_desc *desc) 115static 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 */
134static int desc_to_gpio(const struct gpio_desc *desc) 136static 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 */
1583const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) 1588const 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++) {