0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/err.h>
0011 #include <linux/gpio.h>
0012 #include <linux/gpio/consumer.h>
0013 #include <linux/device.h>
0014 #include <linux/gfp.h>
0015
0016 #include "gpiolib.h"
0017
0018 static void devm_gpiod_release(struct device *dev, void *res)
0019 {
0020 struct gpio_desc **desc = res;
0021
0022 gpiod_put(*desc);
0023 }
0024
0025 static int devm_gpiod_match(struct device *dev, void *res, void *data)
0026 {
0027 struct gpio_desc **this = res, **gpio = data;
0028
0029 return *this == *gpio;
0030 }
0031
0032 static void devm_gpiod_release_array(struct device *dev, void *res)
0033 {
0034 struct gpio_descs **descs = res;
0035
0036 gpiod_put_array(*descs);
0037 }
0038
0039 static int devm_gpiod_match_array(struct device *dev, void *res, void *data)
0040 {
0041 struct gpio_descs **this = res, **gpios = data;
0042
0043 return *this == *gpios;
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
0057 const char *con_id,
0058 enum gpiod_flags flags)
0059 {
0060 return devm_gpiod_get_index(dev, con_id, 0, flags);
0061 }
0062 EXPORT_SYMBOL_GPL(devm_gpiod_get);
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
0075 const char *con_id,
0076 enum gpiod_flags flags)
0077 {
0078 return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
0079 }
0080 EXPORT_SYMBOL_GPL(devm_gpiod_get_optional);
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
0094 const char *con_id,
0095 unsigned int idx,
0096 enum gpiod_flags flags)
0097 {
0098 struct gpio_desc **dr;
0099 struct gpio_desc *desc;
0100
0101 desc = gpiod_get_index(dev, con_id, idx, flags);
0102 if (IS_ERR(desc))
0103 return desc;
0104
0105
0106
0107
0108
0109 if (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
0110 struct devres *dres;
0111
0112 dres = devres_find(dev, devm_gpiod_release,
0113 devm_gpiod_match, &desc);
0114 if (dres)
0115 return desc;
0116 }
0117
0118 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
0119 GFP_KERNEL);
0120 if (!dr) {
0121 gpiod_put(desc);
0122 return ERR_PTR(-ENOMEM);
0123 }
0124
0125 *dr = desc;
0126 devres_add(dev, dr);
0127
0128 return desc;
0129 }
0130 EXPORT_SYMBOL_GPL(devm_gpiod_get_index);
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
0148 const struct device_node *node,
0149 const char *propname, int index,
0150 enum gpiod_flags dflags,
0151 const char *label)
0152 {
0153 struct gpio_desc **dr;
0154 struct gpio_desc *desc;
0155
0156 desc = gpiod_get_from_of_node(node, propname, index, dflags, label);
0157 if (IS_ERR(desc))
0158 return desc;
0159
0160
0161
0162
0163
0164 if (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
0165 struct devres *dres;
0166
0167 dres = devres_find(dev, devm_gpiod_release,
0168 devm_gpiod_match, &desc);
0169 if (dres)
0170 return desc;
0171 }
0172
0173 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
0174 GFP_KERNEL);
0175 if (!dr) {
0176 gpiod_put(desc);
0177 return ERR_PTR(-ENOMEM);
0178 }
0179
0180 *dr = desc;
0181 devres_add(dev, dr);
0182
0183 return desc;
0184 }
0185 EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node);
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev,
0203 struct fwnode_handle *fwnode,
0204 const char *con_id, int index,
0205 enum gpiod_flags flags,
0206 const char *label)
0207 {
0208 struct gpio_desc **dr;
0209 struct gpio_desc *desc;
0210
0211 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
0212 GFP_KERNEL);
0213 if (!dr)
0214 return ERR_PTR(-ENOMEM);
0215
0216 desc = fwnode_gpiod_get_index(fwnode, con_id, index, flags, label);
0217 if (IS_ERR(desc)) {
0218 devres_free(dr);
0219 return desc;
0220 }
0221
0222 *dr = desc;
0223 devres_add(dev, dr);
0224
0225 return desc;
0226 }
0227 EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index);
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
0242 const char *con_id,
0243 unsigned int index,
0244 enum gpiod_flags flags)
0245 {
0246 struct gpio_desc *desc;
0247
0248 desc = devm_gpiod_get_index(dev, con_id, index, flags);
0249 if (gpiod_not_found(desc))
0250 return NULL;
0251
0252 return desc;
0253 }
0254 EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional);
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
0267 const char *con_id,
0268 enum gpiod_flags flags)
0269 {
0270 struct gpio_descs **dr;
0271 struct gpio_descs *descs;
0272
0273 dr = devres_alloc(devm_gpiod_release_array,
0274 sizeof(struct gpio_descs *), GFP_KERNEL);
0275 if (!dr)
0276 return ERR_PTR(-ENOMEM);
0277
0278 descs = gpiod_get_array(dev, con_id, flags);
0279 if (IS_ERR(descs)) {
0280 devres_free(dr);
0281 return descs;
0282 }
0283
0284 *dr = descs;
0285 devres_add(dev, dr);
0286
0287 return descs;
0288 }
0289 EXPORT_SYMBOL_GPL(devm_gpiod_get_array);
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302 struct gpio_descs *__must_check
0303 devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
0304 enum gpiod_flags flags)
0305 {
0306 struct gpio_descs *descs;
0307
0308 descs = devm_gpiod_get_array(dev, con_id, flags);
0309 if (gpiod_not_found(descs))
0310 return NULL;
0311
0312 return descs;
0313 }
0314 EXPORT_SYMBOL_GPL(devm_gpiod_get_array_optional);
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
0326 {
0327 WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
0328 &desc));
0329 }
0330 EXPORT_SYMBOL_GPL(devm_gpiod_put);
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc)
0343 {
0344 int ret;
0345
0346 if (IS_ERR_OR_NULL(desc))
0347 return;
0348 ret = devres_destroy(dev, devm_gpiod_release,
0349 devm_gpiod_match, &desc);
0350
0351
0352
0353
0354
0355 if (ret == -ENOENT)
0356 return;
0357
0358 WARN_ON(ret);
0359 }
0360 EXPORT_SYMBOL_GPL(devm_gpiod_unhinge);
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
0372 {
0373 WARN_ON(devres_release(dev, devm_gpiod_release_array,
0374 devm_gpiod_match_array, &descs));
0375 }
0376 EXPORT_SYMBOL_GPL(devm_gpiod_put_array);
0377
0378 static void devm_gpio_release(struct device *dev, void *res)
0379 {
0380 unsigned *gpio = res;
0381
0382 gpio_free(*gpio);
0383 }
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396 int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
0397 {
0398 unsigned *dr;
0399 int rc;
0400
0401 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
0402 if (!dr)
0403 return -ENOMEM;
0404
0405 rc = gpio_request(gpio, label);
0406 if (rc) {
0407 devres_free(dr);
0408 return rc;
0409 }
0410
0411 *dr = gpio;
0412 devres_add(dev, dr);
0413
0414 return 0;
0415 }
0416 EXPORT_SYMBOL_GPL(devm_gpio_request);
0417
0418
0419
0420
0421
0422
0423
0424
0425 int devm_gpio_request_one(struct device *dev, unsigned gpio,
0426 unsigned long flags, const char *label)
0427 {
0428 unsigned *dr;
0429 int rc;
0430
0431 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
0432 if (!dr)
0433 return -ENOMEM;
0434
0435 rc = gpio_request_one(gpio, flags, label);
0436 if (rc) {
0437 devres_free(dr);
0438 return rc;
0439 }
0440
0441 *dr = gpio;
0442 devres_add(dev, dr);
0443
0444 return 0;
0445 }
0446 EXPORT_SYMBOL_GPL(devm_gpio_request_one);
0447
0448 static void devm_gpio_chip_release(void *data)
0449 {
0450 struct gpio_chip *gc = data;
0451
0452 gpiochip_remove(gc);
0453 }
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc, void *data,
0473 struct lock_class_key *lock_key,
0474 struct lock_class_key *request_key)
0475 {
0476 int ret;
0477
0478 ret = gpiochip_add_data_with_key(gc, data, lock_key, request_key);
0479 if (ret < 0)
0480 return ret;
0481
0482 return devm_add_action_or_reset(dev, devm_gpio_chip_release, gc);
0483 }
0484 EXPORT_SYMBOL_GPL(devm_gpiochip_add_data_with_key);