Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andrew Lunn and committed by
Jason Cooper
5343527b 53dfa8e4

+32 -21
+17 -3
Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
··· 1 - GPIO line that should be set high/low to power off a device 1 + Driver a GPIO line that can be used to turn the power off. 2 + 3 + The driver supports both level triggered and edge triggered power off. 4 + At driver load time, the driver will request the given gpio line and 5 + install a pm_power_off handler. If the optional properties 'input' is 6 + not found, the GPIO line will be driven in the inactive 7 + state. Otherwise its configured as an input. 8 + 9 + When the pm_power_off is called, the gpio is configured as an output, 10 + and drive active, so triggering a level triggered power off 11 + condition. This will also cause an inactive->active edge condition, so 12 + triggering positive edge triggered power off. After a delay of 100ms, 13 + the GPIO is set to inactive, thus causing an active->inactive edge, 14 + triggering negative edge triggered power off. After another 100ms 15 + delay the GPIO is driver active again. If the power is still on and 16 + the CPU still running after a 3000ms delay, a WARN_ON(1) is emitted. 2 17 3 18 Required properties: 4 19 - compatible : should be "gpio-poweroff". ··· 28 13 property is not specified, the GPIO is initialized as an output in its 29 14 inactive state. 30 15 31 - 32 16 Examples: 33 17 34 18 gpio-poweroff { 35 19 compatible = "gpio-poweroff"; 36 - gpios = <&gpio 4 0>; /* GPIO 4 Active Low */ 20 + gpios = <&gpio 4 0>; 37 21 };
+15 -18
drivers/power/reset/gpio-poweroff.c
··· 29 29 30 30 static void gpio_poweroff_do_poweroff(void) 31 31 { 32 - BUG_ON(gpio_num == -1); 32 + BUG_ON(!gpio_is_valid(gpio_num)); 33 33 34 - /* drive it active */ 34 + /* drive it active, also inactive->active edge */ 35 35 gpio_direction_output(gpio_num, !gpio_active_low); 36 36 mdelay(100); 37 - /* rising edge or drive inactive */ 37 + /* drive inactive, also active->inactive edge */ 38 38 gpio_set_value(gpio_num, gpio_active_low); 39 39 mdelay(100); 40 - /* falling edge */ 40 + 41 + /* drive it active, also inactive->active edge */ 41 42 gpio_set_value(gpio_num, !gpio_active_low); 42 43 43 44 /* give it some time */ ··· 61 60 } 62 61 63 62 gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); 64 - if (gpio_num < 0) { 65 - pr_err("%s: Could not get GPIO configuration: %d", 66 - __func__, gpio_num); 67 - return -ENODEV; 68 - } 63 + if (!gpio_is_valid(gpio_num)) 64 + return gpio_num; 65 + 69 66 gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; 70 67 71 - if (of_get_property(pdev->dev.of_node, "input", NULL)) 72 - input = true; 68 + input = of_property_read_bool(pdev->dev.of_node, "input"); 73 69 74 70 ret = gpio_request(gpio_num, "poweroff-gpio"); 75 71 if (ret) { ··· 96 98 97 99 static int __devexit gpio_poweroff_remove(struct platform_device *pdev) 98 100 { 99 - if (gpio_num != -1) 100 - gpio_free(gpio_num); 101 + gpio_free(gpio_num); 101 102 if (pm_power_off == &gpio_poweroff_do_poweroff) 102 103 pm_power_off = NULL; 103 104 ··· 112 115 .probe = gpio_poweroff_probe, 113 116 .remove = __devexit_p(gpio_poweroff_remove), 114 117 .driver = { 115 - .name = "poweroff-gpio", 116 - .owner = THIS_MODULE, 117 - .of_match_table = of_gpio_poweroff_match, 118 - }, 118 + .name = "poweroff-gpio", 119 + .owner = THIS_MODULE, 120 + .of_match_table = of_gpio_poweroff_match, 121 + }, 119 122 }; 120 123 121 124 module_platform_driver(gpio_poweroff_driver); 122 125 123 126 MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>"); 124 127 MODULE_DESCRIPTION("GPIO poweroff driver"); 125 - MODULE_LICENSE("GPL"); 128 + MODULE_LICENSE("GPL v2"); 126 129 MODULE_ALIAS("platform:poweroff-gpio");