gpio: gpio_{request,free}() now required (feature removal)
We want to phase out the GPIO "autorequest" mechanism in gpiolib and require all callers to use gpio_request(). - Update feature-removal-schedule - Update the documentation now - Convert the relevant pr_warning() in gpiolib to a WARN() so folk using this mechanism get a noisy stack dump Some drivers and board init code will probably need to change. Implementations not using gpiolib will still be fine; they are already required to implement gpio_{request,free}() stubs. 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>
This commit is contained in:
Родитель
926b663ce8
Коммит
8a0cecffeb
|
@ -255,6 +255,16 @@ Who: Jan Engelhardt <jengelh@computergmbh.de>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib
|
||||||
|
When: February 2010
|
||||||
|
Why: All callers should use explicit gpio_request()/gpio_free().
|
||||||
|
The autorequest mechanism in gpiolib was provided mostly as a
|
||||||
|
migration aid for legacy GPIO interfaces (for SOC based GPIOs).
|
||||||
|
Those users have now largely migrated. Platforms implementing
|
||||||
|
the GPIO interfaces without using gpiolib will see no changes.
|
||||||
|
Who: David Brownell <dbrownell@users.sourceforge.net>
|
||||||
|
---------------------------
|
||||||
|
|
||||||
What: b43 support for firmware revision < 410
|
What: b43 support for firmware revision < 410
|
||||||
When: The schedule was July 2008, but it was decided that we are going to keep the
|
When: The schedule was July 2008, but it was decided that we are going to keep the
|
||||||
code as long as there are no major maintanance headaches.
|
code as long as there are no major maintanance headaches.
|
||||||
|
|
|
@ -123,7 +123,10 @@ platform-specific implementation issue.
|
||||||
|
|
||||||
Using GPIOs
|
Using GPIOs
|
||||||
-----------
|
-----------
|
||||||
One of the first things to do with a GPIO, often in board setup code when
|
The first thing a system should do with a GPIO is allocate it, using
|
||||||
|
the gpio_request() call; see later.
|
||||||
|
|
||||||
|
One of the next things to do with a GPIO, often in board setup code when
|
||||||
setting up a platform_device using the GPIO, is mark its direction:
|
setting up a platform_device using the GPIO, is mark its direction:
|
||||||
|
|
||||||
/* set as input or output, returning 0 or negative errno */
|
/* set as input or output, returning 0 or negative errno */
|
||||||
|
@ -141,8 +144,8 @@ This helps avoid signal glitching during system startup.
|
||||||
|
|
||||||
For compatibility with legacy interfaces to GPIOs, setting the direction
|
For compatibility with legacy interfaces to GPIOs, setting the direction
|
||||||
of a GPIO implicitly requests that GPIO (see below) if it has not been
|
of a GPIO implicitly requests that GPIO (see below) if it has not been
|
||||||
requested already. That compatibility may be removed in the future;
|
requested already. That compatibility is being removed from the optional
|
||||||
explicitly requesting GPIOs is strongly preferred.
|
gpiolib framework.
|
||||||
|
|
||||||
Setting the direction can fail if the GPIO number is invalid, or when
|
Setting the direction can fail if the GPIO number is invalid, or when
|
||||||
that particular GPIO can't be used in that mode. It's generally a bad
|
that particular GPIO can't be used in that mode. It's generally a bad
|
||||||
|
@ -195,7 +198,7 @@ This requires sleeping, which can't be done from inside IRQ handlers.
|
||||||
|
|
||||||
Platforms that support this type of GPIO distinguish them from other GPIOs
|
Platforms that support this type of GPIO distinguish them from other GPIOs
|
||||||
by returning nonzero from this call (which requires a valid GPIO number,
|
by returning nonzero from this call (which requires a valid GPIO number,
|
||||||
either explicitly or implicitly requested):
|
which should have been previously allocated with gpio_request):
|
||||||
|
|
||||||
int gpio_cansleep(unsigned gpio);
|
int gpio_cansleep(unsigned gpio);
|
||||||
|
|
||||||
|
@ -212,10 +215,9 @@ for GPIOs that can't be accessed from IRQ handlers, these calls act the
|
||||||
same as the spinlock-safe calls.
|
same as the spinlock-safe calls.
|
||||||
|
|
||||||
|
|
||||||
Claiming and Releasing GPIOs (OPTIONAL)
|
Claiming and Releasing GPIOs
|
||||||
---------------------------------------
|
----------------------------
|
||||||
To help catch system configuration errors, two calls are defined.
|
To help catch system configuration errors, two calls are defined.
|
||||||
However, many platforms don't currently support this mechanism.
|
|
||||||
|
|
||||||
/* request GPIO, returning 0 or negative errno.
|
/* request GPIO, returning 0 or negative errno.
|
||||||
* non-null labels may be useful for diagnostics.
|
* non-null labels may be useful for diagnostics.
|
||||||
|
@ -244,13 +246,6 @@ Some platforms may also use knowledge about what GPIOs are active for
|
||||||
power management, such as by powering down unused chip sectors and, more
|
power management, such as by powering down unused chip sectors and, more
|
||||||
easily, gating off unused clocks.
|
easily, gating off unused clocks.
|
||||||
|
|
||||||
These two calls are optional because not not all current Linux platforms
|
|
||||||
offer such functionality in their GPIO support; a valid implementation
|
|
||||||
could return success for all gpio_request() calls. Unlike the other calls,
|
|
||||||
the state they represent doesn't normally match anything from a hardware
|
|
||||||
register; it's just a software bitmap which clearly is not necessary for
|
|
||||||
correct operation of hardware or (bug free) drivers.
|
|
||||||
|
|
||||||
Note that requesting a GPIO does NOT cause it to be configured in any
|
Note that requesting a GPIO does NOT cause it to be configured in any
|
||||||
way; it just marks that GPIO as in use. Separate code must handle any
|
way; it just marks that GPIO as in use. Separate code must handle any
|
||||||
pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
|
pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
|
||||||
|
|
|
@ -69,20 +69,24 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
|
||||||
* those calls have no teeth) we can't avoid autorequesting. This nag
|
* those calls have no teeth) we can't avoid autorequesting. This nag
|
||||||
* message should motivate switching to explicit requests... so should
|
* message should motivate switching to explicit requests... so should
|
||||||
* the weaker cleanup after faults, compared to gpio_request().
|
* the weaker cleanup after faults, compared to gpio_request().
|
||||||
|
*
|
||||||
|
* NOTE: the autorequest mechanism is going away; at this point it's
|
||||||
|
* only "legal" in the sense that (old) code using it won't break yet,
|
||||||
|
* but instead only triggers a WARN() stack dump.
|
||||||
*/
|
*/
|
||||||
static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
|
static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
|
||||||
{
|
{
|
||||||
if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
|
const struct gpio_chip *chip = desc->chip;
|
||||||
struct gpio_chip *chip = desc->chip;
|
const int gpio = chip->base + offset;
|
||||||
int gpio = chip->base + offset;
|
|
||||||
|
|
||||||
|
if (WARN(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0,
|
||||||
|
"autorequest GPIO-%d\n", gpio)) {
|
||||||
if (!try_module_get(chip->owner)) {
|
if (!try_module_get(chip->owner)) {
|
||||||
pr_err("GPIO-%d: module can't be gotten \n", gpio);
|
pr_err("GPIO-%d: module can't be gotten \n", gpio);
|
||||||
clear_bit(FLAG_REQUESTED, &desc->flags);
|
clear_bit(FLAG_REQUESTED, &desc->flags);
|
||||||
/* lose */
|
/* lose */
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
pr_warning("GPIO-%d autorequested\n", gpio);
|
|
||||||
desc_set_label(desc, "[auto]");
|
desc_set_label(desc, "[auto]");
|
||||||
/* caller must chip->request() w/o spinlock */
|
/* caller must chip->request() w/o spinlock */
|
||||||
if (chip->request)
|
if (chip->request)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче