at v3.16-rc2 6.6 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 * 43 * Managed gpiod_get(). GPIO descriptors returned from this function are 44 * automatically disposed on driver detach. See gpiod_get() for detailed 45 * information about behavior and return values. 46 */ 47struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, 48 const char *con_id) 49{ 50 return devm_gpiod_get_index(dev, con_id, 0); 51} 52EXPORT_SYMBOL(devm_gpiod_get); 53 54/** 55 * devm_gpiod_get_optional - Resource-managed gpiod_get_optional() 56 * @dev: GPIO consumer 57 * @con_id: function within the GPIO consumer 58 * 59 * Managed gpiod_get_optional(). GPIO descriptors returned from this function 60 * are automatically disposed on driver detach. See gpiod_get_optional() for 61 * detailed information about behavior and return values. 62 */ 63struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev, 64 const char *con_id) 65{ 66 return devm_gpiod_get_index_optional(dev, con_id, 0); 67} 68EXPORT_SYMBOL(devm_gpiod_get_optional); 69 70/** 71 * devm_gpiod_get_index - Resource-managed gpiod_get_index() 72 * @dev: GPIO consumer 73 * @con_id: function within the GPIO consumer 74 * @idx: index of the GPIO to obtain in the consumer 75 * 76 * Managed gpiod_get_index(). GPIO descriptors returned from this function are 77 * automatically disposed on driver detach. See gpiod_get_index() for detailed 78 * information about behavior and return values. 79 */ 80struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, 81 const char *con_id, 82 unsigned int idx) 83{ 84 struct gpio_desc **dr; 85 struct gpio_desc *desc; 86 87 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpiod_desc *), 88 GFP_KERNEL); 89 if (!dr) 90 return ERR_PTR(-ENOMEM); 91 92 desc = gpiod_get_index(dev, con_id, idx); 93 if (IS_ERR(desc)) { 94 devres_free(dr); 95 return desc; 96 } 97 98 *dr = desc; 99 devres_add(dev, dr); 100 101 return desc; 102} 103EXPORT_SYMBOL(devm_gpiod_get_index); 104 105/** 106 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() 107 * @dev: GPIO consumer 108 * @con_id: function within the GPIO consumer 109 * @index: index of the GPIO to obtain in the consumer 110 * 111 * Managed gpiod_get_index_optional(). GPIO descriptors returned from this 112 * function are automatically disposed on driver detach. See 113 * gpiod_get_index_optional() for detailed information about behavior and 114 * return values. 115 */ 116struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev, 117 const char *con_id, 118 unsigned int index) 119{ 120 struct gpio_desc *desc; 121 122 desc = devm_gpiod_get_index(dev, con_id, index); 123 if (IS_ERR(desc)) { 124 if (PTR_ERR(desc) == -ENOENT) 125 return NULL; 126 } 127 128 return desc; 129} 130EXPORT_SYMBOL(devm_gpiod_get_index_optional); 131 132/** 133 * devm_gpiod_put - Resource-managed gpiod_put() 134 * @desc: GPIO descriptor to dispose of 135 * 136 * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or 137 * devm_gpiod_get_index(). Normally this function will not be called as the GPIO 138 * will be disposed of by the resource management code. 139 */ 140void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 141{ 142 WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match, 143 &desc)); 144} 145EXPORT_SYMBOL(devm_gpiod_put); 146 147 148 149 150static void devm_gpio_release(struct device *dev, void *res) 151{ 152 unsigned *gpio = res; 153 154 gpio_free(*gpio); 155} 156 157static int devm_gpio_match(struct device *dev, void *res, void *data) 158{ 159 unsigned *this = res, *gpio = data; 160 161 return *this == *gpio; 162} 163 164/** 165 * devm_gpio_request - request a GPIO for a managed device 166 * @dev: device to request the GPIO for 167 * @gpio: GPIO to allocate 168 * @label: the name of the requested GPIO 169 * 170 * Except for the extra @dev argument, this function takes the 171 * same arguments and performs the same function as 172 * gpio_request(). GPIOs requested with this function will be 173 * automatically freed on driver detach. 174 * 175 * If an GPIO allocated with this function needs to be freed 176 * separately, devm_gpio_free() must be used. 177 */ 178 179int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) 180{ 181 unsigned *dr; 182 int rc; 183 184 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); 185 if (!dr) 186 return -ENOMEM; 187 188 rc = gpio_request(gpio, label); 189 if (rc) { 190 devres_free(dr); 191 return rc; 192 } 193 194 *dr = gpio; 195 devres_add(dev, dr); 196 197 return 0; 198} 199EXPORT_SYMBOL(devm_gpio_request); 200 201/** 202 * devm_gpio_request_one - request a single GPIO with initial setup 203 * @dev: device to request for 204 * @gpio: the GPIO number 205 * @flags: GPIO configuration as specified by GPIOF_* 206 * @label: a literal description string of this GPIO 207 */ 208int devm_gpio_request_one(struct device *dev, unsigned gpio, 209 unsigned long flags, const char *label) 210{ 211 unsigned *dr; 212 int rc; 213 214 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); 215 if (!dr) 216 return -ENOMEM; 217 218 rc = gpio_request_one(gpio, flags, label); 219 if (rc) { 220 devres_free(dr); 221 return rc; 222 } 223 224 *dr = gpio; 225 devres_add(dev, dr); 226 227 return 0; 228} 229EXPORT_SYMBOL(devm_gpio_request_one); 230 231/** 232 * devm_gpio_free - free a GPIO 233 * @dev: device to free GPIO for 234 * @gpio: GPIO to free 235 * 236 * Except for the extra @dev argument, this function takes the 237 * same arguments and performs the same function as gpio_free(). 238 * This function instead of gpio_free() should be used to manually 239 * free GPIOs allocated with devm_gpio_request(). 240 */ 241void devm_gpio_free(struct device *dev, unsigned int gpio) 242{ 243 244 WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match, 245 &gpio)); 246} 247EXPORT_SYMBOL(devm_gpio_free);