linux/drivers/gpio/devres.c
<<
>>
Prefs
   1/*
   2 * drivers/gpio/devres.c - managed gpio resources
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2
   6 * as published by the Free Software Foundation.
   7 *
   8 * You should have received a copy of the GNU General Public License
   9 * along with this program; if not, write to the Free Software
  10 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  11 *
  12 * This file is based on kernel/irq/devres.c
  13 *
  14 * Copyright (c) 2011 John Crispin <blogic@openwrt.org>
  15 */
  16
  17#include <linux/module.h>
  18#include <linux/err.h>
  19#include <linux/gpio.h>
  20#include <linux/gpio/consumer.h>
  21#include <linux/device.h>
  22#include <linux/gfp.h>
  23
  24static void devm_gpiod_release(struct device *dev, void *res)
  25{
  26        struct gpio_desc **desc = res;
  27
  28        gpiod_put(*desc);
  29}
  30
  31static int devm_gpiod_match(struct device *dev, void *res, void *data)
  32{
  33        struct gpio_desc **this = res, **gpio = data;
  34
  35        return *this == *gpio;
  36}
  37
  38/**
  39 * devm_gpiod_get - Resource-managed gpiod_get()
  40 * @dev:        GPIO consumer
  41 * @con_id:     function within the GPIO consumer
  42 * @flags:      optional GPIO initialization flags
  43 *
  44 * Managed gpiod_get(). GPIO descriptors returned from this function are
  45 * automatically disposed on driver detach. See gpiod_get() for detailed
  46 * information about behavior and return values.
  47 */
  48struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
  49                                              const char *con_id,
  50                                              enum gpiod_flags flags)
  51{
  52        return devm_gpiod_get_index(dev, con_id, 0, flags);
  53}
  54EXPORT_SYMBOL(__devm_gpiod_get);
  55
  56/**
  57 * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
  58 * @dev: GPIO consumer
  59 * @con_id: function within the GPIO consumer
  60 * @flags: optional GPIO initialization flags
  61 *
  62 * Managed gpiod_get_optional(). GPIO descriptors returned from this function
  63 * are automatically disposed on driver detach. See gpiod_get_optional() for
  64 * detailed information about behavior and return values.
  65 */
  66struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
  67                                                       const char *con_id,
  68                                                       enum gpiod_flags flags)
  69{
  70        return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
  71}
  72EXPORT_SYMBOL(__devm_gpiod_get_optional);
  73
  74/**
  75 * devm_gpiod_get_index - Resource-managed gpiod_get_index()
  76 * @dev:        GPIO consumer
  77 * @con_id:     function within the GPIO consumer
  78 * @idx:        index of the GPIO to obtain in the consumer
  79 * @flags:      optional GPIO initialization flags
  80 *
  81 * Managed gpiod_get_index(). GPIO descriptors returned from this function are
  82 * automatically disposed on driver detach. See gpiod_get_index() for detailed
  83 * information about behavior and return values.
  84 */
  85struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
  86                                                    const char *con_id,
  87                                                    unsigned int idx,
  88                                                    enum gpiod_flags flags)
  89{
  90        struct gpio_desc **dr;
  91        struct gpio_desc *desc;
  92
  93        dr = devres_alloc(devm_gpiod_release, sizeof(struct gpiod_desc *),
  94                          GFP_KERNEL);
  95        if (!dr)
  96                return ERR_PTR(-ENOMEM);
  97
  98        desc = gpiod_get_index(dev, con_id, idx, flags);
  99        if (IS_ERR(desc)) {
 100                devres_free(dr);
 101                return desc;
 102        }
 103
 104        *dr = desc;
 105        devres_add(dev, dr);
 106
 107        return desc;
 108}
 109EXPORT_SYMBOL(__devm_gpiod_get_index);
 110
 111/**
 112 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
 113 * @dev: GPIO consumer
 114 * @con_id: function within the GPIO consumer
 115 * @index: index of the GPIO to obtain in the consumer
 116 * @flags: optional GPIO initialization flags
 117 *
 118 * Managed gpiod_get_index_optional(). GPIO descriptors returned from this
 119 * function are automatically disposed on driver detach. See
 120 * gpiod_get_index_optional() for detailed information about behavior and
 121 * return values.
 122 */
 123struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev,
 124                                                             const char *con_id,
 125                                                             unsigned int index,
 126                                                         enum gpiod_flags flags)
 127{
 128        struct gpio_desc *desc;
 129
 130        desc = devm_gpiod_get_index(dev, con_id, index, flags);
 131        if (IS_ERR(desc)) {
 132                if (PTR_ERR(desc) == -ENOENT)
 133                        return NULL;
 134        }
 135
 136        return desc;
 137}
 138EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
 139
 140/**
 141 * devm_gpiod_put - Resource-managed gpiod_put()
 142 * @desc:       GPIO descriptor to dispose of
 143 *
 144 * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
 145 * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
 146 * will be disposed of by the resource management code.
 147 */
 148void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
 149{
 150        WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
 151                &desc));
 152}
 153EXPORT_SYMBOL(devm_gpiod_put);
 154
 155
 156
 157
 158static void devm_gpio_release(struct device *dev, void *res)
 159{
 160        unsigned *gpio = res;
 161
 162        gpio_free(*gpio);
 163}
 164
 165static int devm_gpio_match(struct device *dev, void *res, void *data)
 166{
 167        unsigned *this = res, *gpio = data;
 168
 169        return *this == *gpio;
 170}
 171
 172/**
 173 *      devm_gpio_request - request a GPIO for a managed device
 174 *      @dev: device to request the GPIO for
 175 *      @gpio: GPIO to allocate
 176 *      @label: the name of the requested GPIO
 177 *
 178 *      Except for the extra @dev argument, this function takes the
 179 *      same arguments and performs the same function as
 180 *      gpio_request().  GPIOs requested with this function will be
 181 *      automatically freed on driver detach.
 182 *
 183 *      If an GPIO allocated with this function needs to be freed
 184 *      separately, devm_gpio_free() must be used.
 185 */
 186
 187int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
 188{
 189        unsigned *dr;
 190        int rc;
 191
 192        dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
 193        if (!dr)
 194                return -ENOMEM;
 195
 196        rc = gpio_request(gpio, label);
 197        if (rc) {
 198                devres_free(dr);
 199                return rc;
 200        }
 201
 202        *dr = gpio;
 203        devres_add(dev, dr);
 204
 205        return 0;
 206}
 207EXPORT_SYMBOL(devm_gpio_request);
 208
 209/**
 210 *      devm_gpio_request_one - request a single GPIO with initial setup
 211 *      @dev:   device to request for
 212 *      @gpio:  the GPIO number
 213 *      @flags: GPIO configuration as specified by GPIOF_*
 214 *      @label: a literal description string of this GPIO
 215 */
 216int devm_gpio_request_one(struct device *dev, unsigned gpio,
 217                          unsigned long flags, const char *label)
 218{
 219        unsigned *dr;
 220        int rc;
 221
 222        dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
 223        if (!dr)
 224                return -ENOMEM;
 225
 226        rc = gpio_request_one(gpio, flags, label);
 227        if (rc) {
 228                devres_free(dr);
 229                return rc;
 230        }
 231
 232        *dr = gpio;
 233        devres_add(dev, dr);
 234
 235        return 0;
 236}
 237EXPORT_SYMBOL(devm_gpio_request_one);
 238
 239/**
 240 *      devm_gpio_free - free a GPIO
 241 *      @dev: device to free GPIO for
 242 *      @gpio: GPIO to free
 243 *
 244 *      Except for the extra @dev argument, this function takes the
 245 *      same arguments and performs the same function as gpio_free().
 246 *      This function instead of gpio_free() should be used to manually
 247 *      free GPIOs allocated with devm_gpio_request().
 248 */
 249void devm_gpio_free(struct device *dev, unsigned int gpio)
 250{
 251
 252        WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
 253                &gpio));
 254}
 255EXPORT_SYMBOL(devm_gpio_free);
 256