-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:
 - compatible : should be "gpio-poweroff".
   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 */
+       gpios = <&gpio 4 0>;
 };
 
 
 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);
        mdelay(100);
-       /* rising edge or drive inactive */
+       /* drive inactive, also active->inactive edge */
        gpio_set_value(gpio_num, gpio_active_low);
        mdelay(100);
-       /* falling edge */
+
+       /* drive it active, also inactive->active edge */
        gpio_set_value(gpio_num, !gpio_active_low);
 
        /* give it some time */
        }
 
        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;
-       }
+       if (!gpio_is_valid(gpio_num))
+               return gpio_num;
+
        gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
 
-       if (of_get_property(pdev->dev.of_node, "input", NULL))
-               input = true;
+       input = of_property_read_bool(pdev->dev.of_node, "input");
 
        ret = gpio_request(gpio_num, "poweroff-gpio");
        if (ret) {
 
 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)
                pm_power_off = NULL;
 
        .probe = gpio_poweroff_probe,
        .remove = __devexit_p(gpio_poweroff_remove),
        .driver = {
-                  .name = "poweroff-gpio",
-                  .owner = THIS_MODULE,
-                  .of_match_table = of_gpio_poweroff_match,
-                  },
+               .name = "poweroff-gpio",
+               .owner = THIS_MODULE,
+               .of_match_table = of_gpio_poweroff_match,
+       },
 };
 
 module_platform_driver(gpio_poweroff_driver);
 
 MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>");
 MODULE_DESCRIPTION("GPIO poweroff driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:poweroff-gpio");