diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:42:58 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:42:58 +0000 |
commit | a082943b09f4f707990ad0ac6326df8480507f02 (patch) | |
tree | de32e4def600e56134cd085a7447cb6620542078 /target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch | |
parent | 67fbcc7bd42cc07b1f3c6b5c9f2db37647178f25 (diff) | |
download | master-187ad058-a082943b09f4f707990ad0ac6326df8480507f02.tar.gz master-187ad058-a082943b09f4f707990ad0ac6326df8480507f02.tar.bz2 master-187ad058-a082943b09f4f707990ad0ac6326df8480507f02.zip |
rename target/linux/generic-2.6 to generic
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21952 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch')
-rw-r--r-- | target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch b/target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch new file mode 100644 index 0000000000..8da25daa75 --- /dev/null +++ b/target/linux/generic/patches-2.6.25/960-backport_gpiolib_better_rmmod_infrastructure.patch @@ -0,0 +1,89 @@ +From: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de> +Date: Mon, 28 Apr 2008 09:14:44 +0000 (-0700) +Subject: gpiolib: better rmmod infrastructure +X-Git-Tag: v2.6.26-rc1~851 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=438d8908b379b6322fc3b28d45c9ebdddf58bc20 + +gpiolib: better rmmod infrastructure + +As long as one or more GPIOs on a gpio chip are used its driver should not be +unloaded. The existing mechanism (gpiochip_remove failure) doesn't address +that, since rmmod can no longer be made to fail by having the cleanup code +report errors. Module usecounts are the solution. + +Assuming standard "initialize struct to zero" policies, this change won't +affect SOC platform drivers. However, drivers for external chips (on I2C and +SPI busses) should be updated if they can be built as modules. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de> +[ gpio_ensure_requested() needs to update module usecounts too ] +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +--- + +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -68,6 +68,9 @@ static void gpio_ensure_requested(struct + if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { + pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); + desc_set_label(desc, "[auto]"); ++ if (!try_module_get(desc->chip->owner)) ++ pr_err("GPIO-%d: module can't be gotten \n", ++ (int)(desc - gpio_desc)); + } + } + +@@ -177,6 +180,9 @@ int gpio_request(unsigned gpio, const ch + if (desc->chip == NULL) + goto done; + ++ if (!try_module_get(desc->chip->owner)) ++ goto done; ++ + /* NOTE: gpio_request() can be called in early boot, + * before IRQs are enabled. + */ +@@ -184,8 +190,10 @@ int gpio_request(unsigned gpio, const ch + if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { + desc_set_label(desc, label ? : "?"); + status = 0; +- } else ++ } else { + status = -EBUSY; ++ module_put(desc->chip->owner); ++ } + + done: + if (status) +@@ -209,9 +217,10 @@ void gpio_free(unsigned gpio) + spin_lock_irqsave(&gpio_lock, flags); + + desc = &gpio_desc[gpio]; +- if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) ++ if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { + desc_set_label(desc, NULL); +- else ++ module_put(desc->chip->owner); ++ } else + WARN_ON(extra_checks); + + spin_unlock_irqrestore(&gpio_lock, flags); +--- a/include/asm-generic/gpio.h ++++ b/include/asm-generic/gpio.h +@@ -17,6 +17,7 @@ + #endif + + struct seq_file; ++struct module; + + /** + * struct gpio_chip - abstract a GPIO controller +@@ -48,6 +49,7 @@ struct seq_file; + */ + struct gpio_chip { + char *label; ++ struct module *owner; + + int (*direction_input)(struct gpio_chip *chip, + unsigned offset); |