Power: gpio-poweroff: Fix documentation and gpio_is_valid
Improve the documentation to clarify level vs edge triggered power off. Improve the comments for level vs edge triggered power off. Make use of gpio_is_valid(). Reported-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
This commit is contained in:
committed by
Jason Cooper
parent
53dfa8e4aa
commit
5343527bbf
@@ -1,4 +1,19 @@
|
|||||||
GPIO line that should be set high/low to power off a device
|
Driver a GPIO line that can be used to turn the power off.
|
||||||
|
|
||||||
|
The driver supports both level triggered and edge triggered power off.
|
||||||
|
At driver load time, the driver will request the given gpio line and
|
||||||
|
install a pm_power_off handler. If the optional properties 'input' is
|
||||||
|
not found, the GPIO line will be driven in the inactive
|
||||||
|
state. Otherwise its configured as an input.
|
||||||
|
|
||||||
|
When the pm_power_off is called, the gpio is configured as an output,
|
||||||
|
and drive active, so triggering a level triggered power off
|
||||||
|
condition. This will also cause an inactive->active edge condition, so
|
||||||
|
triggering positive edge triggered power off. After a delay of 100ms,
|
||||||
|
the GPIO is set to inactive, thus causing an active->inactive edge,
|
||||||
|
triggering negative edge triggered power off. After another 100ms
|
||||||
|
delay the GPIO is driver active again. If the power is still on and
|
||||||
|
the CPU still running after a 3000ms delay, a WARN_ON(1) is emitted.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : should be "gpio-poweroff".
|
- compatible : should be "gpio-poweroff".
|
||||||
@@ -13,10 +28,9 @@ Optional properties:
|
|||||||
property is not specified, the GPIO is initialized as an output in its
|
property is not specified, the GPIO is initialized as an output in its
|
||||||
inactive state.
|
inactive state.
|
||||||
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
gpio-poweroff {
|
gpio-poweroff {
|
||||||
compatible = "gpio-poweroff";
|
compatible = "gpio-poweroff";
|
||||||
gpios = <&gpio 4 0>; /* GPIO 4 Active Low */
|
gpios = <&gpio 4 0>;
|
||||||
};
|
};
|
||||||
|
@@ -29,15 +29,16 @@ static int gpio_active_low;
|
|||||||
|
|
||||||
static void gpio_poweroff_do_poweroff(void)
|
static void gpio_poweroff_do_poweroff(void)
|
||||||
{
|
{
|
||||||
BUG_ON(gpio_num == -1);
|
BUG_ON(!gpio_is_valid(gpio_num));
|
||||||
|
|
||||||
/* drive it active */
|
/* drive it active, also inactive->active edge */
|
||||||
gpio_direction_output(gpio_num, !gpio_active_low);
|
gpio_direction_output(gpio_num, !gpio_active_low);
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
/* rising edge or drive inactive */
|
/* drive inactive, also active->inactive edge */
|
||||||
gpio_set_value(gpio_num, gpio_active_low);
|
gpio_set_value(gpio_num, gpio_active_low);
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
/* falling edge */
|
|
||||||
|
/* drive it active, also inactive->active edge */
|
||||||
gpio_set_value(gpio_num, !gpio_active_low);
|
gpio_set_value(gpio_num, !gpio_active_low);
|
||||||
|
|
||||||
/* give it some time */
|
/* give it some time */
|
||||||
@@ -60,15 +61,12 @@ static int __devinit gpio_poweroff_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
|
gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
|
||||||
if (gpio_num < 0) {
|
if (!gpio_is_valid(gpio_num))
|
||||||
pr_err("%s: Could not get GPIO configuration: %d",
|
return gpio_num;
|
||||||
__func__, gpio_num);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
|
gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||||
|
|
||||||
if (of_get_property(pdev->dev.of_node, "input", NULL))
|
input = of_property_read_bool(pdev->dev.of_node, "input");
|
||||||
input = true;
|
|
||||||
|
|
||||||
ret = gpio_request(gpio_num, "poweroff-gpio");
|
ret = gpio_request(gpio_num, "poweroff-gpio");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -98,7 +96,6 @@ err:
|
|||||||
|
|
||||||
static int __devexit gpio_poweroff_remove(struct platform_device *pdev)
|
static int __devexit gpio_poweroff_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
if (gpio_num != -1)
|
|
||||||
gpio_free(gpio_num);
|
gpio_free(gpio_num);
|
||||||
if (pm_power_off == &gpio_poweroff_do_poweroff)
|
if (pm_power_off == &gpio_poweroff_do_poweroff)
|
||||||
pm_power_off = NULL;
|
pm_power_off = NULL;
|
||||||
@@ -125,5 +122,5 @@ module_platform_driver(gpio_poweroff_driver);
|
|||||||
|
|
||||||
MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>");
|
MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>");
|
||||||
MODULE_DESCRIPTION("GPIO poweroff driver");
|
MODULE_DESCRIPTION("GPIO poweroff driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_ALIAS("platform:poweroff-gpio");
|
MODULE_ALIAS("platform:poweroff-gpio");
|
||||||
|
Reference in New Issue
Block a user