at v3.19-rc2 287 lines 7.7 kB view raw
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 gpio_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_get_gpiod_from_child - get a GPIO descriptor from a device's child node 113 * @dev: GPIO consumer 114 * @child: firmware node (child of @dev) 115 * 116 * GPIO descriptors returned from this function are automatically disposed on 117 * driver detach. 118 */ 119struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, 120 struct fwnode_handle *child) 121{ 122 struct gpio_desc **dr; 123 struct gpio_desc *desc; 124 125 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), 126 GFP_KERNEL); 127 if (!dr) 128 return ERR_PTR(-ENOMEM); 129 130 desc = fwnode_get_named_gpiod(child, "gpios"); 131 if (IS_ERR(desc)) { 132 devres_free(dr); 133 return desc; 134 } 135 136 *dr = desc; 137 devres_add(dev, dr); 138 139 return desc; 140} 141EXPORT_SYMBOL(devm_get_gpiod_from_child); 142 143/** 144 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() 145 * @dev: GPIO consumer 146 * @con_id: function within the GPIO consumer 147 * @index: index of the GPIO to obtain in the consumer 148 * @flags: optional GPIO initialization flags 149 * 150 * Managed gpiod_get_index_optional(). GPIO descriptors returned from this 151 * function are automatically disposed on driver detach. See 152 * gpiod_get_index_optional() for detailed information about behavior and 153 * return values. 154 */ 155struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev, 156 const char *con_id, 157 unsigned int index, 158 enum gpiod_flags flags) 159{ 160 struct gpio_desc *desc; 161 162 desc = devm_gpiod_get_index(dev, con_id, index, flags); 163 if (IS_ERR(desc)) { 164 if (PTR_ERR(desc) == -ENOENT) 165 return NULL; 166 } 167 168 return desc; 169} 170EXPORT_SYMBOL(__devm_gpiod_get_index_optional); 171 172/** 173 * devm_gpiod_put - Resource-managed gpiod_put() 174 * @desc: GPIO descriptor to dispose of 175 * 176 * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or 177 * devm_gpiod_get_index(). Normally this function will not be called as the GPIO 178 * will be disposed of by the resource management code. 179 */ 180void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 181{ 182 WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match, 183 &desc)); 184} 185EXPORT_SYMBOL(devm_gpiod_put); 186 187 188 189 190static void devm_gpio_release(struct device *dev, void *res) 191{ 192 unsigned *gpio = res; 193 194 gpio_free(*gpio); 195} 196 197static int devm_gpio_match(struct device *dev, void *res, void *data) 198{ 199 unsigned *this = res, *gpio = data; 200 201 return *this == *gpio; 202} 203 204/** 205 * devm_gpio_request - request a GPIO for a managed device 206 * @dev: device to request the GPIO for 207 * @gpio: GPIO to allocate 208 * @label: the name of the requested GPIO 209 * 210 * Except for the extra @dev argument, this function takes the 211 * same arguments and performs the same function as 212 * gpio_request(). GPIOs requested with this function will be 213 * automatically freed on driver detach. 214 * 215 * If an GPIO allocated with this function needs to be freed 216 * separately, devm_gpio_free() must be used. 217 */ 218 219int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) 220{ 221 unsigned *dr; 222 int rc; 223 224 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); 225 if (!dr) 226 return -ENOMEM; 227 228 rc = gpio_request(gpio, label); 229 if (rc) { 230 devres_free(dr); 231 return rc; 232 } 233 234 *dr = gpio; 235 devres_add(dev, dr); 236 237 return 0; 238} 239EXPORT_SYMBOL(devm_gpio_request); 240 241/** 242 * devm_gpio_request_one - request a single GPIO with initial setup 243 * @dev: device to request for 244 * @gpio: the GPIO number 245 * @flags: GPIO configuration as specified by GPIOF_* 246 * @label: a literal description string of this GPIO 247 */ 248int devm_gpio_request_one(struct device *dev, unsigned gpio, 249 unsigned long flags, const char *label) 250{ 251 unsigned *dr; 252 int rc; 253 254 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); 255 if (!dr) 256 return -ENOMEM; 257 258 rc = gpio_request_one(gpio, flags, label); 259 if (rc) { 260 devres_free(dr); 261 return rc; 262 } 263 264 *dr = gpio; 265 devres_add(dev, dr); 266 267 return 0; 268} 269EXPORT_SYMBOL(devm_gpio_request_one); 270 271/** 272 * devm_gpio_free - free a GPIO 273 * @dev: device to free GPIO for 274 * @gpio: GPIO to free 275 * 276 * Except for the extra @dev argument, this function takes the 277 * same arguments and performs the same function as gpio_free(). 278 * This function instead of gpio_free() should be used to manually 279 * free GPIOs allocated with devm_gpio_request(). 280 */ 281void devm_gpio_free(struct device *dev, unsigned int gpio) 282{ 283 284 WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match, 285 &gpio)); 286} 287EXPORT_SYMBOL(devm_gpio_free);