From: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
To: linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org
Cc: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>,
Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org>,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
gmbnomis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Subject: [PATCH 1/3] gpio: Add simple poweroff-gpio driver
Date: Sun, 11 Nov 2012 17:21:29 +0100 [thread overview]
Message-ID: <1352650891-18356-2-git-send-email-andrew@lunn.ch> (raw)
In-Reply-To: <1352650891-18356-1-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
From: Jamie Lentin <jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org>
Given appropriate devicetree bindings, this driver registers a
pm_power_off function to set a GPIO line high/low to power down
your board.
Signed-off-by: Jamie Lentin <jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org>
Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
---
.../devicetree/bindings/gpio/gpio-poweroff.txt | 22 ++++
drivers/gpio/Kconfig | 10 ++
drivers/gpio/Makefile | 2 +
drivers/gpio/gpio-poweroff.c | 129 ++++++++++++++++++++
4 files changed, 163 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
create mode 100644 drivers/gpio/gpio-poweroff.c
diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
new file mode 100644
index 0000000..558cdf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
@@ -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 */
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d055cee..5ec1714 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -75,6 +75,16 @@ config GPIO_SYSFS
Kernel drivers may also request that a particular GPIO be
exported to userspace; this can be useful when debugging.
+config GPIO_POWEROFF
+ tristate "GPIO power-off driver"
+ depends on OF_GPIO
+ help
+ This driver supports turning off your device via a GPIO line.
+ If your device needs a GPIO high/low to power down, say Y and
+ create a binding in your devicetree.
+
+ If unsure, say N
+
config GPIO_GENERIC
tristate
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9aeed67..a8efda3 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -5,6 +5,8 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
+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..101ad57
--- /dev/null
+++ b/drivers/gpio/gpio-poweroff.c
@@ -0,0 +1,129 @@
+/*
+ * Toggles a GPIO pin to power down a device
+ *
+ * Jamie Lentin <jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org>
+ * Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
+ *
+ * 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 */
+ 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);
+
+ WARN_ON(1);
+}
+
+static int __devinit gpio_poweroff_probe(struct platform_device *pdev)
+{
+ enum of_gpio_flags flags;
+ bool input = false;
+ int ret;
+
+ /* If a pm_power_off function has already been added, leave it alone */
+ if (pm_power_off != NULL) {
+ pr_err("%s: pm_power_off function already registered",
+ __func__);
+ return -EBUSY;
+ }
+
+ gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
+ if (gpio_num < 0) {
+ pr_err("%s: Could not get GPIO configuration: %d",
+ __func__, gpio_num);
+ return -ENODEV;
+ }
+ gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ if (of_get_property(pdev->dev.of_node, "input", NULL))
+ input = true;
+
+ ret = gpio_request(gpio_num, "poweroff-gpio");
+ if (ret) {
+ pr_err("%s: Could not get GPIO %d", __func__, gpio_num);
+ return ret;
+ }
+ if (input) {
+ if (gpio_direction_input(gpio_num)) {
+ pr_err("Could not set direction of GPIO %d to input",
+ gpio_num);
+ goto err;
+ }
+ } else {
+ if (gpio_direction_output(gpio_num, gpio_active_low)) {
+ pr_err("Could not set direction of GPIO %d", gpio_num);
+ goto err;
+ }
+ }
+
+ pm_power_off = &gpio_poweroff_do_poweroff;
+ return 0;
+
+err:
+ gpio_free(gpio_num);
+ return -ENODEV;
+}
+
+static int __devexit gpio_poweroff_remove(struct platform_device *pdev)
+{
+ if (gpio_num != -1)
+ gpio_free(gpio_num);
+ if (pm_power_off == &gpio_poweroff_do_poweroff)
+ pm_power_off = NULL;
+
+ return 0;
+}
+
+static const struct of_device_id of_gpio_poweroff_match[] = {
+ { .compatible = "gpio-poweroff", },
+ {},
+};
+
+static struct platform_driver gpio_poweroff_driver = {
+ .probe = gpio_poweroff_probe,
+ .remove = __devexit_p(gpio_poweroff_remove),
+ .driver = {
+ .name = "poweroff-gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = of_gpio_poweroff_match,
+ },
+};
+
+module_platform_driver(gpio_poweroff_driver);
+
+MODULE_AUTHOR("Jamie Lentin <jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org>");
+MODULE_DESCRIPTION("GPIO poweroff driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:poweroff-gpio");
--
1.7.10.4
next prev parent reply other threads:[~2012-11-11 16:21 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-11 16:21 [PATCH 0/3] GPIO driver to turn power off Andrew Lunn
[not found] ` <1352650891-18356-1-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-11 16:21 ` Andrew Lunn [this message]
[not found] ` <1352650891-18356-2-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-11 22:03 ` [PATCH 1/3] gpio: Add simple poweroff-gpio driver Stephen Warren
[not found] ` <50A020C5.4070506-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-11-12 8:25 ` Andrew Lunn
[not found] ` <20121112082546.GU22029-g2DYL2Zd6BY@public.gmane.org>
2012-11-12 16:17 ` Stephen Warren
[not found] ` <50A1212C.2080601-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-11-12 18:19 ` Andrew Lunn
[not found] ` <20121112181947.GS24583-g2DYL2Zd6BY@public.gmane.org>
2012-11-12 18:43 ` Anton Vorontsov
2012-11-12 18:58 ` Stephen Warren
[not found] ` <50A146E7.2040608-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-11-12 19:17 ` Anton Vorontsov
2012-11-15 10:35 ` Linus Walleij
[not found] ` <CACRpkdb=ra9NwqEneyMoM5YnOFTVQoBxPATjUN6anooXVLiCjw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-15 10:59 ` Anton Vorontsov
2012-11-15 11:10 ` Linus Walleij
[not found] ` <CACRpkdZ_4C2XA1c2U_E8GnbfiXZk67MYR7JzgwXf1iVwHCde2Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-21 13:17 ` Grant Likely
2012-11-15 18:00 ` Stephen Warren
2012-11-12 1:00 ` Linus Walleij
[not found] ` <CACRpkdZvHBjFQTrQnxvc3WCOb2CqGbjYJxyQ5qQkSbU+UWHYZA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-12 1:12 ` Anton Vorontsov
2012-11-12 6:07 ` Andrew Lunn
[not found] ` <20121112060740.GR24583-g2DYL2Zd6BY@public.gmane.org>
2012-11-12 6:53 ` Anton Vorontsov
2012-11-15 18:05 ` Grant Likely
2012-11-15 18:11 ` Jamie Lentin
[not found] ` <alpine.DEB.2.00.1211151810050.25381-5X291BYdrx55rAo4AelP/Ydd74u8MsAO@public.gmane.org>
2012-11-15 18:21 ` Grant Likely
[not found] ` <CACxGe6tgNVH9zeafMRKXcRUZmQjQXrAy_QtvhxpTT74200Hnxg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-21 13:20 ` Grant Likely
2012-11-11 16:21 ` [PATCH 2/3] ARM: Kirkwood: Convert DNSKW to use gpio-poweroff Andrew Lunn
2012-11-11 16:21 ` [PATCH 3/3] ARM: Kirkwood: Convert IB62x0 " Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1352650891-18356-2-git-send-email-andrew@lunn.ch \
--to=andrew-g2dyl2zd6by@public.gmane.org \
--cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
--cc=gmbnomis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org \
--cc=jm-Pj/HzkgeCk7QXOPxS62xeg@public.gmane.org \
--cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).