Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / drivers / video / backlight / pwm_bl.c
index e48fded..8d8959a 100644 (file)
@@ -409,6 +409,33 @@ static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data)
 static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
 {
        struct device_node *node = pb->dev->of_node;
+       bool active = true;
+
+       /*
+        * If the enable GPIO is present, observable (either as input
+        * or output) and off then the backlight is not currently active.
+        * */
+       if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
+               active = false;
+
+       if (!regulator_is_enabled(pb->power_supply))
+               active = false;
+
+       if (!pwm_is_enabled(pb->pwm))
+               active = false;
+
+       /*
+        * Synchronize the enable_gpio with the observed state of the
+        * hardware.
+        */
+       if (pb->enable_gpio)
+               gpiod_direction_output(pb->enable_gpio, active);
+
+       /*
+        * Do not change pb->enabled here! pb->enabled essentially
+        * tells us if we own one of the regulator's use counts and
+        * right now we do not.
+        */
 
        /* Not booted with device tree or no phandle link to the node */
        if (!node || !node->phandle)
@@ -420,20 +447,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
         * assume that another driver will enable the backlight at the
         * appropriate time. Therefore, if it is disabled, keep it so.
         */
-
-       /* if the enable GPIO is disabled, do not enable the backlight */
-       if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
-               return FB_BLANK_POWERDOWN;
-
-       /* The regulator is disabled, do not enable the backlight */
-       if (!regulator_is_enabled(pb->power_supply))
-               return FB_BLANK_POWERDOWN;
-
-       /* The PWM is disabled, keep it like this */
-       if (!pwm_is_enabled(pb->pwm))
-               return FB_BLANK_POWERDOWN;
-
-       return FB_BLANK_UNBLANK;
+       return active ? FB_BLANK_UNBLANK: FB_BLANK_POWERDOWN;
 }
 
 static int pwm_backlight_probe(struct platform_device *pdev)
@@ -486,18 +500,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
                goto err_alloc;
        }
 
-       /*
-        * If the GPIO is not known to be already configured as output, that
-        * is, if gpiod_get_direction returns either 1 or -EINVAL, change the
-        * direction to output and set the GPIO as active.
-        * Do not force the GPIO to active when it was already output as it
-        * could cause backlight flickering or we would enable the backlight too
-        * early. Leave the decision of the initial backlight state for later.
-        */
-       if (pb->enable_gpio &&
-           gpiod_get_direction(pb->enable_gpio) != 0)
-               gpiod_direction_output(pb->enable_gpio, 1);
-
        pb->power_supply = devm_regulator_get(&pdev->dev, "power");
        if (IS_ERR(pb->power_supply)) {
                ret = PTR_ERR(pb->power_supply);