[coldfire]: remove 2.6.25 support
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-2.6.25 / 960-backport_gpiolib_better_rmmod_infrastructure.patch
1 From: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
2 Date: Mon, 28 Apr 2008 09:14:44 +0000 (-0700)
3 Subject: gpiolib: better rmmod infrastructure
4 X-Git-Tag: v2.6.26-rc1~851
5 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=438d8908b379b6322fc3b28d45c9ebdddf58bc20
6
7 gpiolib: better rmmod infrastructure
8
9 As long as one or more GPIOs on a gpio chip are used its driver should not be
10 unloaded. The existing mechanism (gpiochip_remove failure) doesn't address
11 that, since rmmod can no longer be made to fail by having the cleanup code
12 report errors. Module usecounts are the solution.
13
14 Assuming standard "initialize struct to zero" policies, this change won't
15 affect SOC platform drivers. However, drivers for external chips (on I2C and
16 SPI busses) should be updated if they can be built as modules.
17
18 Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
19 [ gpio_ensure_requested() needs to update module usecounts too ]
20 Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
21 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
22 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
23 ---
24
25 --- a/drivers/gpio/gpiolib.c
26 +++ b/drivers/gpio/gpiolib.c
27 @@ -68,6 +68,9 @@ static void gpio_ensure_requested(struct
28 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
29 pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc));
30 desc_set_label(desc, "[auto]");
31 + if (!try_module_get(desc->chip->owner))
32 + pr_err("GPIO-%d: module can't be gotten \n",
33 + (int)(desc - gpio_desc));
34 }
35 }
36
37 @@ -177,6 +180,9 @@ int gpio_request(unsigned gpio, const ch
38 if (desc->chip == NULL)
39 goto done;
40
41 + if (!try_module_get(desc->chip->owner))
42 + goto done;
43 +
44 /* NOTE: gpio_request() can be called in early boot,
45 * before IRQs are enabled.
46 */
47 @@ -184,8 +190,10 @@ int gpio_request(unsigned gpio, const ch
48 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
49 desc_set_label(desc, label ? : "?");
50 status = 0;
51 - } else
52 + } else {
53 status = -EBUSY;
54 + module_put(desc->chip->owner);
55 + }
56
57 done:
58 if (status)
59 @@ -209,9 +217,10 @@ void gpio_free(unsigned gpio)
60 spin_lock_irqsave(&gpio_lock, flags);
61
62 desc = &gpio_desc[gpio];
63 - if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags))
64 + if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) {
65 desc_set_label(desc, NULL);
66 - else
67 + module_put(desc->chip->owner);
68 + } else
69 WARN_ON(extra_checks);
70
71 spin_unlock_irqrestore(&gpio_lock, flags);
72 --- a/include/asm-generic/gpio.h
73 +++ b/include/asm-generic/gpio.h
74 @@ -17,6 +17,7 @@
75 #endif
76
77 struct seq_file;
78 +struct module;
79
80 /**
81 * struct gpio_chip - abstract a GPIO controller
82 @@ -48,6 +49,7 @@ struct seq_file;
83 */
84 struct gpio_chip {
85 char *label;
86 + struct module *owner;
87
88 int (*direction_input)(struct gpio_chip *chip,
89 unsigned offset);