aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 4e51fe3c1fc4..6a6bd569e1f8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -8,6 +8,7 @@
8#include <linux/debugfs.h> 8#include <linux/debugfs.h>
9#include <linux/seq_file.h> 9#include <linux/seq_file.h>
10#include <linux/gpio.h> 10#include <linux/gpio.h>
11#include <linux/of_gpio.h>
11#include <linux/idr.h> 12#include <linux/idr.h>
12#include <linux/slab.h> 13#include <linux/slab.h>
13 14
@@ -1100,16 +1101,24 @@ int gpiochip_add(struct gpio_chip *chip)
1100 } 1101 }
1101 } 1102 }
1102 1103
1104 of_gpiochip_add(chip);
1105
1103unlock: 1106unlock:
1104 spin_unlock_irqrestore(&gpio_lock, flags); 1107 spin_unlock_irqrestore(&gpio_lock, flags);
1105 if (status == 0) 1108
1106 status = gpiochip_export(chip); 1109 if (status)
1110 goto fail;
1111
1112 status = gpiochip_export(chip);
1113 if (status)
1114 goto fail;
1115
1116 return 0;
1107fail: 1117fail:
1108 /* failures here can mean systems won't boot... */ 1118 /* failures here can mean systems won't boot... */
1109 if (status) 1119 pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
1110 pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", 1120 chip->base, chip->base + chip->ngpio - 1,
1111 chip->base, chip->base + chip->ngpio - 1, 1121 chip->label ? : "generic");
1112 chip->label ? : "generic");
1113 return status; 1122 return status;
1114} 1123}
1115EXPORT_SYMBOL_GPL(gpiochip_add); 1124EXPORT_SYMBOL_GPL(gpiochip_add);
@@ -1128,6 +1137,8 @@ int gpiochip_remove(struct gpio_chip *chip)
1128 1137
1129 spin_lock_irqsave(&gpio_lock, flags); 1138 spin_lock_irqsave(&gpio_lock, flags);
1130 1139
1140 of_gpiochip_remove(chip);
1141
1131 for (id = chip->base; id < chip->base + chip->ngpio; id++) { 1142 for (id = chip->base; id < chip->base + chip->ngpio; id++) {
1132 if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { 1143 if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
1133 status = -EBUSY; 1144 status = -EBUSY;
@@ -1148,6 +1159,38 @@ int gpiochip_remove(struct gpio_chip *chip)
1148} 1159}
1149EXPORT_SYMBOL_GPL(gpiochip_remove); 1160EXPORT_SYMBOL_GPL(gpiochip_remove);
1150 1161
1162/**
1163 * gpiochip_find() - iterator for locating a specific gpio_chip
1164 * @data: data to pass to match function
1165 * @callback: Callback function to check gpio_chip
1166 *
1167 * Similar to bus_find_device. It returns a reference to a gpio_chip as
1168 * determined by a user supplied @match callback. The callback should return
1169 * 0 if the device doesn't match and non-zero if it does. If the callback is
1170 * non-zero, this function will return to the caller and not iterate over any
1171 * more gpio_chips.
1172 */
1173struct gpio_chip *gpiochip_find(void *data,
1174 int (*match)(struct gpio_chip *chip, void *data))
1175{
1176 struct gpio_chip *chip = NULL;
1177 unsigned long flags;
1178 int i;
1179
1180 spin_lock_irqsave(&gpio_lock, flags);
1181 for (i = 0; i < ARCH_NR_GPIOS; i++) {
1182 if (!gpio_desc[i].chip)
1183 continue;
1184
1185 if (match(gpio_desc[i].chip, data)) {
1186 chip = gpio_desc[i].chip;
1187 break;
1188 }
1189 }
1190 spin_unlock_irqrestore(&gpio_lock, flags);
1191
1192 return chip;
1193}
1151 1194
1152/* These "optional" allocation calls help prevent drivers from stomping 1195/* These "optional" allocation calls help prevent drivers from stomping
1153 * on each other, and help provide better diagnostics in debugfs. 1196 * on each other, and help provide better diagnostics in debugfs.