* published by the Free Software Foundation.
  */
 
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
        unsigned int            lth_brightness;
        unsigned int            *levels;
        bool                    enabled;
+       int                     enable_gpio;
+       unsigned long           enable_gpio_flags;
        int                     (*notify)(struct device *,
                                          int brightness);
        void                    (*notify_after)(struct device *,
                     pb->lth_brightness;
 
        pwm_config(pb->pwm, duty_cycle, pb->period);
+
+       if (gpio_is_valid(pb->enable_gpio)) {
+               if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
+                       gpio_set_value(pb->enable_gpio, 0);
+               else
+                       gpio_set_value(pb->enable_gpio, 1);
+       }
+
        pwm_enable(pb->pwm);
        pb->enabled = true;
 }
        pwm_config(pb->pwm, 0, pb->period);
        pwm_disable(pb->pwm);
 
+       if (gpio_is_valid(pb->enable_gpio)) {
+               if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
+                       gpio_set_value(pb->enable_gpio, 1);
+               else
+                       gpio_set_value(pb->enable_gpio, 0);
+       }
+
        pb->enabled = false;
 }
 
                                  struct platform_pwm_backlight_data *data)
 {
        struct device_node *node = dev->of_node;
+       enum of_gpio_flags flags;
        struct property *prop;
        int length;
        u32 value;
                data->max_brightness--;
        }
 
-       /*
-        * TODO: Most users of this driver use a number of GPIOs to control
-        *       backlight power. Support for specifying these needs to be
-        *       added.
-        */
+       data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0,
+                                                   &flags);
+       if (data->enable_gpio == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
+       if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW))
+               data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW;
 
        return 0;
 }
        } else
                max = data->max_brightness;
 
+       pb->enable_gpio = data->enable_gpio;
+       pb->enable_gpio_flags = data->enable_gpio_flags;
        pb->notify = data->notify;
        pb->notify_after = data->notify_after;
        pb->check_fb = data->check_fb;
        pb->dev = &pdev->dev;
        pb->enabled = false;
 
+       if (gpio_is_valid(pb->enable_gpio)) {
+               unsigned long flags;
+
+               if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
+                       flags = GPIOF_OUT_INIT_HIGH;
+               else
+                       flags = GPIOF_OUT_INIT_LOW;
+
+               ret = gpio_request_one(pb->enable_gpio, flags, "enable");
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n",
+                               pb->enable_gpio, ret);
+                       goto err_alloc;
+               }
+       }
+
        pb->pwm = devm_pwm_get(&pdev->dev, NULL);
        if (IS_ERR(pb->pwm)) {
                dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
                if (IS_ERR(pb->pwm)) {
                        dev_err(&pdev->dev, "unable to request legacy PWM\n");
                        ret = PTR_ERR(pb->pwm);
-                       goto err_alloc;
+                       goto err_gpio;
                }
        }
 
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                ret = PTR_ERR(bl);
-               goto err_alloc;
+               goto err_gpio;
        }
 
        if (data->dft_brightness > data->max_brightness) {
        platform_set_drvdata(pdev, bl);
        return 0;
 
+err_gpio:
+       if (gpio_is_valid(pb->enable_gpio))
+               gpio_free(pb->enable_gpio);
 err_alloc:
        if (data->exit)
                data->exit(&pdev->dev);