Blame view

drivers/gpio/devres.c 2.35 KB
1a0703ede   John Crispin   GPIO: add binding...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  /*
   * drivers/gpio/devres.c - managed gpio resources
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2
   * as published by the Free Software Foundation.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * This file is based on kernel/irq/devres.c
   *
   * Copyright (c) 2011 John Crispin <blogic@openwrt.org>
   */
  
  #include <linux/module.h>
  #include <linux/gpio.h>
  #include <linux/device.h>
  #include <linux/gfp.h>
  
  static void devm_gpio_release(struct device *dev, void *res)
  {
  	unsigned *gpio = res;
  
  	gpio_free(*gpio);
  }
  
  static int devm_gpio_match(struct device *dev, void *res, void *data)
  {
  	unsigned *this = res, *gpio = data;
  
  	return *this == *gpio;
  }
  
  /**
   *      devm_gpio_request - request a gpio for a managed device
   *      @dev: device to request the gpio for
   *      @gpio: gpio to allocate
   *      @label: the name of the requested gpio
   *
   *      Except for the extra @dev argument, this function takes the
   *      same arguments and performs the same function as
   *      gpio_request().  GPIOs requested with this function will be
   *      automatically freed on driver detach.
   *
   *      If an GPIO allocated with this function needs to be freed
   *      separately, devm_gpio_free() must be used.
   */
  
  int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
  {
  	unsigned *dr;
  	int rc;
  
  	dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
  	if (!dr)
  		return -ENOMEM;
  
  	rc = gpio_request(gpio, label);
  	if (rc) {
  		devres_free(dr);
  		return rc;
  	}
  
  	*dr = gpio;
  	devres_add(dev, dr);
  
  	return 0;
  }
  EXPORT_SYMBOL(devm_gpio_request);
  
  /**
   *      devm_gpio_free - free an interrupt
   *      @dev: device to free gpio for
   *      @gpio: gpio to free
   *
   *      Except for the extra @dev argument, this function takes the
   *      same arguments and performs the same function as gpio_free().
   *      This function instead of gpio_free() should be used to manually
   *      free GPIOs allocated with devm_gpio_request().
   */
  void devm_gpio_free(struct device *dev, unsigned int gpio)
  {
  
  	WARN_ON(devres_destroy(dev, devm_gpio_release, devm_gpio_match,
  		&gpio));
  	gpio_free(gpio);
  }
  EXPORT_SYMBOL(devm_gpio_free);