Skip to content

Commit 5866b11

Browse files
Daniel Thompsongregkh
authored andcommitted
backlight: pwm_bl: Improve bootloader/kernel device handover
commit 79fad92 upstream. Currently there are (at least) two problems in the way pwm_bl starts managing the enable_gpio pin. Both occur when the backlight is initially off and the driver finds the pin not already in output mode and, as a result, unconditionally switches it to output-mode and asserts the signal. Problem 1: This could cause the backlight to flicker since, at this stage in driver initialisation, we have no idea what the PWM and regulator are doing (an unconfigured PWM could easily "rest" at 100% duty cycle). Problem 2: This will cause us not to correctly honour the post_pwm_on_delay (which also risks flickers). Fix this by moving the code to configure the GPIO output mode until after we have examines the handover state. That allows us to initialize enable_gpio to off if the backlight is currently off and on if the backlight is on. Cc: [email protected] Reported-by: Marek Vasut <[email protected]> Signed-off-by: Daniel Thompson <[email protected]> Acked-by: Marek Vasut <[email protected]> Tested-by: Marek Vasut <[email protected]> Signed-off-by: Lee Jones <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4c00435 commit 5866b11

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

drivers/video/backlight/pwm_bl.c

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,33 @@ static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data)
417417
static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
418418
{
419419
struct device_node *node = pb->dev->of_node;
420+
bool active = true;
421+
422+
/*
423+
* If the enable GPIO is present, observable (either as input
424+
* or output) and off then the backlight is not currently active.
425+
* */
426+
if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
427+
active = false;
428+
429+
if (!regulator_is_enabled(pb->power_supply))
430+
active = false;
431+
432+
if (!pwm_is_enabled(pb->pwm))
433+
active = false;
434+
435+
/*
436+
* Synchronize the enable_gpio with the observed state of the
437+
* hardware.
438+
*/
439+
if (pb->enable_gpio)
440+
gpiod_direction_output(pb->enable_gpio, active);
441+
442+
/*
443+
* Do not change pb->enabled here! pb->enabled essentially
444+
* tells us if we own one of the regulator's use counts and
445+
* right now we do not.
446+
*/
420447

421448
/* Not booted with device tree or no phandle link to the node */
422449
if (!node || !node->phandle)
@@ -428,20 +455,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
428455
* assume that another driver will enable the backlight at the
429456
* appropriate time. Therefore, if it is disabled, keep it so.
430457
*/
431-
432-
/* if the enable GPIO is disabled, do not enable the backlight */
433-
if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
434-
return FB_BLANK_POWERDOWN;
435-
436-
/* The regulator is disabled, do not enable the backlight */
437-
if (!regulator_is_enabled(pb->power_supply))
438-
return FB_BLANK_POWERDOWN;
439-
440-
/* The PWM is disabled, keep it like this */
441-
if (!pwm_is_enabled(pb->pwm))
442-
return FB_BLANK_POWERDOWN;
443-
444-
return FB_BLANK_UNBLANK;
458+
return active ? FB_BLANK_UNBLANK: FB_BLANK_POWERDOWN;
445459
}
446460

447461
static int pwm_backlight_probe(struct platform_device *pdev)
@@ -494,18 +508,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
494508
goto err_alloc;
495509
}
496510

497-
/*
498-
* If the GPIO is not known to be already configured as output, that
499-
* is, if gpiod_get_direction returns either 1 or -EINVAL, change the
500-
* direction to output and set the GPIO as active.
501-
* Do not force the GPIO to active when it was already output as it
502-
* could cause backlight flickering or we would enable the backlight too
503-
* early. Leave the decision of the initial backlight state for later.
504-
*/
505-
if (pb->enable_gpio &&
506-
gpiod_get_direction(pb->enable_gpio) != 0)
507-
gpiod_direction_output(pb->enable_gpio, 1);
508-
509511
pb->power_supply = devm_regulator_get(&pdev->dev, "power");
510512
if (IS_ERR(pb->power_supply)) {
511513
ret = PTR_ERR(pb->power_supply);

0 commit comments

Comments
 (0)