[ar7] fix cpmac panics with 2.6.32 (#6764)
[openwrt.git] / target / linux / generic-2.6 / patches-2.6.25 / 963-backport_gpio_chip_reserve.patch
1 From: Anton Vorontsov <avorontsov@ru.mvista.com>
2 Date: Mon, 28 Apr 2008 09:14:47 +0000 (-0700)
3 Subject: gpiochip_reserve()
4 X-Git-Tag: v2.6.26-rc1~847
5 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=169b6a7a6e91e1ea32136681b475cbaf2074bf35
6
7 gpiochip_reserve()
8
9 Add a new function gpiochip_reserve() to reserve ranges of gpios that platform
10 code has pre-allocated. That is, this marks gpio numbers which will be
11 claimed by drivers that haven't yet been loaded, and thus are not available
12 for dynamic gpio number allocation.
13
14 [akpm@linux-foundation.org: remove unneeded __must_check]
15 [david-b@pacbell.net: don't export gpiochip_reserve (section fix)]
16 Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
17 Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
18 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
19 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
20 ---
21
22 --- a/drivers/gpio/gpiolib.c
23 +++ b/drivers/gpio/gpiolib.c
24 @@ -43,6 +43,7 @@ struct gpio_desc {
25 /* flag symbols are bit numbers */
26 #define FLAG_REQUESTED 0
27 #define FLAG_IS_OUT 1
28 +#define FLAG_RESERVED 2
29
30 #ifdef CONFIG_DEBUG_FS
31 const char *label;
32 @@ -88,9 +89,10 @@ static int gpiochip_find_base(int ngpio)
33 int base = -ENOSPC;
34
35 for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) {
36 - struct gpio_chip *chip = gpio_desc[i].chip;
37 + struct gpio_desc *desc = &gpio_desc[i];
38 + struct gpio_chip *chip = desc->chip;
39
40 - if (!chip) {
41 + if (!chip && !test_bit(FLAG_RESERVED, &desc->flags)) {
42 spare++;
43 if (spare == ngpio) {
44 base = i;
45 @@ -98,7 +100,8 @@ static int gpiochip_find_base(int ngpio)
46 }
47 } else {
48 spare = 0;
49 - i -= chip->ngpio - 1;
50 + if (chip)
51 + i -= chip->ngpio - 1;
52 }
53 }
54
55 @@ -108,6 +111,47 @@ static int gpiochip_find_base(int ngpio)
56 }
57
58 /**
59 + * gpiochip_reserve() - reserve range of gpios to use with platform code only
60 + * @start: starting gpio number
61 + * @ngpio: number of gpios to reserve
62 + * Context: platform init, potentially before irqs or kmalloc will work
63 + *
64 + * Returns a negative errno if any gpio within the range is already reserved
65 + * or registered, else returns zero as a success code. Use this function
66 + * to mark a range of gpios as unavailable for dynamic gpio number allocation,
67 + * for example because its driver support is not yet loaded.
68 + */
69 +int __init gpiochip_reserve(int start, int ngpio)
70 +{
71 + int ret = 0;
72 + unsigned long flags;
73 + int i;
74 +
75 + if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio))
76 + return -EINVAL;
77 +
78 + spin_lock_irqsave(&gpio_lock, flags);
79 +
80 + for (i = start; i < start + ngpio; i++) {
81 + struct gpio_desc *desc = &gpio_desc[i];
82 +
83 + if (desc->chip || test_bit(FLAG_RESERVED, &desc->flags)) {
84 + ret = -EBUSY;
85 + goto err;
86 + }
87 +
88 + set_bit(FLAG_RESERVED, &desc->flags);
89 + }
90 +
91 + pr_debug("%s: reserved gpios from %d to %d\n",
92 + __func__, start, start + ngpio - 1);
93 +err:
94 + spin_unlock_irqrestore(&gpio_lock, flags);
95 +
96 + return ret;
97 +}
98 +
99 +/**
100 * gpiochip_add() - register a gpio_chip
101 * @chip: the chip to register, with chip->base initialized
102 * Context: potentially before irqs or kmalloc will work
103 --- a/include/asm-generic/gpio.h
104 +++ b/include/asm-generic/gpio.h
105 @@ -74,6 +74,7 @@ struct gpio_chip {
106
107 extern const char *gpiochip_is_requested(struct gpio_chip *chip,
108 unsigned offset);
109 +extern int __init __must_check gpiochip_reserve(int start, int ngpio);
110
111 /* add/remove chips */
112 extern int gpiochip_add(struct gpio_chip *chip);
This page took 0.048791 seconds and 5 git commands to generate.