All of lore.kernel.org
 help / color / mirror / Atom feed
* [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-13 18:23 ` Kyle Moffett
  0 siblings, 0 replies; 24+ messages in thread
From: Kyle Moffett @ 2011-12-13 18:23 UTC (permalink / raw)
  To: linux-kernel; +Cc: Grant Likely, Linus Walleij, devicetree-discuss

Hello again,

I posted this patch series a few weeks ago and saw no responses, so I
tweaked the CC list and am reposting it again for review.

I'm working on support for some custom hardware of ours, and part of
the support code is the ability for the software to shutdown the power
supply using GPIOs (via an I2C GPIO controller).

I previously had this in my platform code, but it seemed generically
useful, so I split it out into a separate module for others to use.

The first two patches are generic of_gpio enhancements, providing some
new library functions for requesting lots of GPIOs at once.

The third patch is the actual driver itself.  The driver can be used to
instantiate a platform device as a whole-machine-poweroff device as we
use it on our hardware.  Alternatively it can instantiate multiple
platform devs at specific locations on the device tree which trigger
from the platform_driver->shutdown() callback.

For architectures which are still stuck in the dark ages, this driver
also supports being instantiated via legacy platform_data.

The OpenFirmware binding documentation is added in the third patch.
Since this is my first cut, it's a little rough, so please be gentle.

I'm interested to know what you all think.

Cheers,
Kyle Moffett

--
Interested in my work on the Debian "powerpcspe" port?
I'm keeping a blog here: http://pureperl.blogspot.com/


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-13 18:23 ` Kyle Moffett
  0 siblings, 0 replies; 24+ messages in thread
From: Kyle Moffett @ 2011-12-13 18:23 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

Hello again,

I posted this patch series a few weeks ago and saw no responses, so I
tweaked the CC list and am reposting it again for review.

I'm working on support for some custom hardware of ours, and part of
the support code is the ability for the software to shutdown the power
supply using GPIOs (via an I2C GPIO controller).

I previously had this in my platform code, but it seemed generically
useful, so I split it out into a separate module for others to use.

The first two patches are generic of_gpio enhancements, providing some
new library functions for requesting lots of GPIOs at once.

The third patch is the actual driver itself.  The driver can be used to
instantiate a platform device as a whole-machine-poweroff device as we
use it on our hardware.  Alternatively it can instantiate multiple
platform devs at specific locations on the device tree which trigger
from the platform_driver->shutdown() callback.

For architectures which are still stuck in the dark ages, this driver
also supports being instantiated via legacy platform_data.

The OpenFirmware binding documentation is added in the third patch.
Since this is my first cut, it's a little rough, so please be gentle.

I'm interested to know what you all think.

Cheers,
Kyle Moffett

--
Interested in my work on the Debian "powerpcspe" port?
I'm keeping a blog here: http://pureperl.blogspot.com/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [REPOST RFC PATCH 1/3] of_gpio: Extend of_gpio_count() to support other property names
  2011-12-13 18:23 ` Kyle Moffett
  (?)
@ 2011-12-13 18:23 ` Kyle Moffett
  -1 siblings, 0 replies; 24+ messages in thread
From: Kyle Moffett @ 2011-12-13 18:23 UTC (permalink / raw)
  To: linux-kernel
  Cc: Grant Likely, Linus Walleij, devicetree-discuss, Kyle Moffett,
	Rob Herring

The of_get_named_gpio_flags() function allows the caller to specify the
property name which should be read for a list of GPIOs.

Unfortunately there is no easy way to *count* the number of GPIOs listed
in an arbitrary property.

To resolve this, rename of_gpio_count() to of_gpio_count_named() and add
a new "propname" parameter.

Also add a static inline replacement for of_gpio_count() which calls
of_gpio_count_named() with "gpios" to avoid breaking existing users.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
 drivers/of/gpio.c       |   13 ++++++-------
 include/linux/of_gpio.h |   27 +++++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index ef0105f..f349aaf 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -83,8 +83,9 @@ err0:
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
- * of_gpio_count - Count GPIOs for a device
+ * of_gpio_count_named - Count GPIOs for a device
  * @np:		device node to count GPIOs for
+ * @propname:	property name containing gpio specifier(s)
  *
  * The function returns the count of GPIOs specified for a node.
  *
@@ -98,15 +99,13 @@ EXPORT_SYMBOL(of_get_named_gpio_flags);
  * defines four GPIOs (so this function will return 4), two of which
  * are not specified.
  */
-unsigned int of_gpio_count(struct device_node *np)
+unsigned int of_gpio_count_named(struct device_node *np, const char *propname)
 {
 	unsigned int cnt = 0;
 
 	do {
-		int ret;
-
-		ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells",
-						  cnt, NULL, NULL);
+		int ret = of_parse_phandles_with_args(np, propname,
+				"#gpio-cells", cnt, NULL, NULL);
 		/* A hole in the gpios = <> counts anyway. */
 		if (ret < 0 && ret != -EEXIST)
 			break;
@@ -114,7 +113,7 @@ unsigned int of_gpio_count(struct device_node *np)
 
 	return cnt;
 }
-EXPORT_SYMBOL(of_gpio_count);
+EXPORT_SYMBOL(of_gpio_count_named);
 
 /**
  * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 52280a2..1411a06 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -49,7 +49,8 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
 extern int of_get_named_gpio_flags(struct device_node *np,
 		const char *list_name, int index, enum of_gpio_flags *flags);
 
-extern unsigned int of_gpio_count(struct device_node *np);
+extern unsigned int of_gpio_count_named(struct device_node *np,
+		const char *propname);
 
 extern int of_mm_gpiochip_add(struct device_node *np,
 			      struct of_mm_gpio_chip *mm_gc);
@@ -69,7 +70,8 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
 	return -ENOSYS;
 }
 
-static inline unsigned int of_gpio_count(struct device_node *np)
+static inline unsigned int of_gpio_count_named(struct device_node *np,
+		const char *propname)
 {
 	return 0;
 }
@@ -87,6 +89,27 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 #endif /* CONFIG_OF_GPIO */
 
 /**
+ * of_gpio_count - Count GPIOs for a device
+ * @np:		device node to count GPIOs for
+ *
+ * The function returns the count of GPIOs specified for a node.
+ *
+ * Note that the empty GPIO specifiers counts too. For example,
+ *
+ * gpios = <0
+ *          &pio1 1 2
+ *          0
+ *          &pio2 3 4>;
+ *
+ * defines four GPIOs (so this function will return 4), two of which
+ * are not specified.
+ */
+static inline unsigned int of_gpio_count(struct device_node *np)
+{
+	return of_gpio_count_named(np, "gpios");
+}
+
+/**
  * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API
  * @np:		device node to get GPIO from
  * @index:	index of the GPIO
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [REPOST RFC PATCH 2/3] of_gpio: Add new helpers for easily requesting lots of GPIOs
  2011-12-13 18:23 ` Kyle Moffett
  (?)
  (?)
@ 2011-12-13 18:23 ` Kyle Moffett
  2012-01-04 18:49   ` Grant Likely
  -1 siblings, 1 reply; 24+ messages in thread
From: Kyle Moffett @ 2011-12-13 18:23 UTC (permalink / raw)
  To: linux-kernel
  Cc: Grant Likely, Linus Walleij, devicetree-discuss, Kyle Moffett,
	Rob Herring

Mirroring the new gpio_request_array() interface, we add several a few
helper functions for operating on entire arrays of GPIOs.

Also, to make it easier to write various combinations of "of_get_gpio()"
followed by "gpio_request()", add several other new inline wrappers.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
 drivers/of/gpio.c       |   96 +++++++++++++++++++++++++++++
 include/linux/of_gpio.h |  154 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 250 insertions(+), 0 deletions(-)

diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index f349aaf..4c04f2f 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -83,6 +83,47 @@ err0:
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
+ * of_get_gpio_array_flags() - Get array of gpios to use with GPIO API
+ * @np:		device node to get GPIOs from
+ * @of_gpios:	array of "struct of_gpio" to select which GPIOs to look up
+ * @of_flags:	array of "enum of_gpio_flags" to be filled in (may be NULL)
+ * @gpios:	array of "struct gpio" to be filled in
+ * @num:	the number of GPIOs to look up
+ *
+ * Takes a constant array of "struct of_gpio" and looks up each item in the
+ * indicated device-node.  The results are stored into the @gpios array,
+ * along with the optional GPIO "label" and "flags" values from the "of_gpio"
+ * structure.
+ *
+ * If an array of @of_flags is provided then any flags from the translate
+ * function will be stored into the corresponding element there.
+ */
+int of_get_gpio_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num)
+{
+	int err = 0;
+
+	size_t i;
+	for (i = 0; i < num; i++) {
+		/* Copy over the GPIO values */
+		gpios[i].flags = of_gpios[i].gpio_flags;
+		gpios[i].label = of_gpios[i].gpio_label;
+
+		/* Now dig the rest out of the device-tree */
+		gpios[i].gpio = of_get_named_gpio_flags(np,
+				of_gpios[i].propname, of_gpios[i].index,
+				(of_flags ? &of_flags[num] : NULL));
+
+		if (gpios[i].gpio < 0)
+			err = err ?: gpios[i].gpio;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(of_get_gpio_array_flags);
+
+/**
  * of_gpio_count_named - Count GPIOs for a device
  * @np:		device node to count GPIOs for
  * @propname:	property name containing gpio specifier(s)
@@ -116,6 +157,61 @@ unsigned int of_gpio_count_named(struct device_node *np, const char *propname)
 EXPORT_SYMBOL(of_gpio_count_named);
 
 /**
+ * of_gpio_request_named_flags() - Request a GPIO using the device-tree
+ * @np:		device node to get GPIO from
+ * @propname:	property name containing gpio specifier(s)
+ * @index:	index of the GPIO
+ * @flags:	a flags pointer to fill in
+ * @gpio_flags:	The setup flags to pass into the GPIO API
+ * @gpio_label:	The label to pass into the GPIO API
+ *
+ * This is a simple wrapper around gpio_request_one() that looks up the GPIO
+ * from the device-tree first using of_get_named_gpio_flags().
+ */
+int of_gpio_request_named_flags(struct device_node *np,
+		const char *propname, int index, enum of_gpio_flags *of_flags,
+		unsigned long gpio_flags, const char *gpio_label)
+{
+	int err;
+
+	/* Retrieve the GPIO information from the device-tree */
+	int gpio = of_get_named_gpio_flags(np, propname, index, of_flags);
+	if (gpio < 0)
+		return gpio;
+
+	/* Request the GPIO */
+	err = gpio_request_one(gpio, gpio_flags, gpio_label);
+	return err ? err : gpio;
+}
+EXPORT_SYMBOL(of_gpio_request_named_flags);
+
+/**
+ * of_gpio_request_array_flags() - Request GPIOs using the device-tree
+ * @np:		device node to get GPIO from
+ * @of_gpios:	array of "struct of_gpio" to select which GPIOs to request
+ * @of_flags:	array of "enum of_gpio_flags" to be filled in (may be NULL)
+ * @gpios:	array of "struct gpio" to be filled in
+ * @num:	the number of GPIOs to request
+ *
+ * This is a simple wrapper around gpio_request_array() that looks up the
+ * GPIOs from the device-tree first using of_get_gpio_array_flags().
+ */
+int of_gpio_request_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num)
+{
+	/* Retrieve the GPIO information from the device-tree */
+	int err = of_get_gpio_array_flags(np, of_gpios,
+			of_flags, gpios, num);
+	if (err)
+		return err;
+
+	/* Request all of the GPIOs */
+	return gpio_request_array(gpios, num);
+}
+EXPORT_SYMBOL(of_gpio_request_array_flags);
+
+/**
  * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
  * @gc:		pointer to the gpio_chip structure
  * @np:		device node of the GPIO chip
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 1411a06..babce09 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -30,6 +30,20 @@ enum of_gpio_flags {
 	OF_GPIO_ACTIVE_LOW = 0x1,
 };
 
+/*
+ * This struct is passed to of_named_gpio_request_array() to initialize the
+ * passed-in array of "struct gpio" for use by gpio_request_array().
+ */
+struct of_gpio {
+	/* These values are used to locate the GPIO in the device-tree */
+	const char *propname;
+	int index;
+
+	/* These values are used to request the discovered GPIO */
+	unsigned long gpio_flags;
+	const char *gpio_label;
+};
+
 #ifdef CONFIG_OF_GPIO
 
 /*
@@ -49,9 +63,21 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
 extern int of_get_named_gpio_flags(struct device_node *np,
 		const char *list_name, int index, enum of_gpio_flags *flags);
 
+extern int of_get_gpio_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num);
+
 extern unsigned int of_gpio_count_named(struct device_node *np,
 		const char *propname);
 
+extern int of_gpio_request_named_flags(struct device_node *np,
+		const char *propname, int index, enum of_gpio_flags *of_flags,
+		unsigned long gpio_flags, const char *gpio_label);
+
+extern int of_gpio_request_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num);
+
 extern int of_mm_gpiochip_add(struct device_node *np,
 			      struct of_mm_gpio_chip *mm_gc);
 
@@ -70,12 +96,51 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_get_gpio_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num)
+{
+	/*
+	 * This function must always initialize all the "struct gpio"s even
+	 * if they cannot be probed to allow the user to detect the source of
+	 * each error.
+	 */
+	size_t i;
+	for (i = 0; i < num; i++) {
+		gpios[i].gpio = -ENOSYS;
+		gpios[i].label = of_gpios[i].label;
+		gpios[i].flags = of_gpios[i].flags;
+	}
+	return -ENOSYS;
+}
+
 static inline unsigned int of_gpio_count_named(struct device_node *np,
 		const char *propname)
 {
 	return 0;
 }
 
+static inline int of_gpio_request_named_flags(struct device_node *np,
+		const char *propname, int index, enum of_gpio_flags *of_flags,
+		unsigned long gpio_flags, const char *gpio_label)
+{
+	return -ENOSYS;
+}
+
+static inline int of_gpio_request_array_flags(struct device_node *np,
+		const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags,
+		struct gpio *gpios, size_t num)
+{
+	/* Same initialization as of_get_gpio_array_flags() above */
+	size_t i;
+	for (i = 0; i < num; i++) {
+		gpios[i].gpio = -ENOSYS;
+		gpios[i].label = of_gpios[i].label;
+		gpios[i].flags = of_gpios[i].flags;
+	}
+	return -ENOSYS;
+}
+
 static inline int of_gpio_simple_xlate(struct gpio_chip *gc,
 				       struct device_node *np,
 				       const void *gpio_spec, u32 *flags)
@@ -153,4 +218,93 @@ static inline int of_get_gpio(struct device_node *np, int index)
 	return of_get_gpio_flags(np, index, NULL);
 }
 
+/**
+ * of_gpio_request_one_flags() - Request a GPIO using the device-tree
+ * @np:		device node to get GPIO from
+ * @index:	index of the GPIO
+ * @flags:	a flags pointer to fill in
+ * @gpio_flags:	The setup flags to pass into the GPIO API
+ * @gpio_label:	The label to pass into the GPIO API
+ *
+ * This is a simple wrapper around gpio_request_one() that looks up the GPIO
+ * from the device-tree first using of_get_gpio_flags().
+ */
+static inline int of_gpio_request_one_flags(struct device_node *np,
+		int index, enum of_gpio_flags *of_flags,
+		unsigned long gpio_flags, const char *gpio_label)
+{
+	return of_gpio_request_named_flags(np, "gpios", index,
+			of_flags, gpio_flags, gpio_label);
+}
+
+/**
+ * of_gpio_request_named() - Request a GPIO using the device-tree
+ * @np:		device node to get GPIO from
+ * @propname:	Name of property containing gpio specifier(s)
+ * @index:	index of the GPIO
+ * @gpio_flags:	The setup flags to pass into the GPIO API
+ * @gpio_label:	The label to pass into the GPIO API
+ *
+ * This is a simple wrapper around gpio_request_one() that looks up the GPIO
+ * from the device-tree first using of_get_named_gpio().
+ */
+static inline int of_gpio_request_named(struct device_node *np,
+		const char *propname, int index,
+		unsigned long gpio_flags, const char *gpio_label)
+{
+	return of_gpio_request_named_flags(np, propname, index,
+			NULL, gpio_flags, gpio_label);
+}
+
+/**
+ * of_gpio_request_one() - Request a GPIO using the device-tree
+ * @np:		device node to get GPIO from
+ * @index:	index of the GPIO
+ * @gpio_flags:	The setup flags to pass into the GPIO API
+ * @gpio_label:	The label to pass into the GPIO API
+ *
+ * This is a simple wrapper around gpio_request_one() that looks up the GPIO
+ * from the device-tree first using of_get_gpio().
+ */
+static inline int of_gpio_request_one(struct device_node *np,
+		int index, unsigned long gpio_flags, const char *gpio_label)
+{
+	return of_gpio_request_one_flags(np, index, NULL,
+			gpio_flags, gpio_label);
+}
+
+/**
+ * of_get_gpio_array() - Get an array of GPIO numbers to use with GPIO API
+ * @np:		device node to get GPIO from
+ * @of_gpios:	array of "struct of_gpio" to select which GPIOs to look up
+ * @gpios:	array of "struct gpio" to be filled in
+ * @num:	the number of GPIOs to look up
+ *
+ * Takes a constant array of "struct of_gpio" and looks up each item in the
+ * indicated device-node.  The results are stored into the @gpios array,
+ * along with the optional GPIO "label" and "flags" values from the "of_gpio"
+ * structure.
+ */
+static inline int of_get_gpio_array(struct device_node *np,
+		const struct of_gpio *of_gpios, struct gpio *gpios, size_t num)
+{
+	return of_get_gpio_array_flags(np, of_gpios, NULL, gpios, num);
+}
+
+/**
+ * of_gpio_request_array() - Request GPIOs using the device-tree
+ * @np:		device node to get GPIO from
+ * @of_gpios:	array of "struct of_gpio" to select which GPIOs to request
+ * @gpios:	array of "struct gpio" to be filled in
+ * @num:	the number of GPIOs to request
+ *
+ * This is a simple wrapper around gpio_request_array() that looks up the
+ * GPIOs from the device-tree first using of_get_gpio_array().
+ */
+static inline int of_gpio_request_array(struct device_node *np,
+		const struct of_gpio *of_gpios, struct gpio *gpios, size_t num)
+{
+	return of_gpio_request_array_flags(np, of_gpios, NULL, gpios, num);
+}
+
 #endif /* __LINUX_OF_GPIO_H */
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [REPOST RFC PATCH 3/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-13 18:23 ` Kyle Moffett
                   ` (2 preceding siblings ...)
  (?)
@ 2011-12-13 18:23 ` Kyle Moffett
  -1 siblings, 0 replies; 24+ messages in thread
From: Kyle Moffett @ 2011-12-13 18:23 UTC (permalink / raw)
  To: linux-kernel
  Cc: Grant Likely, Linus Walleij, devicetree-discuss, Kyle Moffett,
	Rob Herring, Randy Dunlap, linux-doc

This driver is especially useful on systems with an OF device-tree as
they can automatically instantiate the driver from GPIOs described in
the device-tree.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
 .../devicetree/bindings/gpio/gpio-poweroff.txt     |   70 ++++
 drivers/gpio/Kconfig                               |   10 +
 drivers/gpio/Makefile                              |    3 +
 drivers/gpio/gpio-poweroff.c                       |  360 ++++++++++++++++++++
 include/linux/power/gpio-poweroff.h                |   43 +++
 5 files changed, 486 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
 create mode 100644 drivers/gpio/gpio-poweroff.c
 create mode 100644 include/linux/power/gpio-poweroff.h

diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
new file mode 100644
index 0000000..418662a
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
@@ -0,0 +1,70 @@
+Simple system and device poweroff via GPIO lines
+
+This performs powerdown of individual devices (or the entire system) using
+generic GPIO lines configured in the device tree.
+
+Each device can have the following properties:
+
+  * compatible (REQUIRED)
+      Must be "linux,gpio-poweroff".
+
+  * machine-power-control (OPTIONAL)
+      Does not have a value.  If present, the poweroff device is considered
+      to affect the entire system instead of just a single physical device.
+
+      NOTE1: If this property is absent, the device-node must be present at
+      the correct location in the device-tree so the platform_drv->shutdown
+      callback is executed at the appropriate time during system shutdown.
+
+      NOTE2: In order to trigger devices with this property present, the
+      platform support code must call gpio_machine_poweroff().
+
+  * final-delay-msecs (OPTIONAL)
+      After turning off the final power domain, wait the specified number of
+      milliseconds before continuing.  The default is 0, if not specified.
+
+
+Each device also has a list of power domains to be acted upon, represented as
+three separate properties.  A power domain is made up of the corresponding
+elements in each property array:
+
+  * power-domain-gpios (REQUIRED)
+      An array of GPIO specifiers of each power domain.  All elements must be
+      valid and available or the device will fail to probe.
+
+      The GPIO binding must support the OF_GPIO_ACTIVE_LOW flag in order to
+      specify the polarity of the GPIO.  If your GPIO controller uses the
+      standard Linux of_gpio_simple_xlate(), then you can simply specify a 1
+      in the second cell to indicate an active-low GPIO.
+
+  * power-domain-names (OPTIONAL)
+      An array of the humna-readable names of each power domain.  If missing
+      then generic numbers will be used for each domain.  Entries present
+      beyond the number of "power-domain-gpios" will be ignored.
+
+  * power-domain-delays-msec (OPTIONAL)
+      An array of 32-bit cells, each cell indicating how many milliseconds to
+      delay before activating the GPIO for the given power domain.  If left
+      unspecified then a default of 0 will be assumed. Entries present beyond
+      the number of "power-domain-gpios" will be ignored.
+
+Examples:
+
+gpios {
+	compatible = "simple-bus";
+
+	/* Whole-system power control */
+	power-control {
+		compatible = "linux,gpio-poweroff";
+
+		// Whole system, not a leaf device
+		machine-power-control;
+
+		// Power domains are turned off in this order
+		power-domain-names =	"TS", "S", "U";
+		power-domain-gpios =	<&pca9554a 3 0
+					 &pca9554a 2 0
+					 &pca9554a 1 0>;
+		power-domain-delays-msec = <500 500 500>;
+	};
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8482a23..b6e1141 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -489,4 +489,14 @@ config GPIO_TPS65910
 	help
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
+
+comment "Generic GPIO-based devices:"
+
+config GPIO_POWEROFF
+	tristate "Generic support for turning off platform devices with GPIOs"
+	help
+	  This enables a generic "gpio-poweroff" driver which may be used by
+	  custom platform-support code or included in OpenFirmware device
+	  trees to power off hardware using generic GPIO lines.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index dbcb0bc..b52d54e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,6 +4,9 @@ ccflags-$(CONFIG_DEBUG_GPIO)	+= -DDEBUG
 
 obj-$(CONFIG_GPIOLIB)		+= gpiolib.o
 
+# Generic GPIO platform drivers.
+obj-$(CONFIG_GPIO_POWEROFF)	+= gpio-poweroff.o
+
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC)	+= gpio-generic.o
 
diff --git a/drivers/gpio/gpio-poweroff.c b/drivers/gpio/gpio-poweroff.c
new file mode 100644
index 0000000..36ebb3b
--- /dev/null
+++ b/drivers/gpio/gpio-poweroff.c
@@ -0,0 +1,360 @@
+/*
+ * drivers/power/gpio-poweroff.c  -  Generic GPIO poweroff driver
+ *
+ * Maintainer: Kyle Moffett <Kyle.D.Moffett@boeing.com>
+ *
+ * Copyright 2010-2011 eXMeritus, A Boeing Company
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the  terms of  version 2  of the  GNU General Public  License, as
+ * published by the Free Software Foundation.
+ */
+#include <linux/power/gpio-poweroff.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+struct gpio_poweroff {
+	const struct gpio_poweroff_platform_data *pdata;
+	struct platform_device *pdev;
+	struct list_head node;
+};
+
+static struct gpio_poweroff_platform_data *
+gpio_poweroff_get_pdata(struct platform_device *pdev)
+{
+	struct gpio_poweroff_platform_data *pdata;
+	enum of_gpio_flags *gpio_flags = NULL;
+	struct of_gpio *of_gpios = NULL;
+	struct gpio *gpios = NULL;
+	u32 *gpio_mdelays = NULL;
+	struct device_node *np;
+	unsigned long i, nr;
+	int err;
+
+	/* First check for static platform data */
+	if (pdev->dev.platform_data)
+		return pdev->dev.platform_data;
+
+	/* Then check for an OpenFirmware device node */
+	np = pdev->dev.of_node;
+	if (!np) {
+		dev_err(&pdev->dev, "No gpio-poweroff pdata or of_node!\n");
+		return NULL;
+	}
+
+	/* Ok, create platform data based on the device node */
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Can't allocate gpio-poweroff pdata!\n");
+		return NULL;
+	}
+	pdata->dynamic_platform_data = true;
+
+	/*
+	 * If a "machine-power-control" property is present at all, then this
+	 * device will be regarded as a machine-poweroff handler and will not
+	 * be called until the very end when gpio_machine_poweroff() is
+	 * called by the architecture code.
+	 */
+	if (of_get_property(np, "machine-power-control", NULL))
+		pdata->is_machine_poweroff = true;
+	else
+		pdata->is_machine_poweroff = false;
+
+	/*
+	 * If a "final-delay-msecs" property is present, the poweroff
+	 * sequence will continue with the next device after the specified
+	 * delay (which may be zero).
+	 *
+	 * Otherwise it will hang here indefinitely.
+	 */
+	pdata->final_mdelay = 0;
+	of_property_read_u32(np, "final-delay-msecs", &pdata->final_mdelay);
+
+	/* Count the GPIOs */
+	pdata->nr_gpios = nr = of_gpio_count_named(np, "power-domain-gpios");
+	if (!pdata->nr_gpios) {
+		dev_warn(&pdev->dev, "No GPIOs to use during poweroff!\n");
+		return pdata;
+	}
+
+	/* Allocate enough memory for the tables */
+#define KCALLOC_ARRAY(ARRAY, NR, FLAGS) \
+	ARRAY = kcalloc(NR, sizeof((ARRAY)[0]), FLAGS)
+	KCALLOC_ARRAY(of_gpios,     nr, GFP_KERNEL);
+	KCALLOC_ARRAY(gpios,        nr, GFP_KERNEL);
+	KCALLOC_ARRAY(gpio_mdelays, nr, GFP_KERNEL);
+	KCALLOC_ARRAY(gpio_flags,   nr, GFP_KERNEL);
+#undef KCALLOC_ARRAY
+	if (!of_gpios || !gpios || !gpio_mdelays || !gpio_flags) {
+		dev_err(&pdev->dev, "Can't allocate tables for %lu GPIOs\n", nr);
+		goto err_kfree;
+	}
+
+	/* Parse the GPIO information from the device-tree */
+	for (i = 0; i < nr; i++) {
+		const char *label;
+
+		/* Initialize values */
+		of_gpios[i].propname = "power-domain-gpios";
+		of_gpios[i].index = i;
+		of_gpios[i].gpio_flags = GPIOF_DIR_OUT;
+
+		/* Try to read a label from the device-tree */
+		if (!of_property_read_string_index(np, "power-domain-names",
+					i, &label))
+			of_gpios[i].gpio_label = kstrdup(label, GFP_KERNEL);
+		else
+			of_gpios[i].gpio_label = NULL;
+	}
+	err = of_get_gpio_array_flags(np, of_gpios, gpio_flags, gpios, nr);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to parse all %lu GPIOs: %d\n", nr, err);
+		goto err_kfree_labels;
+	}
+
+	/* Set initial output values appropriately */
+	for (i = 0; i < nr; i++) {
+		if (gpio_flags[i] & OF_GPIO_ACTIVE_LOW)
+			gpios[i].flags |= GPIOF_INIT_HIGH;
+		else
+			gpios[i].flags |= GPIOF_INIT_LOW;
+	}
+
+	/* Parse the GPIO delays from the device-tree */
+	err = of_property_read_u32_array(np, "power-domain-delays-msec",
+			gpio_mdelays, nr);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to parse all %lu GPIO delays: %d\n", nr, err);
+		goto err_kfree_labels;
+	}
+
+	/* Free the temporary data and save the other arrays */
+	kfree(of_gpios);
+	pdata->gpios = gpios;
+	pdata->gpio_mdelays = gpio_mdelays;
+	pdata->gpio_flags = gpio_flags;
+	return pdata;
+
+err_kfree_labels:
+	for (i = 0; i < nr; i++)
+		kfree(of_gpios[i].gpio_label);
+err_kfree:
+	kfree(of_gpios);
+	kfree(gpios);
+	kfree(gpio_mdelays);
+	kfree(gpio_flags);
+	kfree(pdata);
+	return NULL;
+}
+
+static void gpio_poweroff_release_pdata(struct platform_device *pdev,
+		const struct gpio_poweroff_platform_data *pdata)
+{
+	unsigned long i, nr = pdata->nr_gpios;
+
+	/* Don't free anything unless we own the platform data */
+	if (!pdata || !pdata->dynamic_platform_data)
+		return;
+
+	/* Free any dynamically-allocated power domain labels */
+	for (i = 0; i < nr; i++)
+		kfree(pdata->gpios[i].label);
+
+	/* Free all the tables and then the platform data itself */
+	kfree(pdata->gpios);
+	kfree(pdata->gpio_mdelays);
+	kfree(pdata->gpio_flags);
+	kfree(pdata);
+}
+
+/* This list is used for "machine-poweroff" devices */
+static LIST_HEAD(gpio_machine_poweroff_list);
+static DEFINE_MUTEX(gpio_machine_poweroff_mutex);
+
+static int __devinit gpio_poweroff_probe(struct platform_device *pdev)
+{
+	const struct gpio_poweroff_platform_data *pdata;
+	struct gpio_poweroff *poweroff;
+	int ret;
+
+	/* Get the platform data from wherever is handy */
+	pdata = gpio_poweroff_get_pdata(pdev);
+	if (!pdata)
+		return -ENODEV;
+
+	/* Allocate a driver datastructure */
+	poweroff = kzalloc(sizeof(*poweroff), GFP_KERNEL);
+	if (!poweroff) {
+		dev_err(&pdev->dev, "Can't allocate gpio-poweroff data!\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Request all of the GPIOs.
+	 *
+	 * NOTE: The platform_data must set these to outputs, with the
+	 * correct levels so that the board doesn't power off here.
+	 */
+	ret = gpio_request_array(pdata->gpios, pdata->nr_gpios);
+	if (ret) {
+		dev_err(&pdev->dev, "Error requesting poweroff GPIOs!\n");
+		goto err;
+	}
+
+	/* Save the data */
+	poweroff->pdata = pdata;
+	poweroff->pdev = pdev;
+
+	/* If this is a machine-poweroff device, add it to the list */
+	if (pdata->is_machine_poweroff) {
+		mutex_lock(&gpio_machine_poweroff_mutex);
+		list_add_tail(&poweroff->node, &gpio_machine_poweroff_list);
+		mutex_unlock(&gpio_machine_poweroff_mutex);
+	} else {
+		INIT_LIST_HEAD(&poweroff->node);
+	}
+
+	/* Attach the data to the device */
+	dev_set_drvdata(&pdev->dev, poweroff);
+	dev_info(&pdev->dev, "Successfully initialized gpio-poweroff!\n");
+	return 0;
+
+err:
+	dev_err(&pdev->dev, "Could not initialize gpio-poweroff: %d\n", ret);
+	gpio_poweroff_release_pdata(pdev, pdata);
+	kfree(poweroff);
+	return ret;
+}
+
+static int __devexit gpio_poweroff_remove(struct platform_device *pdev)
+{
+	struct gpio_poweroff *poweroff = dev_get_drvdata(&pdev->dev);
+
+	/* Detach the data from the device */
+	dev_info(&pdev->dev, "Removing gpio-poweroff device\n");
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	/* Remove the poweroff device from the list */
+	mutex_lock(&gpio_machine_poweroff_mutex);
+	list_del(&poweroff->node);
+	mutex_unlock(&gpio_machine_poweroff_mutex);
+
+	/* Release the GPIOs and free the driver data */
+	gpio_free_array(poweroff->pdata->gpios, poweroff->pdata->nr_gpios);
+	gpio_poweroff_release_pdata(pdev, poweroff->pdata);
+	kfree(poweroff);
+	return 0;
+}
+
+/* Turn off power using a given "struct gpio_poweroff" */
+static void do_gpio_poweroff(struct gpio_poweroff *poweroff, bool machine)
+{
+	const struct gpio_poweroff_platform_data *pdata = poweroff->pdata;
+	struct device *dev = &poweroff->pdev->dev;
+	unsigned long i;
+
+	/*
+	 * If this device is a "machine-poweroff" device, only execute
+	 * the powerdown at the very end of the shutdown sequence.
+	 */
+	if (pdata->is_machine_poweroff && !machine)
+		return;
+
+	/* Enable each GPIO in order */
+	dev_info(dev, "Performing GPIO-based poweroff...\n");
+	for (i = 0; i < pdata->nr_gpios; i++) {
+		/* Get the label and number of the GPIO */
+		const char *label = pdata->gpios[i].label;
+		int gpio = pdata->gpios[i].gpio;
+
+		enum of_gpio_flags of_flags = 0;
+		unsigned long msec = 0;
+		bool active;
+
+		/* Get the flags and delay (if present) */
+		if (pdata->gpio_flags)
+			of_flags = pdata->gpio_flags[i];
+		if (pdata->gpio_mdelays)
+			msec = pdata->gpio_mdelays[i];
+
+		active = !(of_flags & OF_GPIO_ACTIVE_LOW);
+		if (label)
+			dev_info(dev, "Turning off power domain \"%s\" "
+					"using an active-%s GPIO after %lums",
+					label, (active?"high":"low"), msec);
+		else
+			dev_info(dev, "Turning off power domain %d "
+					"using an active-%s GPIO after %lums",
+					gpio, (active?"high":"low"), msec);
+
+		/* Program the GPIO after the delay */
+		mdelay(msec);
+		gpio_set_value_cansleep(gpio, active);
+	}
+
+	/* Perform the final delay */
+	mdelay(pdata->final_mdelay);
+}
+
+/* Per-device shutdown */
+static void gpio_poweroff_shutdown(struct platform_device *pdev)
+{
+	do_gpio_poweroff(dev_get_drvdata(&pdev->dev), false);
+}
+
+/* Whole-machine shutdown */
+void gpio_machine_poweroff(void)
+{
+	struct gpio_poweroff *poweroff;
+
+	pr_warning("Performing machine poweroff using GPIOs\n");
+
+	/* Iterate over each poweroff device in order */
+	mutex_lock(&gpio_machine_poweroff_mutex);
+	list_for_each_entry(poweroff, &gpio_machine_poweroff_list, node)
+		do_gpio_poweroff(poweroff, true);
+	mutex_unlock(&gpio_machine_poweroff_mutex);
+
+	pr_crit("Still online! System power off using GPIOs failed?\n");
+}
+
+static const struct of_device_id of_match_table[] = {
+	{ .compatible = "linux,gpio-poweroff" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, of_match_table);
+
+static struct platform_driver gpio_poweroff_driver = {
+	.driver = {
+		.name = "gpio-poweroff",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_table,
+	},
+	.probe		= gpio_poweroff_probe,
+	.shutdown	= gpio_poweroff_shutdown,
+	.remove		= __devexit_p(gpio_poweroff_remove),
+};
+
+static int __init gpio_poweroff_init(void)
+{
+	return platform_driver_register(&gpio_poweroff_driver);
+}
+module_init(gpio_poweroff_init);
+
+static void __exit gpio_poweroff_exit(void)
+{
+	platform_driver_unregister(&gpio_poweroff_driver);
+}
+module_exit(gpio_poweroff_exit);
+
+MODULE_AUTHOR("Kyle Moffett");
+MODULE_DESCRIPTION("Simple GPIO Power-Off Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/power/gpio-poweroff.h b/include/linux/power/gpio-poweroff.h
new file mode 100644
index 0000000..70787f1
--- /dev/null
+++ b/include/linux/power/gpio-poweroff.h
@@ -0,0 +1,43 @@
+/*
+ * gpio-poweroff.h  -  Generic GPIO-based poweroff driver
+ *
+ * Maintainer: Kyle Moffett <Kyle.D.Moffett@boeing.com>
+ *
+ * Copyright (C) 2010-2011 eXMeritus, A Boeing Company
+ *
+ */
+
+#ifndef LINUX_POWER_GPIO_POWEROFF_H_
+#define LINUX_POWER_GPIO_POWEROFF_H_
+
+#include <linux/of_gpio.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct gpio_poweroff_platform_data {
+	/* The number of poweroff GPIOs to use */
+	size_t nr_gpios;
+
+	/* An array of pre-requested GPIOs, and active-low/high status */
+	const struct gpio *gpios;
+	const enum of_gpio_flags *gpio_flags;
+
+	/* The delay to use before each GPIO is triggered */
+	const u32 *gpio_mdelays;
+
+	/* The final delay after all GPIOs have been set */
+	u32 final_mdelay;
+
+	/*
+	 * If set, this is excluded from normal platform_device processing
+	 * and only called when gpio_machine_poweroff() is run.
+	 */
+	bool is_machine_poweroff;
+
+	/* The platform_data and arrays should be kfree()d during removal */
+	bool dynamic_platform_data;
+};
+
+void gpio_machine_poweroff(void);
+
+#endif /* not LINUX_POWER_GPIO_POWEROFF_H_ */
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-13 18:23 ` Kyle Moffett
                   ` (3 preceding siblings ...)
  (?)
@ 2011-12-13 19:10 ` Rob Herring
  2011-12-13 20:44     ` Moffett, Kyle D
  -1 siblings, 1 reply; 24+ messages in thread
From: Rob Herring @ 2011-12-13 19:10 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, devicetree-discuss, Liam Girdwood, Grant Likely

On 12/13/2011 12:23 PM, Kyle Moffett wrote:
> Hello again,
> 
> I posted this patch series a few weeks ago and saw no responses, so I
> tweaked the CC list and am reposting it again for review.
> 
> I'm working on support for some custom hardware of ours, and part of
> the support code is the ability for the software to shutdown the power
> supply using GPIOs (via an I2C GPIO controller).
> 
> I previously had this in my platform code, but it seemed generically
> useful, so I split it out into a separate module for others to use.
> 
> The first two patches are generic of_gpio enhancements, providing some
> new library functions for requesting lots of GPIOs at once.
> 
> The third patch is the actual driver itself.  The driver can be used to
> instantiate a platform device as a whole-machine-poweroff device as we
> use it on our hardware.  Alternatively it can instantiate multiple
> platform devs at specific locations on the device tree which trigger
> from the platform_driver->shutdown() callback.
> 
> For architectures which are still stuck in the dark ages, this driver
> also supports being instantiated via legacy platform_data.

Leave them there... :)

> The OpenFirmware binding documentation is added in the third patch.
> Since this is my first cut, it's a little rough, so please be gentle.
> 
> I'm interested to know what you all think.

Does the regulator framework gpio-regulator not work for this?

The DT gpio patches look useful on their own.

Rob

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-13 19:10 ` [REPOST RFC PATCH 0/3] " Rob Herring
@ 2011-12-13 20:44     ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-13 20:44 UTC (permalink / raw)
  To: Rob Herring; +Cc: linux-kernel, devicetree-discuss, Liam Girdwood, Grant Likely

On Dec 13, 2011, at 14:10, Rob Herring wrote:
> On 12/13/2011 12:23 PM, Kyle Moffett wrote:
>> 
>> I posted this patch series a few weeks ago and saw no responses, so I
>> tweaked the CC list and am reposting it again for review.
>> 
>> I'm working on support for some custom hardware of ours, and part of
>> the support code is the ability for the software to shutdown the power
>> supply using GPIOs (via an I2C GPIO controller).
>> 
>> I previously had this in my platform code, but it seemed generically
>> useful, so I split it out into a separate module for others to use.
>> 
>> The first two patches are generic of_gpio enhancements, providing some
>> new library functions for requesting lots of GPIOs at once.
>> 
>> The third patch is the actual driver itself.  The driver can be used to
>> instantiate a platform device as a whole-machine-poweroff device as we
>> use it on our hardware.  Alternatively it can instantiate multiple
>> platform devs at specific locations on the device tree which trigger
>> from the platform_driver->shutdown() callback.
>> 
>> For architectures which are still stuck in the dark ages, this driver
>> also supports being instantiated via legacy platform_data.
> 
> Leave them there... :)

Mostly this was out of convenience and imitating the other OF platform
drivers.  I wrote it and ended up with a struct full of probe data being
passed between functions, so I just called it "platform_data" :-D.


>> The OpenFirmware binding documentation is added in the third patch.
>> Since this is my first cut, it's a little rough, so please be gentle.
>> 
>> I'm interested to know what you all think.
> 
> Does the regulator framework gpio-regulator not work for this?

Well, when I initially wrote this code, the regulator framework didn't
exist :-D.

I looked at it a bit when I was generalizing my code, but it seemed
dramatically more complicated than I needed, and I couldn't see any
reasonable way to hook it from the machine_poweroff() code.

There's also the fact that I was looking for a pure-device-tree type
of driver and the regulator framework does not seem to support the
standard OF-platform probe system.

I will admit that there's probably some value in having a more generic
GPIO-power-control (instead of just poweroff), but I don't have the
target use-case to be able to design for it.


> The DT gpio patches look useful on their own.

Yeah, it seemed like a fairly generic extension of the existing API.

Thanks for the comments!

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-13 20:44     ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-13 20:44 UTC (permalink / raw)
  To: Rob Herring; +Cc: linux-kernel, devicetree-discuss, Liam Girdwood, Grant Likely

On Dec 13, 2011, at 14:10, Rob Herring wrote:
> On 12/13/2011 12:23 PM, Kyle Moffett wrote:
>> 
>> I posted this patch series a few weeks ago and saw no responses, so I
>> tweaked the CC list and am reposting it again for review.
>> 
>> I'm working on support for some custom hardware of ours, and part of
>> the support code is the ability for the software to shutdown the power
>> supply using GPIOs (via an I2C GPIO controller).
>> 
>> I previously had this in my platform code, but it seemed generically
>> useful, so I split it out into a separate module for others to use.
>> 
>> The first two patches are generic of_gpio enhancements, providing some
>> new library functions for requesting lots of GPIOs at once.
>> 
>> The third patch is the actual driver itself.  The driver can be used to
>> instantiate a platform device as a whole-machine-poweroff device as we
>> use it on our hardware.  Alternatively it can instantiate multiple
>> platform devs at specific locations on the device tree which trigger
>> from the platform_driver->shutdown() callback.
>> 
>> For architectures which are still stuck in the dark ages, this driver
>> also supports being instantiated via legacy platform_data.
> 
> Leave them there... :)

Mostly this was out of convenience and imitating the other OF platform
drivers.  I wrote it and ended up with a struct full of probe data being
passed between functions, so I just called it "platform_data" :-D.


>> The OpenFirmware binding documentation is added in the third patch.
>> Since this is my first cut, it's a little rough, so please be gentle.
>> 
>> I'm interested to know what you all think.
> 
> Does the regulator framework gpio-regulator not work for this?

Well, when I initially wrote this code, the regulator framework didn't
exist :-D.

I looked at it a bit when I was generalizing my code, but it seemed
dramatically more complicated than I needed, and I couldn't see any
reasonable way to hook it from the machine_poweroff() code.

There's also the fact that I was looking for a pure-device-tree type
of driver and the regulator framework does not seem to support the
standard OF-platform probe system.

I will admit that there's probably some value in having a more generic
GPIO-power-control (instead of just poweroff), but I don't have the
target use-case to be able to design for it.


> The DT gpio patches look useful on their own.

Yeah, it seemed like a fairly generic extension of the existing API.

Thanks for the comments!

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-13 18:23 ` Kyle Moffett
                   ` (4 preceding siblings ...)
  (?)
@ 2011-12-14 11:59 ` Mark Brown
  -1 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-14 11:59 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, Grant Likely, Linus Walleij, devicetree-discuss

On Tue, Dec 13, 2011 at 01:23:31PM -0500, Kyle Moffett wrote:

> I'm working on support for some custom hardware of ours, and part of
> the support code is the ability for the software to shutdown the power
> supply using GPIOs (via an I2C GPIO controller).

We already have the regulator API for controlling power to devices,
simple GPIO supplies are supported using fixed voltage regulators.  The
drivers that are being turned off should have regulator support added to
them.  If we have a separate method for doing GPIOs then drivers would
have to support multiple methods of controlling their power.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-13 20:44     ` Moffett, Kyle D
@ 2011-12-14 12:02       ` Mark Brown
  -1 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-14 12:02 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Tue, Dec 13, 2011 at 02:44:48PM -0600, Moffett, Kyle D wrote:

> I looked at it a bit when I was generalizing my code, but it seemed
> dramatically more complicated than I needed, and I couldn't see any
> reasonable way to hook it from the machine_poweroff() code.

Some ST platform had to do odd stuff with regulators to power off, it
made a platform device representing the odd poweroff code.

> There's also the fact that I was looking for a pure-device-tree type
> of driver and the regulator framework does not seem to support the
> standard OF-platform probe system.

The regulator API in -next has DT bindings.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-14 12:02       ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-14 12:02 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Tue, Dec 13, 2011 at 02:44:48PM -0600, Moffett, Kyle D wrote:

> I looked at it a bit when I was generalizing my code, but it seemed
> dramatically more complicated than I needed, and I couldn't see any
> reasonable way to hook it from the machine_poweroff() code.

Some ST platform had to do odd stuff with regulators to power off, it
made a platform device representing the odd poweroff code.

> There's also the fact that I was looking for a pure-device-tree type
> of driver and the regulator framework does not seem to support the
> standard OF-platform probe system.

The regulator API in -next has DT bindings.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-14 20:34         ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-14 20:34 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Dec 14, 2011, at 07:02, Mark Brown wrote:
> On Tue, Dec 13, 2011 at 02:44:48PM -0600, Moffett, Kyle D wrote:
>> I looked at it a bit when I was generalizing my code, but it seemed
>> dramatically more complicated than I needed, and I couldn't see any
>> reasonable way to hook it from the machine_poweroff() code.
> 
> Some ST platform had to do odd stuff with regulators to power off, it
> made a platform device representing the odd poweroff code.

This is actually what I did originally, albeit with GPIOs.

In our case we have a chassis with 6 computers in it, and one of the
computers has 3 GPIOs which are wired to the "off" signal for each domain
(one domain per pair of computers).

Due to isolation requirements, that computer can't turn the domains back
on from software, so really all we need to be able to do is trigger each
GPIO in sequence as part of the poweroff.

So basically the "gpio-poweroff" driver was just a slightly-more-generic
way of doing what I was doing before, by looking up the GPIOs in the
device-tree.


>> There's also the fact that I was looking for a pure-device-tree type
>> of driver and the regulator framework does not seem to support the
>> standard OF-platform probe system.
> 
> The regulator API in -next has DT bindings.

Based on the description of our hardware, is there a good way that I
can wire up gpio-regulator driver to our hardware with just the device
tree (and maybe one small board-specific function) to make it shut down
each domain in sequence at poweroff time? Otherwise I will just go back
to my custom board-specific function for GPIO-twiddling.

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-14 20:34         ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-14 20:34 UTC (permalink / raw)
  To: Mark Brown
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Liam Girdwood

On Dec 14, 2011, at 07:02, Mark Brown wrote:
> On Tue, Dec 13, 2011 at 02:44:48PM -0600, Moffett, Kyle D wrote:
>> I looked at it a bit when I was generalizing my code, but it seemed
>> dramatically more complicated than I needed, and I couldn't see any
>> reasonable way to hook it from the machine_poweroff() code.
> 
> Some ST platform had to do odd stuff with regulators to power off, it
> made a platform device representing the odd poweroff code.

This is actually what I did originally, albeit with GPIOs.

In our case we have a chassis with 6 computers in it, and one of the
computers has 3 GPIOs which are wired to the "off" signal for each domain
(one domain per pair of computers).

Due to isolation requirements, that computer can't turn the domains back
on from software, so really all we need to be able to do is trigger each
GPIO in sequence as part of the poweroff.

So basically the "gpio-poweroff" driver was just a slightly-more-generic
way of doing what I was doing before, by looking up the GPIOs in the
device-tree.


>> There's also the fact that I was looking for a pure-device-tree type
>> of driver and the regulator framework does not seem to support the
>> standard OF-platform probe system.
> 
> The regulator API in -next has DT bindings.

Based on the description of our hardware, is there a good way that I
can wire up gpio-regulator driver to our hardware with just the device
tree (and maybe one small board-specific function) to make it shut down
each domain in sequence at poweroff time? Otherwise I will just go back
to my custom board-specific function for GPIO-twiddling.

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-17  9:20           ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-17  9:20 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Wed, Dec 14, 2011 at 02:34:37PM -0600, Moffett, Kyle D wrote:
> On Dec 14, 2011, at 07:02, Mark Brown wrote:

> > The regulator API in -next has DT bindings.

> Based on the description of our hardware, is there a good way that I
> can wire up gpio-regulator driver to our hardware with just the device
> tree (and maybe one small board-specific function) to make it shut down
> each domain in sequence at poweroff time? Otherwise I will just go back
> to my custom board-specific function for GPIO-twiddling.

No, it's a very rare use case so there's nothing off the shelf.  But it
should be straightfoward to write a device driver doing this.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-17  9:20           ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-17  9:20 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Liam Girdwood

On Wed, Dec 14, 2011 at 02:34:37PM -0600, Moffett, Kyle D wrote:
> On Dec 14, 2011, at 07:02, Mark Brown wrote:

> > The regulator API in -next has DT bindings.

> Based on the description of our hardware, is there a good way that I
> can wire up gpio-regulator driver to our hardware with just the device
> tree (and maybe one small board-specific function) to make it shut down
> each domain in sequence at poweroff time? Otherwise I will just go back
> to my custom board-specific function for GPIO-twiddling.

No, it's a very rare use case so there's nothing off the shelf.  But it
should be straightfoward to write a device driver doing this.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
  2011-12-17  9:20           ` Mark Brown
@ 2011-12-19 16:56             ` Moffett, Kyle D
  -1 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-19 16:56 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Dec 17, 2011, at 04:20, Mark Brown wrote:
> On Wed, Dec 14, 2011 at 02:34:37PM -0600, Moffett, Kyle D wrote:
>> On Dec 14, 2011, at 07:02, Mark Brown wrote:
>>> The regulator API in -next has DT bindings.
>> 
>> Based on the description of our hardware, is there a good way that I
>> can wire up gpio-regulator driver to our hardware with just the device
>> tree (and maybe one small board-specific function) to make it shut down
>> each domain in sequence at poweroff time? Otherwise I will just go back
>> to my custom board-specific function for GPIO-twiddling.
> 
> No, it's a very rare use case so there's nothing off the shelf.  But it
> should be straightfoward to write a device driver doing this.

Well, so that's what the "gpio-poweroff" driver I wrote is.  All it does
is hook into the device model and DT and provide various poweroff hooks
that poke GPIOs.

I still don't understand how the regulator API is supposed to help in my
particular case (whole-system poweroff).

Additional advice would be highly appreciated.

Cheers,
Kyle Moffett


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-19 16:56             ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-19 16:56 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Dec 17, 2011, at 04:20, Mark Brown wrote:
> On Wed, Dec 14, 2011 at 02:34:37PM -0600, Moffett, Kyle D wrote:
>> On Dec 14, 2011, at 07:02, Mark Brown wrote:
>>> The regulator API in -next has DT bindings.
>> 
>> Based on the description of our hardware, is there a good way that I
>> can wire up gpio-regulator driver to our hardware with just the device
>> tree (and maybe one small board-specific function) to make it shut down
>> each domain in sequence at poweroff time? Otherwise I will just go back
>> to my custom board-specific function for GPIO-twiddling.
> 
> No, it's a very rare use case so there's nothing off the shelf.  But it
> should be straightfoward to write a device driver doing this.

Well, so that's what the "gpio-poweroff" driver I wrote is.  All it does
is hook into the device model and DT and provide various poweroff hooks
that poke GPIOs.

I still don't understand how the regulator API is supposed to help in my
particular case (whole-system poweroff).

Additional advice would be highly appreciated.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20  1:38               ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-20  1:38 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Mon, Dec 19, 2011 at 10:56:41AM -0600, Moffett, Kyle D wrote:

> I still don't understand how the regulator API is supposed to help in my
> particular case (whole-system poweroff).

Well, it depends what you need to do.  In the ST-Ericsson case what they
needed to do was collapse the core supplies for the CPU.  But previously
you were talking about power domains, not whole system poweroff.
Usually a power domain is a subset of the full system power.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20  1:38               ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-20  1:38 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Liam Girdwood

On Mon, Dec 19, 2011 at 10:56:41AM -0600, Moffett, Kyle D wrote:

> I still don't understand how the regulator API is supposed to help in my
> particular case (whole-system poweroff).

Well, it depends what you need to do.  In the ST-Ericsson case what they
needed to do was collapse the core supplies for the CPU.  But previously
you were talking about power domains, not whole system poweroff.
Usually a power domain is a subset of the full system power.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20  1:53                 ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-20  1:53 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Dec 19, 2011, at 20:38, Mark Brown wrote:
> On Mon, Dec 19, 2011 at 10:56:41AM -0600, Moffett, Kyle D wrote:
>> I still don't understand how the regulator API is supposed to help in my
>> particular case (whole-system poweroff).
> 
> Well, it depends what you need to do.  In the ST-Ericsson case what they
> needed to do was collapse the core supplies for the CPU.  But previously
> you were talking about power domains, not whole system poweroff.
> Usually a power domain is a subset of the full system power.

Well, I have control of 3 separate power domains in the sense that
there are 6 physically separate computers sharing a single supply,
with 2 in each domain (and only 1 of the 6 controlling the shared
supply).

Obviously when the 'control computer' goes off the GPIOs will
fluctuate wildly, so the power supply only responds to the GPIOs as
a signal to cut power, not to re-enable it.  The system is designed
to require user intervention to resupply power after it has shut
itself down.

So I do have separate power domains, but in this particular
hardware build I simply want to shut them all down in a fixed order
(due to the specific arrangement of power supply connections).

Previously I had about 200 lines of code in my machine_poweroff
hook to walk a list of GPIOs in the device tree and turn them all
off in a fixed order.  After looking at that a while I decided it
would be better off as a pseudo-generic driver that could be used
by any DT platform with a GPIO used to shut down system power.

I ended up with the "gpio-poweroff" driver which also makes the
time delays configurable.

Since I noticed that platform_drv also has a device-specific
poweroff hook, I added a boolean DT value to switch between
powering down at machine_poweroff() time and powering down during
the device->poweroff() walk.

I realize that this driver is basically incapable of any kind of
runtime power management but it could be used on X86 platforms
that convert to device-tree.  In particular ones with embedded
controllers and BMC devices would otherwise be using ACPI device
methods to poke a few GPIOs in basically the same fashion.

The benefit is that instead of ACPI AML (bytecode poking magic
IO registers at some undocumented address) you have a standard
GPIO driver and a piece of pseudo-self-documenting device-tree
that basically says "the HW engineers set it up so you set these
GPIOs in that order and it turns off".

Make sense?

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20  1:53                 ` Moffett, Kyle D
  0 siblings, 0 replies; 24+ messages in thread
From: Moffett, Kyle D @ 2011-12-20  1:53 UTC (permalink / raw)
  To: Mark Brown
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Liam Girdwood

On Dec 19, 2011, at 20:38, Mark Brown wrote:
> On Mon, Dec 19, 2011 at 10:56:41AM -0600, Moffett, Kyle D wrote:
>> I still don't understand how the regulator API is supposed to help in my
>> particular case (whole-system poweroff).
> 
> Well, it depends what you need to do.  In the ST-Ericsson case what they
> needed to do was collapse the core supplies for the CPU.  But previously
> you were talking about power domains, not whole system poweroff.
> Usually a power domain is a subset of the full system power.

Well, I have control of 3 separate power domains in the sense that
there are 6 physically separate computers sharing a single supply,
with 2 in each domain (and only 1 of the 6 controlling the shared
supply).

Obviously when the 'control computer' goes off the GPIOs will
fluctuate wildly, so the power supply only responds to the GPIOs as
a signal to cut power, not to re-enable it.  The system is designed
to require user intervention to resupply power after it has shut
itself down.

So I do have separate power domains, but in this particular
hardware build I simply want to shut them all down in a fixed order
(due to the specific arrangement of power supply connections).

Previously I had about 200 lines of code in my machine_poweroff
hook to walk a list of GPIOs in the device tree and turn them all
off in a fixed order.  After looking at that a while I decided it
would be better off as a pseudo-generic driver that could be used
by any DT platform with a GPIO used to shut down system power.

I ended up with the "gpio-poweroff" driver which also makes the
time delays configurable.

Since I noticed that platform_drv also has a device-specific
poweroff hook, I added a boolean DT value to switch between
powering down at machine_poweroff() time and powering down during
the device->poweroff() walk.

I realize that this driver is basically incapable of any kind of
runtime power management but it could be used on X86 platforms
that convert to device-tree.  In particular ones with embedded
controllers and BMC devices would otherwise be using ACPI device
methods to poke a few GPIOs in basically the same fashion.

The benefit is that instead of ACPI AML (bytecode poking magic
IO registers at some undocumented address) you have a standard
GPIO driver and a piece of pseudo-self-documenting device-tree
that basically says "the HW engineers set it up so you set these
GPIOs in that order and it turns off".

Make sense?

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20 14:38                   ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-20 14:38 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: Rob Herring, linux-kernel, devicetree-discuss, Liam Girdwood,
	Grant Likely

On Mon, Dec 19, 2011 at 07:53:06PM -0600, Moffett, Kyle D wrote:
> On Dec 19, 2011, at 20:38, Mark Brown wrote:

> > Well, it depends what you need to do.  In the ST-Ericsson case what they
> > needed to do was collapse the core supplies for the CPU.  But previously
> > you were talking about power domains, not whole system poweroff.
> > Usually a power domain is a subset of the full system power.

> Well, I have control of 3 separate power domains in the sense that
> there are 6 physically separate computers sharing a single supply,
> with 2 in each domain (and only 1 of the 6 controlling the shared
> supply).

OK, that's really not what people commonly understand by "power domain".
This is really only about system powerdown sequencing so a custom driver
is probably fine.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs
@ 2011-12-20 14:38                   ` Mark Brown
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2011-12-20 14:38 UTC (permalink / raw)
  To: Moffett, Kyle D
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Liam Girdwood

On Mon, Dec 19, 2011 at 07:53:06PM -0600, Moffett, Kyle D wrote:
> On Dec 19, 2011, at 20:38, Mark Brown wrote:

> > Well, it depends what you need to do.  In the ST-Ericsson case what they
> > needed to do was collapse the core supplies for the CPU.  But previously
> > you were talking about power domains, not whole system poweroff.
> > Usually a power domain is a subset of the full system power.

> Well, I have control of 3 separate power domains in the sense that
> there are 6 physically separate computers sharing a single supply,
> with 2 in each domain (and only 1 of the 6 controlling the shared
> supply).

OK, that's really not what people commonly understand by "power domain".
This is really only about system powerdown sequencing so a custom driver
is probably fine.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [REPOST RFC PATCH 2/3] of_gpio: Add new helpers for easily requesting lots of GPIOs
  2011-12-13 18:23 ` [REPOST RFC PATCH 2/3] of_gpio: Add new helpers for easily requesting lots of GPIOs Kyle Moffett
@ 2012-01-04 18:49   ` Grant Likely
  0 siblings, 0 replies; 24+ messages in thread
From: Grant Likely @ 2012-01-04 18:49 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Linus Walleij, devicetree-discuss, Rob Herring

On Tue, Dec 13, 2011 at 01:23:33PM -0500, Kyle Moffett wrote:
> Mirroring the new gpio_request_array() interface, we add several a few
> helper functions for operating on entire arrays of GPIOs.
> 
> Also, to make it easier to write various combinations of "of_get_gpio()"
> followed by "gpio_request()", add several other new inline wrappers.
> 
> Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> ---
>  drivers/of/gpio.c       |   96 +++++++++++++++++++++++++++++
>  include/linux/of_gpio.h |  154 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 250 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
> index f349aaf..4c04f2f 100644
> --- a/drivers/of/gpio.c
> +++ b/drivers/of/gpio.c
> @@ -83,6 +83,47 @@ err0:
>  EXPORT_SYMBOL(of_get_named_gpio_flags);
>  
>  /**
> + * of_get_gpio_array_flags() - Get array of gpios to use with GPIO API
> + * @np:		device node to get GPIOs from
> + * @of_gpios:	array of "struct of_gpio" to select which GPIOs to look up
> + * @of_flags:	array of "enum of_gpio_flags" to be filled in (may be NULL)
> + * @gpios:	array of "struct gpio" to be filled in
> + * @num:	the number of GPIOs to look up
> + *
> + * Takes a constant array of "struct of_gpio" and looks up each item in the
> + * indicated device-node.  The results are stored into the @gpios array,
> + * along with the optional GPIO "label" and "flags" values from the "of_gpio"
> + * structure.
> + *
> + * If an array of @of_flags is provided then any flags from the translate
> + * function will be stored into the corresponding element there.
> + */

That seems overly complex to me.  How many gpios are you expecting to
request?  If it is less than a handful, then I think letting the
driver call of_get_request() multiple times would still be simpler.

g.


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2012-01-04 19:06 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-13 18:23 [REPOST RFC PATCH 0/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs Kyle Moffett
2011-12-13 18:23 ` Kyle Moffett
2011-12-13 18:23 ` [REPOST RFC PATCH 1/3] of_gpio: Extend of_gpio_count() to support other property names Kyle Moffett
2011-12-13 18:23 ` [REPOST RFC PATCH 2/3] of_gpio: Add new helpers for easily requesting lots of GPIOs Kyle Moffett
2012-01-04 18:49   ` Grant Likely
2011-12-13 18:23 ` [REPOST RFC PATCH 3/3] New "gpio-poweroff" driver to turn off platform devices with GPIOs Kyle Moffett
2011-12-13 19:10 ` [REPOST RFC PATCH 0/3] " Rob Herring
2011-12-13 20:44   ` Moffett, Kyle D
2011-12-13 20:44     ` Moffett, Kyle D
2011-12-14 12:02     ` Mark Brown
2011-12-14 12:02       ` Mark Brown
2011-12-14 20:34       ` Moffett, Kyle D
2011-12-14 20:34         ` Moffett, Kyle D
2011-12-17  9:20         ` Mark Brown
2011-12-17  9:20           ` Mark Brown
2011-12-19 16:56           ` Moffett, Kyle D
2011-12-19 16:56             ` Moffett, Kyle D
2011-12-20  1:38             ` Mark Brown
2011-12-20  1:38               ` Mark Brown
2011-12-20  1:53               ` Moffett, Kyle D
2011-12-20  1:53                 ` Moffett, Kyle D
2011-12-20 14:38                 ` Mark Brown
2011-12-20 14:38                   ` Mark Brown
2011-12-14 11:59 ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.