Skip to contentSkip to conversation

GPIO driver to turn power off

PATCH Superseded Andrew Lunn 5 participants 12 messages Nov 13, 2012 – Nov 17, 2012

Subsystems (5)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover GPIO driver to turn power off

A few of the Kirkwood systems use a GPIO line to turn the power off on shutdown. They request the GPIO line in the board setup code, optionally setting it as an output and driving it inactive. They then register a function for pm_power_off. At the end of the shutdown, this function is called. The GPIO line is configured as an output, if not already so, and then driven active. In order to cover the use case of edges rather then levels, triggering power off, the GPIO line is then toggled active and later inactive. This should allow the driver to be used by PXA which also has boards using the same scheme.

The driver code was initially developed by Jamie Lentin and extended to cover the PXA case by Andrew Lunn.

v1 -> v2: Moved to drivers/power/reset

Andrew Lunn (2):
ARM: Kirkwood: Convert DNSKW to use gpio-poweroff.
ARM: Kirkwood: Convert IB62x0 to use gpio-poweroff.

Jamie Lentin (1):
power: Add simple poweroff-gpio driver

 .../devicetree/bindings/gpio/gpio-poweroff.txt     |   22 ++++
 arch/arm/boot/dts/kirkwood-dnskw.dtsi              |    5 +
 arch/arm/boot/dts/kirkwood-ib62x0.dts              |    6 +
 arch/arm/mach-kirkwood/Kconfig                     |    4 +
 arch/arm/mach-kirkwood/board-dnskw.c               |   12 --
 arch/arm/mach-kirkwood/board-ib62x0.c              |   13 --
 drivers/power/Kconfig                              |    3 +
 drivers/power/Makefile                             |    1 +
 drivers/power/reset/Kconfig                        |   15 +++
 drivers/power/reset/Makefile                       |    1 +
 drivers/power/reset/gpio-poweroff.c                |  129 ++++++++++++++++++++
 11 files changed, 186 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
 create mode 100644 drivers/power/reset/Kconfig
 create mode 100644 drivers/power/reset/Makefile
 create mode 100644 drivers/power/reset/gpio-poweroff.c
Signature · 1 line
1.7.10.4
#1 lore raw

PATCH v2 1/3 power: Add simple poweroff-gpio driver

From: Jamie Lentin <[email protected]>

Given appropriate devicetree bindings, this driver registers a pm_power_off function to set a GPIO line high/low to power down your board.

---
 .../devicetree/bindings/gpio/gpio-poweroff.txt     |   22 ++++
 drivers/power/Kconfig                              |    3 +
 drivers/power/Makefile                             |    1 +
 drivers/power/reset/Kconfig                        |   15 +++
 drivers/power/reset/Makefile                       |    1 +
 drivers/power/reset/gpio-poweroff.c                |  129 ++++++++++++++++++++
 6 files changed, 171 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
 create mode 100644 drivers/power/reset/Kconfig
 create mode 100644 drivers/power/reset/Makefile
 create mode 100644 drivers/power/reset/gpio-poweroff.c
Documentation/devicetree/bindings/gpio/gpio-poweroff.txt new file +22 -0
new file mode 100644
index 0000000..558cdf3
@@ -0,0 +1,22 @@
+GPIO line that should be set high/low to power off a device
+
+Required properties:
+- compatible : should be "gpio-poweroff".
+- gpios : The GPIO to set high/low, see "gpios property" in
+  Documentation/devicetree/bindings/gpio/gpio.txt. If the pin should be
+  low to power down the board set it to "Active Low", otherwise set
+  gpio to "Active High".
+
+Optional properties:
+- input : Initially configure the GPIO line as an input. Only reconfigure
+  it to an output when the pm_power_off function is called. If this optional
+  property is not specified, the GPIO is initialized as an output in its
+  inactive state.
+
+
+Examples:
+
+gpio-poweroff {
+	compatible = "gpio-poweroff";
+	gpios = <&gpio 4 0>; /* GPIO 4 Active Low */
+};
drivers/power/Kconfig +3 -0
index 49a8939..b1d956d 100644
@@ -335,6 +335,9 @@ config AB8500_BATTERY_THERM_ON_BATCTRL
 	help
 	  Say Y to enable battery temperature measurements using
 	  thermistor connected on BATCTRL ADC.
+
+source "drivers/power/reset/Kconfig"
+
 endif # POWER_SUPPLY
 
 source "drivers/power/avs/Kconfig"
drivers/power/Makefile +1 -0
index b949cf8..f1d99f4 100644
@@ -49,3 +49,4 @@ obj-$(CONFIG_CHARGER_MAX8997)	+= max8997_charger.o
 obj-$(CONFIG_CHARGER_MAX8998)	+= max8998_charger.o
 obj-$(CONFIG_POWER_AVS)		+= avs/
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
+obj-$(CONFIG_POWER_RESET)	+= reset/
drivers/power/reset/Kconfig new file +15 -0
new file mode 100644
index 0000000..6461b48
@@ -0,0 +1,15 @@
+menuconfig POWER_RESET
+	bool "Board level reset or power off"
+	help
+	  Provides a number of drivers which either reset a complete board
+	  or shut it down, by manipulating the main power supply on the board.
+
+	  Say Y here to enable board reset and power off
+
+config POWER_RESET_GPIO
+	bool "GPIO power-off driver"
+	depends on OF_GPIO && POWER_RESET
+	help
+	  This driver supports turning off your board via a GPIO line.
+	  If your board needs a GPIO high/low to power down, say Y and
+	  create a binding in your devicetree.
drivers/power/reset/Makefile new file +1 -0
new file mode 100644
index 0000000..751488a
@@ -0,0 +1 @@
+obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
drivers/power/reset/gpio-poweroff.c new file +129 -0

129 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#3 lore raw

PATCH v2 1/3 power: Add simple poweroff-gpio driver

In reply to Andrew Lunn

Hi Andrew,

Quoted 140 lines · Andrew Lunn

From: Jamie Lentin <[email protected]>

Given appropriate devicetree bindings, this driver registers a pm_power_off function to set a GPIO line high/low to power down your board.

---
 .../devicetree/bindings/gpio/gpio-poweroff.txt     |   22 ++++
 drivers/power/Kconfig                              |    3 +
 drivers/power/Makefile                             |    1 +
 drivers/power/reset/Kconfig                        |   15 +++
 drivers/power/reset/Makefile                       |    1 +
 drivers/power/reset/gpio-poweroff.c                |  129 ++++++++++++++++++++
 6 files changed, 171 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
 create mode 100644 drivers/power/reset/Kconfig
 create mode 100644 drivers/power/reset/Makefile
 create mode 100644 drivers/power/reset/gpio-poweroff.c
Documentation/devicetree/bindings/gpio/gpio-poweroff.txt new file +22 -0
new file mode 100644
index 0000000..558cdf3
@@ -0,0 +1,22 @@
+GPIO line that should be set high/low to power off a device
+
+Required properties:
+- compatible : should be "gpio-poweroff".
+- gpios : The GPIO to set high/low, see "gpios property" in
+  Documentation/devicetree/bindings/gpio/gpio.txt. If the pin should be
+  low to power down the board set it to "Active Low", otherwise set
+  gpio to "Active High".
+
+Optional properties:
+- input : Initially configure the GPIO line as an input. Only reconfigure
+  it to an output when the pm_power_off function is called. If this optional
+  property is not specified, the GPIO is initialized as an output in its
+  inactive state.
+
+
+Examples:
+
+gpio-poweroff {
+	compatible = "gpio-poweroff";
+	gpios = <&gpio 4 0>; /* GPIO 4 Active Low */
+};
drivers/power/Kconfig +3 -0
index 49a8939..b1d956d 100644
@@ -335,6 +335,9 @@ config AB8500_BATTERY_THERM_ON_BATCTRL
 	help
 	  Say Y to enable battery temperature measurements using
 	  thermistor connected on BATCTRL ADC.
+
+source "drivers/power/reset/Kconfig"
+
 endif # POWER_SUPPLY
 
 source "drivers/power/avs/Kconfig"
drivers/power/Makefile +1 -0
index b949cf8..f1d99f4 100644
@@ -49,3 +49,4 @@ obj-$(CONFIG_CHARGER_MAX8997)	+= max8997_charger.o
 obj-$(CONFIG_CHARGER_MAX8998)	+= max8998_charger.o
 obj-$(CONFIG_POWER_AVS)		+= avs/
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
+obj-$(CONFIG_POWER_RESET)	+= reset/
drivers/power/reset/Kconfig new file +15 -0
new file mode 100644
index 0000000..6461b48
@@ -0,0 +1,15 @@
+menuconfig POWER_RESET
+	bool "Board level reset or power off"
+	help
+	  Provides a number of drivers which either reset a complete board
+	  or shut it down, by manipulating the main power supply on the board.
+
+	  Say Y here to enable board reset and power off
+
+config POWER_RESET_GPIO
+	bool "GPIO power-off driver"
+	depends on OF_GPIO && POWER_RESET
+	help
+	  This driver supports turning off your board via a GPIO line.
+	  If your board needs a GPIO high/low to power down, say Y and
+	  create a binding in your devicetree.
drivers/power/reset/Makefile new file +1 -0
new file mode 100644
index 0000000..751488a
@@ -0,0 +1 @@
+obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
drivers/power/reset/gpio-poweroff.c new file +34 -0
new file mode 100644
index 0000000..101ad57
@@ -0,0 +1,129 @@
+/*
+ * Toggles a GPIO pin to power down a device
+ *
+ * Jamie Lentin <[email protected]>
+ * Andrew Lunn <[email protected]>
+ *
+ * Copyright (C) 2012 Jamie Lentin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+
+/*
+ * Hold configuration here, cannot be more than one instance of the driver
+ * since pm_power_off itself is global.
+ */
+static int gpio_num = -1;
+static int gpio_active_low;
+
+static void gpio_poweroff_do_poweroff(void)
+{
+	BUG_ON(gpio_num == -1);
+
+	/* drive it active */

drivers/power/reset/gpio-poweroff.c line 44

Quoted 10 lines
drivers/power/reset/gpio-poweroff.c new file +10 -0
+	gpio_direction_output(gpio_num, !gpio_active_low);
+	mdelay(100);
+	/* rising edge or drive inactive */
+	gpio_set_value(gpio_num, gpio_active_low);
+	mdelay(100);
+	/* falling edge */
+	gpio_set_value(gpio_num, !gpio_active_low);
+
+	/* give it some time */
+	mdelay(100);

On the IB-NAS 6210 I need to increase this delay to a whopping 3000 milliseconds to suppress the warning (2000 is not enough). Is it acceptable to increase this to such a high value or do we need another solution?

drivers/power/reset/gpio-poweroff.c line 46

Quoted 3 lines
drivers/power/reset/gpio-poweroff.c new file +2 -0
+
+	WARN_ON(1);
...

- Simon

#4 lore raw

PATCH v2 1/3 power: Add simple poweroff-gpio driver

Quoted 18 lines
Quoted 18 lines

+ * Hold configuration here, cannot be more than one instance of the driver
+ * since pm_power_off itself is global.
+ */

drivers/power/reset/gpio-poweroff.c new file +15 -0
+static int gpio_num = -1;
+static int gpio_active_low;
+
+static void gpio_poweroff_do_poweroff(void)
+{
+	BUG_ON(gpio_num == -1);
+
+	/* drive it active */
+	gpio_direction_output(gpio_num, !gpio_active_low);
+	mdelay(100);
+	/* rising edge or drive inactive */
+	gpio_set_value(gpio_num, gpio_active_low);
+	mdelay(100);
+	/* falling edge */
+	gpio_set_value(gpio_num, !gpio_active_low);
Quoted 8 lines

drivers/power/reset/gpio-poweroff.c line 44

Quoted 3 lines
drivers/power/reset/gpio-poweroff.c new file +3 -0
+
+	/* give it some time */
+	mdelay(100);

On the IB-NAS 6210 I need to increase this delay to a whopping 3000 milliseconds to suppress the warning (2000 is not enough). Is it acceptable to increase this to such a high value or do we need another solution?

Hi Simon

It is interesting how slow these things are at turning off. I already had to increase it once from 10ms for the DNSKW.

So i will increase it to 3000 in the next spin of the patches.

Thanks

Andrew

#5 lore raw

PATCH v2 2/3 ARM: Kirkwood: Convert DNSKW to use gpio-poweroff.

In reply to Andrew Lunn

Also enable the gpio-poweroff driver when DT is used.

---
 arch/arm/boot/dts/kirkwood-dnskw.dtsi |    5 +++++
 arch/arm/mach-kirkwood/Kconfig        |    4 ++++
 arch/arm/mach-kirkwood/board-dnskw.c  |   12 ------------
 3 files changed, 9 insertions(+), 12 deletions(-)
arch/arm/boot/dts/kirkwood-dnskw.dtsi +5 -0
index 9b32d02..22aa07a 100644
@@ -35,6 +35,11 @@
 				      6000 2>;
 	};
 
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio1 4 0>;
+	};
+
 	ocp at f1000000 {
 		sata at 80000 {
 			status = "okay";
arch/arm/mach-kirkwood/Kconfig +4 -0
index 50bca50..e0d26fe 100644
@@ -46,7 +46,11 @@ config MACH_GURUPLUG
 
 config ARCH_KIRKWOOD_DT
 	bool "Marvell Kirkwood Flattened Device Tree"
+	select POWER_SUPPLY
+	select POWER_RESET
+	select POWER_RESET_GPIO
 	select USE_OF
+
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell Kirkwood using flattened device tree.
arch/arm/mach-kirkwood/board-dnskw.c +0 -12
index 43d16d6..549369e 100644
@@ -57,11 +57,6 @@ static unsigned int dnskw_mpp_config[] __initdata = {
 	0
 };
 
-static void dnskw_power_off(void)
-{
-	gpio_set_value(36, 1);
-}
-
 /* Register any GPIO for output and set the value */
 static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
 {
@@ -81,13 +76,6 @@ void __init dnskw_init(void)
 	kirkwood_ehci_init();
 	kirkwood_ge00_init(&dnskw_ge00_data);
 
-	/* Register power-off GPIO. */
-	if (gpio_request(36, "dnskw:power:off") == 0
-	    && gpio_direction_output(36, 0) == 0)
-		pm_power_off = dnskw_power_off;
-	else
-		pr_err("dnskw: failed to configure power-off GPIO\n");
-
 	/* Ensure power is supplied to both HDDs */
 	dnskw_gpio_register(39, "dnskw:power:sata0", 1);
 	dnskw_gpio_register(40, "dnskw:power:sata1", 1);
Signature · 1 line
1.7.10.4
#6 lore raw

PATCH v2 3/3 ARM: Kirkwood: Convert IB62x0 to use gpio-poweroff.

In reply to Andrew Lunn
---
 arch/arm/boot/dts/kirkwood-ib62x0.dts |    6 ++++++
 arch/arm/mach-kirkwood/board-ib62x0.c |   13 -------------
 2 files changed, 6 insertions(+), 13 deletions(-)
arch/arm/boot/dts/kirkwood-ib62x0.dts +6 -0
index 66794ed..9b0e2e3 100644
@@ -79,4 +79,10 @@
 			gpios = <&gpio0 27 0>;
 		};
 	};
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 24 1>;
+	};
+
+
 };
arch/arm/mach-kirkwood/board-ib62x0.c +0 -13
index cfc47f8..7b8adf5 100644
@@ -17,7 +17,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
 #include <linux/input.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -25,8 +24,6 @@
 #include "common.h"
 #include "mpp.h"
 
-#define IB62X0_GPIO_POWER_OFF	24
-
 static struct mv643xx_eth_platform_data ib62x0_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
@@ -49,11 +46,6 @@ static unsigned int ib62x0_mpp_config[] __initdata = {
 	0
 };
 
-static void ib62x0_power_off(void)
-{
-	gpio_set_value(IB62X0_GPIO_POWER_OFF, 1);
-}
-
 void __init ib62x0_init(void)
 {
 	/*
@@ -63,9 +55,4 @@ void __init ib62x0_init(void)
 
 	kirkwood_ehci_init();
 	kirkwood_ge00_init(&ib62x0_ge00_data);
-	if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 &&
-	    gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0)
-		pm_power_off = ib62x0_power_off;
-	else
-		pr_err("board-ib62x0: failed to configure power-off GPIO\n");
 }
Signature · 1 line
1.7.10.4
#7 lore raw

PATCH v2 3/3 ARM: Kirkwood: Convert IB62x0 to use gpio-poweroff.

Hi Andrew,

Quoted 11 lines · Andrew Lunn
---
 arch/arm/boot/dts/kirkwood-ib62x0.dts |    6 ++++++
 arch/arm/mach-kirkwood/board-ib62x0.c |   13 -------------
 2 files changed, 6 insertions(+), 13 deletions(-)
arch/arm/boot/dts/kirkwood-ib62x0.dts +0 -0
index 66794ed..9b0e2e3 100644

arch/arm/boot/dts/kirkwood-ib62x0.dts line 84

Quoted 6 lines
arch/arm/boot/dts/kirkwood-ib62x0.dts +3 -0
@@ -79,4 +79,10 @@
 			gpios = <&gpio0 27 0>;
 		};
 	};
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 24 1>;

This needs to be:

		gpios = <&gpio0 24 0>;

If the GPIO is configured as an input, the box shuts down when initializing the driver.

With this change:

Btw., I also tested it on top of your pinctrl changes, which works like a charm as well.

- Simon

#8 lore raw

PATCH v2 3/3 ARM: Kirkwood: Convert IB62x0 to use gpio-poweroff.

Quoted 22 lines · Simon Baatz

Hi Andrew,

Quoted 11 lines · Andrew Lunn
---
 arch/arm/boot/dts/kirkwood-ib62x0.dts |    6 ++++++
 arch/arm/mach-kirkwood/board-ib62x0.c |   13 -------------
 2 files changed, 6 insertions(+), 13 deletions(-)
arch/arm/boot/dts/kirkwood-ib62x0.dts +0 -0
index 66794ed..9b0e2e3 100644

arch/arm/boot/dts/kirkwood-ib62x0.dts line 84

Quoted 6 lines
arch/arm/boot/dts/kirkwood-ib62x0.dts +3 -0
@@ -79,4 +79,10 @@
 			gpios = <&gpio0 27 0>;
 		};
 	};
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 24 1>;

This needs to be:

Quoted 1 line
		gpios = <&gpio0 24 0>;

I also got it wrong on Jamie's board!

Quoted 10 lines

If the GPIO is configured as an input, the box shuts down when initializing the driver.

With this change:

Btw., I also tested it on top of your pinctrl changes, which works like a charm as well.

Thanks for testing that.

Andrew

#9 lore raw

v2 cover GPIO driver to turn power off

In reply to Andrew Lunn
Quoted 22 lines · Andrew Lunn

A few of the Kirkwood systems use a GPIO line to turn the power off on shutdown. They request the GPIO line in the board setup code, optionally setting it as an output and driving it inactive. They then register a function for pm_power_off. At the end of the shutdown, this function is called. The GPIO line is configured as an output, if not already so, and then driven active. In order to cover the use case of edges rather then levels, triggering power off, the GPIO line is then toggled active and later inactive. This should allow the driver to be used by PXA which also has boards using the same scheme.

The driver code was initially developed by Jamie Lentin and extended to cover the PXA case by Andrew Lunn.

v1 -> v2: Moved to drivers/power/reset

Andrew Lunn (2):
ARM: Kirkwood: Convert DNSKW to use gpio-poweroff.
ARM: Kirkwood: Convert IB62x0 to use gpio-poweroff.

Jamie Lentin (1):
power: Add simple poweroff-gpio driver

Quoted 16 lines
 .../devicetree/bindings/gpio/gpio-poweroff.txt     |   22 ++++
 arch/arm/boot/dts/kirkwood-dnskw.dtsi              |    5 +
 arch/arm/boot/dts/kirkwood-ib62x0.dts              |    6 +
 arch/arm/mach-kirkwood/Kconfig                     |    4 +
 arch/arm/mach-kirkwood/board-dnskw.c               |   12 --
 arch/arm/mach-kirkwood/board-ib62x0.c              |   13 --
 drivers/power/Kconfig                              |    3 +
 drivers/power/Makefile                             |    1 +
 drivers/power/reset/Kconfig                        |   15 +++
 drivers/power/reset/Makefile                       |    1 +
 drivers/power/reset/gpio-poweroff.c                |  129 ++++++++++++++++++++
 11 files changed, 186 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
 create mode 100644 drivers/power/reset/Kconfig
 create mode 100644 drivers/power/reset/Makefile
 create mode 100644 drivers/power/reset/gpio-poweroff.c

Anton,

Is it ok if we take this through the arm-soc tree with your Ack?

thx,

Jason.

#10 lore raw

v2 cover GPIO driver to turn power off

On Fri, Nov 16, 2012 at 09:19:47AM -0500, Jason Cooper wrote:
[...]

Quoted 1 line

Is it ok if we take this through the arm-soc tree with your Ack?

Yup. The driver looks good.

Thanks.

#11 lore raw

v2 cover GPIO driver to turn power off

Quoted 7 lines · Anton Vorontsov

On Fri, Nov 16, 2012 at 09:19:47AM -0500, Jason Cooper wrote:
[...]

Quoted 1 line

Is it ok if we take this through the arm-soc tree with your Ack?

Yup. The driver looks good.

Hi Anton

Thanks for the ACK.

I will respin another version, with the delay before WARN() increased, and fix the polarity of the GPIO i got wrong.

Andrew