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