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 3ca36542e338..83cbc34e3a76 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
@@ -1099,16 +1100,24 @@ int gpiochip_add(struct gpio_chip *chip)
1099 } 1100 }
1100 } 1101 }
1101 1102
1103 of_gpiochip_add(chip);
1104
1102unlock: 1105unlock:
1103 spin_unlock_irqrestore(&gpio_lock, flags); 1106 spin_unlock_irqrestore(&gpio_lock, flags);
1104 if (status == 0) 1107
1105 status = gpiochip_export(chip); 1108 if (status)
1109 goto fail;
1110
1111 status = gpiochip_export(chip);
1112 if (status)
1113 goto fail;
1114
1115 return 0;
1106fail: 1116fail:
1107 /* failures here can mean systems won't boot... */ 1117 /* failures here can mean systems won't boot... */
1108 if (status) 1118 pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
1109 pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", 1119 chip->base, chip->base + chip->ngpio - 1,
1110 chip->base, chip->base + chip->ngpio - 1, 1120 chip->label ? : "generic");
1111 chip->label ? : "generic");
1112 return status; 1121 return status;
1113} 1122}
1114EXPORT_SYMBOL_GPL(gpiochip_add); 1123EXPORT_SYMBOL_GPL(gpiochip_add);
@@ -1127,6 +1136,8 @@ int gpiochip_remove(struct gpio_chip *chip)
1127 1136
1128 spin_lock_irqsave(&gpio_lock, flags); 1137 spin_lock_irqsave(&gpio_lock, flags);
1129 1138
1139 of_gpiochip_remove(chip);
1140
1130 for (id = chip->base; id < chip->base + chip->ngpio; id++) { 1141 for (id = chip->base; id < chip->base + chip->ngpio; id++) {
1131 if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { 1142 if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
1132 status = -EBUSY; 1143 status = -EBUSY;
@@ -1147,6 +1158,38 @@ int gpiochip_remove(struct gpio_chip *chip)
1147} 1158}
1148EXPORT_SYMBOL_GPL(gpiochip_remove); 1159EXPORT_SYMBOL_GPL(gpiochip_remove);
1149 1160
1161/**
1162 * gpiochip_find() - iterator for locating a specific gpio_chip
1163 * @data: data to pass to match function
1164 * @callback: Callback function to check gpio_chip
1165 *
1166 * Similar to bus_find_device. It returns a reference to a gpio_chip as
1167 * determined by a user supplied @match callback. The callback should return
1168 * 0 if the device doesn't match and non-zero if it does. If the callback is
1169 * non-zero, this function will return to the caller and not iterate over any
1170 * more gpio_chips.
1171 */
1172struct gpio_chip *gpiochip_find(void *data,
1173 int (*match)(struct gpio_chip *chip, void *data))
1174{
1175 struct gpio_chip *chip = NULL;
1176 unsigned long flags;
1177 int i;
1178
1179 spin_lock_irqsave(&gpio_lock, flags);
1180 for (i = 0; i < ARCH_NR_GPIOS; i++) {
1181 if (!gpio_desc[i].chip)
1182 continue;
1183
1184 if (match(gpio_desc[i].chip, data)) {
1185 chip = gpio_desc[i].chip;
1186 break;
1187 }
1188 }
1189 spin_unlock_irqrestore(&gpio_lock, flags);
1190
1191 return chip;
1192}
1150 1193
1151/* These "optional" allocation calls help prevent drivers from stomping 1194/* These "optional" allocation calls help prevent drivers from stomping
1152 * on each other, and help provide better diagnostics in debugfs. 1195 * on each other, and help provide better diagnostics in debugfs.