summaryrefslogtreecommitdiff
path: root/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch')
-rw-r--r--packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch746
1 files changed, 0 insertions, 746 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch b/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch
deleted file mode 100644
index f39fedbbaa..0000000000
--- a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch
+++ /dev/null
@@ -1,746 +0,0 @@
-From 3a0251c01446f3a6763e4406ca5495102db63aa4 Mon Sep 17 00:00:00 2001
-From: David Brownell <dbrownell@users.sourceforge.net>
-Date: Fri, 18 Jan 2008 00:35:20 +0300
-Subject: [PATCH 22/64] Provide new implementation infrastructure that platforms may choose to use
- when implementing the GPIO programming interface. Platforms can update their
- GPIO support to use this. In many cases the incremental cost to access a
- non-inlined GPIO should be less than a dozen instructions, with the memory
- cost being about a page (total) of extra data and code. The upside is:
-
- * Providing two features which were "want to have (but OK to defer)" when
- GPIO interfaces were first discussed in November 2006:
-
- - A "struct gpio_chip" to plug in GPIOs that aren't directly supported
- by SOC platforms, but come from FPGAs or other multifunction devices
- using conventional device registers (like UCB-1x00 or SM501 GPIOs,
- and southbridges in PCs with more open specs than usual).
-
- - Full support for message-based GPIO expanders, where registers are
- accessed through sleeping I/O calls. Previous support for these
- "cansleep" calls was just stubs. (One example: the widely used
- pcf8574 I2C chips, with 8 GPIOs each.)
-
- * Including a non-stub implementation of the gpio_{request,free}() calls,
- making those calls much more useful. The diagnostic labels are also
- recorded given DEBUG_FS, so /sys/kernel/debug/gpio can show a snapshot
- of all GPIOs known to this infrastructure.
-
-The driver programming interfaces introduced in 2.6.21 do not change at all;
-this infrastructure is entirely below those covers.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Cc: Sam Ravnborg <sam@ravnborg.org>
-Cc: Jean Delvare <khali@linux-fr.org>
-Cc: Eric Miao <eric.miao@marvell.com>
-Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
-Cc: Philipp Zabel <philipp.zabel@gmail.com>
-Cc: Russell King <rmk@arm.linux.org.uk>
-Cc: Ben Gardner <bgardner@wabtec.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
- drivers/gpio/Makefile | 2 +
- drivers/gpio/gpiolib.c | 567 ++++++++++++++++++++++++++++++++++++++++++++
- include/asm-generic/gpio.h | 98 ++++++++
- 3 files changed, 667 insertions(+), 0 deletions(-)
- create mode 100644 drivers/gpio/gpiolib.c
-
-diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
-index cdbba6b..2db28ce 100644
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -1,3 +1,5 @@
- # gpio support: dedicated expander chips, etc
-
- ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
-+
-+obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-new file mode 100644
-index 0000000..d8db2f8
---- /dev/null
-+++ b/drivers/gpio/gpiolib.c
-@@ -0,0 +1,567 @@
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/irq.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/gpio.h>
-+
-+
-+/* Optional implementation infrastructure for GPIO interfaces.
-+ *
-+ * Platforms may want to use this if they tend to use very many GPIOs
-+ * that aren't part of a System-On-Chip core; or across I2C/SPI/etc.
-+ *
-+ * When kernel footprint or instruction count is an issue, simpler
-+ * implementations may be preferred. The GPIO programming interface
-+ * allows for inlining speed-critical get/set operations for common
-+ * cases, so that access to SOC-integrated GPIOs can sometimes cost
-+ * only an instruction or two per bit.
-+ */
-+
-+
-+/* When debugging, extend minimal trust to callers and platform code.
-+ * Also emit diagnostic messages that may help initial bringup, when
-+ * board setup or driver bugs are most common.
-+ *
-+ * Otherwise, minimize overhead in what may be bitbanging codepaths.
-+ */
-+#ifdef DEBUG
-+#define extra_checks 1
-+#else
-+#define extra_checks 0
-+#endif
-+
-+/* gpio_lock prevents conflicts during gpio_desc[] table updates.
-+ * While any GPIO is requested, its gpio_chip is not removable;
-+ * each GPIO's "requested" flag serves as a lock and refcount.
-+ */
-+static DEFINE_SPINLOCK(gpio_lock);
-+
-+struct gpio_desc {
-+ struct gpio_chip *chip;
-+ unsigned long flags;
-+/* flag symbols are bit numbers */
-+#define FLAG_REQUESTED 0
-+#define FLAG_IS_OUT 1
-+
-+#ifdef CONFIG_DEBUG_FS
-+ const char *label;
-+#endif
-+};
-+static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
-+
-+static inline void desc_set_label(struct gpio_desc *d, const char *label)
-+{
-+#ifdef CONFIG_DEBUG_FS
-+ d->label = label;
-+#endif
-+}
-+
-+/* Warn when drivers omit gpio_request() calls -- legal but ill-advised
-+ * when setting direction, and otherwise illegal. Until board setup code
-+ * and drivers use explicit requests everywhere (which won't happen when
-+ * those calls have no teeth) we can't avoid autorequesting. This nag
-+ * message should motivate switching to explicit requests...
-+ */
-+static void gpio_ensure_requested(struct gpio_desc *desc)
-+{
-+ 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]");
-+ }
-+}
-+
-+/* caller holds gpio_lock *OR* gpio is marked as requested */
-+static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
-+{
-+ return gpio_desc[gpio].chip;
-+}
-+
-+/**
-+ * gpiochip_add() - register a gpio_chip
-+ * @chip: the chip to register, with chip->base initialized
-+ * Context: potentially before irqs or kmalloc will work
-+ *
-+ * Returns a negative errno if the chip can't be registered, such as
-+ * because the chip->base is invalid or already associated with a
-+ * different chip. Otherwise it returns zero as a success code.
-+ */
-+int gpiochip_add(struct gpio_chip *chip)
-+{
-+ unsigned long flags;
-+ int status = 0;
-+ unsigned id;
-+
-+ /* NOTE chip->base negative is reserved to mean a request for
-+ * dynamic allocation. We don't currently support that.
-+ */
-+
-+ if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) {
-+ status = -EINVAL;
-+ goto fail;
-+ }
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ /* these GPIO numbers must not be managed by another gpio_chip */
-+ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
-+ if (gpio_desc[id].chip != NULL) {
-+ status = -EBUSY;
-+ break;
-+ }
-+ }
-+ if (status == 0) {
-+ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
-+ gpio_desc[id].chip = chip;
-+ gpio_desc[id].flags = 0;
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+fail:
-+ /* failures here can mean systems won't boot... */
-+ if (status)
-+ pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n",
-+ chip->base, chip->base + chip->ngpio,
-+ chip->label ? : "generic");
-+ return status;
-+}
-+EXPORT_SYMBOL_GPL(gpiochip_add);
-+
-+/**
-+ * gpiochip_remove() - unregister a gpio_chip
-+ * @chip: the chip to unregister
-+ *
-+ * A gpio_chip with any GPIOs still requested may not be removed.
-+ */
-+int gpiochip_remove(struct gpio_chip *chip)
-+{
-+ unsigned long flags;
-+ int status = 0;
-+ unsigned id;
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
-+ if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
-+ status = -EBUSY;
-+ break;
-+ }
-+ }
-+ if (status == 0) {
-+ for (id = chip->base; id < chip->base + chip->ngpio; id++)
-+ gpio_desc[id].chip = NULL;
-+ }
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ return status;
-+}
-+EXPORT_SYMBOL_GPL(gpiochip_remove);
-+
-+
-+/* These "optional" allocation calls help prevent drivers from stomping
-+ * on each other, and help provide better diagnostics in debugfs.
-+ * They're called even less than the "set direction" calls.
-+ */
-+int gpio_request(unsigned gpio, const char *label)
-+{
-+ struct gpio_desc *desc;
-+ int status = -EINVAL;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ if (gpio >= ARCH_NR_GPIOS)
-+ goto done;
-+ desc = &gpio_desc[gpio];
-+ if (desc->chip == NULL)
-+ goto done;
-+
-+ /* NOTE: gpio_request() can be called in early boot,
-+ * before IRQs are enabled.
-+ */
-+
-+ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
-+ desc_set_label(desc, label ? : "?");
-+ status = 0;
-+ } else
-+ status = -EBUSY;
-+
-+done:
-+ if (status)
-+ pr_debug("gpio_request: gpio-%d (%s) status %d\n",
-+ gpio, label ? : "?", status);
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ return status;
-+}
-+EXPORT_SYMBOL_GPL(gpio_request);
-+
-+void gpio_free(unsigned gpio)
-+{
-+ unsigned long flags;
-+ struct gpio_desc *desc;
-+
-+ if (gpio >= ARCH_NR_GPIOS) {
-+ WARN_ON(extra_checks);
-+ return;
-+ }
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ desc = &gpio_desc[gpio];
-+ if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags))
-+ desc_set_label(desc, NULL);
-+ else
-+ WARN_ON(extra_checks);
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(gpio_free);
-+
-+
-+/**
-+ * gpiochip_is_requested - return string iff signal was requested
-+ * @chip: controller managing the signal
-+ * @offset: of signal within controller's 0..(ngpio - 1) range
-+ *
-+ * Returns NULL if the GPIO is not currently requested, else a string.
-+ * If debugfs support is enabled, the string returned is the label passed
-+ * to gpio_request(); otherwise it is a meaningless constant.
-+ *
-+ * This function is for use by GPIO controller drivers. The label can
-+ * help with diagnostics, and knowing that the signal is used as a GPIO
-+ * can help avoid accidentally multiplexing it to another controller.
-+ */
-+const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
-+{
-+ unsigned gpio = chip->base + offset;
-+
-+ if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip)
-+ return NULL;
-+ if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0)
-+ return NULL;
-+#ifdef CONFIG_DEBUG_FS
-+ return gpio_desc[gpio].label;
-+#else
-+ return "?";
-+#endif
-+}
-+EXPORT_SYMBOL_GPL(gpiochip_is_requested);
-+
-+
-+/* Drivers MUST set GPIO direction before making get/set calls. In
-+ * some cases this is done in early boot, before IRQs are enabled.
-+ *
-+ * As a rule these aren't called more than once (except for drivers
-+ * using the open-drain emulation idiom) so these are natural places
-+ * to accumulate extra debugging checks. Note that we can't (yet)
-+ * rely on gpio_request() having been called beforehand.
-+ */
-+
-+int gpio_direction_input(unsigned gpio)
-+{
-+ unsigned long flags;
-+ struct gpio_chip *chip;
-+ struct gpio_desc *desc = &gpio_desc[gpio];
-+ int status = -EINVAL;
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ if (gpio >= ARCH_NR_GPIOS)
-+ goto fail;
-+ chip = desc->chip;
-+ if (!chip || !chip->get || !chip->direction_input)
-+ goto fail;
-+ gpio -= chip->base;
-+ if (gpio >= chip->ngpio)
-+ goto fail;
-+ gpio_ensure_requested(desc);
-+
-+ /* now we know the gpio is valid and chip won't vanish */
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+
-+ might_sleep_if(extra_checks && chip->can_sleep);
-+
-+ status = chip->direction_input(chip, gpio);
-+ if (status == 0)
-+ clear_bit(FLAG_IS_OUT, &desc->flags);
-+ return status;
-+fail:
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ if (status)
-+ pr_debug("%s: gpio-%d status %d\n",
-+ __FUNCTION__, gpio, status);
-+ return status;
-+}
-+EXPORT_SYMBOL_GPL(gpio_direction_input);
-+
-+int gpio_direction_output(unsigned gpio, int value)
-+{
-+ unsigned long flags;
-+ struct gpio_chip *chip;
-+ struct gpio_desc *desc = &gpio_desc[gpio];
-+ int status = -EINVAL;
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ if (gpio >= ARCH_NR_GPIOS)
-+ goto fail;
-+ chip = desc->chip;
-+ if (!chip || !chip->set || !chip->direction_output)
-+ goto fail;
-+ gpio -= chip->base;
-+ if (gpio >= chip->ngpio)
-+ goto fail;
-+ gpio_ensure_requested(desc);
-+
-+ /* now we know the gpio is valid and chip won't vanish */
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+
-+ might_sleep_if(extra_checks && chip->can_sleep);
-+
-+ status = chip->direction_output(chip, gpio, value);
-+ if (status == 0)
-+ set_bit(FLAG_IS_OUT, &desc->flags);
-+ return status;
-+fail:
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ if (status)
-+ pr_debug("%s: gpio-%d status %d\n",
-+ __FUNCTION__, gpio, status);
-+ return status;
-+}
-+EXPORT_SYMBOL_GPL(gpio_direction_output);
-+
-+
-+/* I/O calls are only valid after configuration completed; the relevant
-+ * "is this a valid GPIO" error checks should already have been done.
-+ *
-+ * "Get" operations are often inlinable as reading a pin value register,
-+ * and masking the relevant bit in that register.
-+ *
-+ * When "set" operations are inlinable, they involve writing that mask to
-+ * one register to set a low value, or a different register to set it high.
-+ * Otherwise locking is needed, so there may be little value to inlining.
-+ *
-+ *------------------------------------------------------------------------
-+ *
-+ * IMPORTANT!!! The hot paths -- get/set value -- assume that callers
-+ * have requested the GPIO. That can include implicit requesting by
-+ * a direction setting call. Marking a gpio as requested locks its chip
-+ * in memory, guaranteeing that these table lookups need no more locking
-+ * and that gpiochip_remove() will fail.
-+ *
-+ * REVISIT when debugging, consider adding some instrumentation to ensure
-+ * that the GPIO was actually requested.
-+ */
-+
-+/**
-+ * __gpio_get_value() - return a gpio's value
-+ * @gpio: gpio whose value will be returned
-+ * Context: any
-+ *
-+ * This is used directly or indirectly to implement gpio_get_value().
-+ * It returns the zero or nonzero value provided by the associated
-+ * gpio_chip.get() method; or zero if no such method is provided.
-+ */
-+int __gpio_get_value(unsigned gpio)
-+{
-+ struct gpio_chip *chip;
-+
-+ chip = gpio_to_chip(gpio);
-+ WARN_ON(extra_checks && chip->can_sleep);
-+ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
-+}
-+EXPORT_SYMBOL_GPL(__gpio_get_value);
-+
-+/**
-+ * __gpio_set_value() - assign a gpio's value
-+ * @gpio: gpio whose value will be assigned
-+ * @value: value to assign
-+ * Context: any
-+ *
-+ * This is used directly or indirectly to implement gpio_set_value().
-+ * It invokes the associated gpio_chip.set() method.
-+ */
-+void __gpio_set_value(unsigned gpio, int value)
-+{
-+ struct gpio_chip *chip;
-+
-+ chip = gpio_to_chip(gpio);
-+ WARN_ON(extra_checks && chip->can_sleep);
-+ chip->set(chip, gpio - chip->base, value);
-+}
-+EXPORT_SYMBOL_GPL(__gpio_set_value);
-+
-+/**
-+ * __gpio_cansleep() - report whether gpio value access will sleep
-+ * @gpio: gpio in question
-+ * Context: any
-+ *
-+ * This is used directly or indirectly to implement gpio_cansleep(). It
-+ * returns nonzero if access reading or writing the GPIO value can sleep.
-+ */
-+int __gpio_cansleep(unsigned gpio)
-+{
-+ struct gpio_chip *chip;
-+
-+ /* only call this on GPIOs that are valid! */
-+ chip = gpio_to_chip(gpio);
-+
-+ return chip->can_sleep;
-+}
-+EXPORT_SYMBOL_GPL(__gpio_cansleep);
-+
-+
-+
-+/* There's no value in making it easy to inline GPIO calls that may sleep.
-+ * Common examples include ones connected to I2C or SPI chips.
-+ */
-+
-+int gpio_get_value_cansleep(unsigned gpio)
-+{
-+ struct gpio_chip *chip;
-+
-+ might_sleep_if(extra_checks);
-+ chip = gpio_to_chip(gpio);
-+ return chip->get(chip, gpio - chip->base);
-+}
-+EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
-+
-+void gpio_set_value_cansleep(unsigned gpio, int value)
-+{
-+ struct gpio_chip *chip;
-+
-+ might_sleep_if(extra_checks);
-+ chip = gpio_to_chip(gpio);
-+ chip->set(chip, gpio - chip->base, value);
-+}
-+EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);
-+
-+
-+#ifdef CONFIG_DEBUG_FS
-+
-+#include <linux/debugfs.h>
-+#include <linux/seq_file.h>
-+
-+
-+static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-+{
-+ unsigned i;
-+ unsigned gpio = chip->base;
-+ struct gpio_desc *gdesc = &gpio_desc[gpio];
-+ int is_out;
-+
-+ for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
-+ if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
-+ continue;
-+
-+ is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
-+ seq_printf(s, " gpio-%-3d (%-12s) %s %s",
-+ gpio, gdesc->label,
-+ is_out ? "out" : "in ",
-+ chip->get
-+ ? (chip->get(chip, i) ? "hi" : "lo")
-+ : "? ");
-+
-+ if (!is_out) {
-+ int irq = gpio_to_irq(gpio);
-+ struct irq_desc *desc = irq_desc + irq;
-+
-+ /* This races with request_irq(), set_irq_type(),
-+ * and set_irq_wake() ... but those are "rare".
-+ *
-+ * More significantly, trigger type flags aren't
-+ * currently maintained by genirq.
-+ */
-+ if (irq >= 0 && desc->action) {
-+ char *trigger;
-+
-+ switch (desc->status & IRQ_TYPE_SENSE_MASK) {
-+ case IRQ_TYPE_NONE:
-+ trigger = "(default)";
-+ break;
-+ case IRQ_TYPE_EDGE_FALLING:
-+ trigger = "edge-falling";
-+ break;
-+ case IRQ_TYPE_EDGE_RISING:
-+ trigger = "edge-rising";
-+ break;
-+ case IRQ_TYPE_EDGE_BOTH:
-+ trigger = "edge-both";
-+ break;
-+ case IRQ_TYPE_LEVEL_HIGH:
-+ trigger = "level-high";
-+ break;
-+ case IRQ_TYPE_LEVEL_LOW:
-+ trigger = "level-low";
-+ break;
-+ default:
-+ trigger = "?trigger?";
-+ break;
-+ }
-+
-+ seq_printf(s, " irq-%d %s%s",
-+ irq, trigger,
-+ (desc->status & IRQ_WAKEUP)
-+ ? " wakeup" : "");
-+ }
-+ }
-+
-+ seq_printf(s, "\n");
-+ }
-+}
-+
-+static int gpiolib_show(struct seq_file *s, void *unused)
-+{
-+ struct gpio_chip *chip = NULL;
-+ unsigned gpio;
-+ int started = 0;
-+
-+ /* REVISIT this isn't locked against gpio_chip removal ... */
-+
-+ for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) {
-+ if (chip == gpio_desc[gpio].chip)
-+ continue;
-+ chip = gpio_desc[gpio].chip;
-+ if (!chip)
-+ continue;
-+
-+ seq_printf(s, "%sGPIOs %d-%d, %s%s:\n",
-+ started ? "\n" : "",
-+ chip->base, chip->base + chip->ngpio - 1,
-+ chip->label ? : "generic",
-+ chip->can_sleep ? ", can sleep" : "");
-+ started = 1;
-+ if (chip->dbg_show)
-+ chip->dbg_show(s, chip);
-+ else
-+ gpiolib_dbg_show(s, chip);
-+ }
-+ return 0;
-+}
-+
-+static int gpiolib_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, gpiolib_show, NULL);
-+}
-+
-+static struct file_operations gpiolib_operations = {
-+ .open = gpiolib_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+static int __init gpiolib_debugfs_init(void)
-+{
-+ /* /sys/kernel/debug/gpio */
-+ (void) debugfs_create_file("gpio", S_IFREG | S_IRUGO,
-+ NULL, NULL, &gpiolib_operations);
-+ return 0;
-+}
-+subsys_initcall(gpiolib_debugfs_init);
-+
-+#endif /* DEBUG_FS */
-diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
-index 2d0aab1..f29a502 100644
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -1,6 +1,102 @@
- #ifndef _ASM_GENERIC_GPIO_H
- #define _ASM_GENERIC_GPIO_H
-
-+#ifdef CONFIG_HAVE_GPIO_LIB
-+
-+/* Platforms may implement their GPIO interface with library code,
-+ * at a small performance cost for non-inlined operations and some
-+ * extra memory (for code and for per-GPIO table entries).
-+ *
-+ * While the GPIO programming interface defines valid GPIO numbers
-+ * to be in the range 0..MAX_INT, this library restricts them to the
-+ * smaller range 0..ARCH_NR_GPIOS.
-+ */
-+
-+#ifndef ARCH_NR_GPIOS
-+#define ARCH_NR_GPIOS 256
-+#endif
-+
-+struct seq_file;
-+
-+/**
-+ * struct gpio_chip - abstract a GPIO controller
-+ * @label: for diagnostics
-+ * @direction_input: configures signal "offset" as input, or returns error
-+ * @get: returns value for signal "offset"; for output signals this
-+ * returns either the value actually sensed, or zero
-+ * @direction_output: configures signal "offset" as output, or returns error
-+ * @set: assigns output value for signal "offset"
-+ * @dbg_show: optional routine to show contents in debugfs; default code
-+ * will be used when this is omitted, but custom code can show extra
-+ * state (such as pullup/pulldown configuration).
-+ * @base: identifies the first GPIO number handled by this chip; or, if
-+ * negative during registration, requests dynamic ID allocation.
-+ * @ngpio: the number of GPIOs handled by this controller; the last GPIO
-+ * handled is (base + ngpio - 1).
-+ * @can_sleep: flag must be set iff get()/set() methods sleep, as they
-+ * must while accessing GPIO expander chips over I2C or SPI
-+ *
-+ * A gpio_chip can help platforms abstract various sources of GPIOs so
-+ * they can all be accessed through a common programing interface.
-+ * Example sources would be SOC controllers, FPGAs, multifunction
-+ * chips, dedicated GPIO expanders, and so on.
-+ *
-+ * Each chip controls a number of signals, identified in method calls
-+ * by "offset" values in the range 0..(@ngpio - 1). When those signals
-+ * are referenced through calls like gpio_get_value(gpio), the offset
-+ * is calculated by subtracting @base from the gpio number.
-+ */
-+struct gpio_chip {
-+ char *label;
-+
-+ int (*direction_input)(struct gpio_chip *chip,
-+ unsigned offset);
-+ int (*get)(struct gpio_chip *chip,
-+ unsigned offset);
-+ int (*direction_output)(struct gpio_chip *chip,
-+ unsigned offset, int value);
-+ void (*set)(struct gpio_chip *chip,
-+ unsigned offset, int value);
-+ void (*dbg_show)(struct seq_file *s,
-+ struct gpio_chip *chip);
-+ int base;
-+ u16 ngpio;
-+ unsigned can_sleep:1;
-+};
-+
-+extern const char *gpiochip_is_requested(struct gpio_chip *chip,
-+ unsigned offset);
-+
-+/* add/remove chips */
-+extern int gpiochip_add(struct gpio_chip *chip);
-+extern int __must_check gpiochip_remove(struct gpio_chip *chip);
-+
-+
-+/* Always use the library code for GPIO management calls,
-+ * or when sleeping may be involved.
-+ */
-+extern int gpio_request(unsigned gpio, const char *label);
-+extern void gpio_free(unsigned gpio);
-+
-+extern int gpio_direction_input(unsigned gpio);
-+extern int gpio_direction_output(unsigned gpio, int value);
-+
-+extern int gpio_get_value_cansleep(unsigned gpio);
-+extern void gpio_set_value_cansleep(unsigned gpio, int value);
-+
-+
-+/* A platform's <asm/gpio.h> code may want to inline the I/O calls when
-+ * the GPIO is constant and refers to some always-present controller,
-+ * giving direct access to chip registers and tight bitbanging loops.
-+ */
-+extern int __gpio_get_value(unsigned gpio);
-+extern void __gpio_set_value(unsigned gpio, int value);
-+
-+extern int __gpio_cansleep(unsigned gpio);
-+
-+
-+#else
-+
- /* platforms that don't directly support access to GPIOs through I2C, SPI,
- * or other blocking infrastructure can use these wrappers.
- */
-@@ -22,4 +118,6 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value)
- gpio_set_value(gpio, value);
- }
-
-+#endif
-+
- #endif /* _ASM_GENERIC_GPIO_H */
---
-1.5.3.8
-