From 8a0cecffeb52363a57257bbbbd58f4c4537a75bb Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 2 Apr 2009 16:57:06 -0700 Subject: [PATCH] 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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/feature-removal-schedule.txt | 10 ++++++++++ Documentation/gpio.txt | 23 +++++++++------------- drivers/gpio/gpiolib.c | 12 +++++++---- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index d0f354670646..a23361e80c64 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -255,6 +255,16 @@ Who: Jan Engelhardt --------------------------- +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 +--------------------------- + What: b43 support for firmware revision < 410 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. diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index b1b988701247..145c25a170c7 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -123,7 +123,10 @@ platform-specific implementation issue. 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: /* 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 of a GPIO implicitly requests that GPIO (see below) if it has not been -requested already. That compatibility may be removed in the future; -explicitly requesting GPIOs is strongly preferred. +requested already. That compatibility is being removed from the optional +gpiolib framework. 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 @@ -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 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); @@ -212,10 +215,9 @@ for GPIOs that can't be accessed from IRQ handlers, these calls act the 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. -However, many platforms don't currently support this mechanism. /* request GPIO, returning 0 or negative errno. * 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 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 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). diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 83c3fe3a136b..51a8d4103be5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -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 * message should motivate switching to explicit requests... so should * 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) { - if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { - struct gpio_chip *chip = desc->chip; - int gpio = chip->base + offset; + const struct gpio_chip *chip = desc->chip; + const 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)) { pr_err("GPIO-%d: module can't be gotten \n", gpio); clear_bit(FLAG_REQUESTED, &desc->flags); /* lose */ return -EIO; } - pr_warning("GPIO-%d autorequested\n", gpio); desc_set_label(desc, "[auto]"); /* caller must chip->request() w/o spinlock */ if (chip->request)