Skip to content

Commit deaeeda

Browse files
Uwe Kleine-Königlag-linaro
authored andcommitted
backlight: pwm_bl: Don't rely on a disabled PWM emiting inactive state
Most but not all PWMs drive the PWM pin to its inactive state when disabled. However if there is no enable_gpio and no regulator the PWM must drive the inactive state to actually disable the backlight. So keep the PWM on in this case. Note that to determine if there is a regulator some effort is required because it might happen that there isn't actually one but the regulator core gave us a dummy. (A nice side effect is that this makes the regulator actually optional even on fully constrained systems.) This fixes backlight disabling e.g. on i.MX6 when an inverted PWM is used. Hint for the future: If this change results in a regression, the bug is in the lowlevel PWM driver. Signed-off-by: Uwe Kleine-König <[email protected]> Reviewed-by: Daniel Thompson <[email protected]> Signed-off-by: Lee Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 00e7e69 commit deaeeda

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

drivers/video/backlight/pwm_bl.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb)
4545
if (pb->enabled)
4646
return;
4747

48-
err = regulator_enable(pb->power_supply);
49-
if (err < 0)
50-
dev_err(pb->dev, "failed to enable power supply\n");
48+
if (pb->power_supply) {
49+
err = regulator_enable(pb->power_supply);
50+
if (err < 0)
51+
dev_err(pb->dev, "failed to enable power supply\n");
52+
}
5153

5254
if (pb->post_pwm_on_delay)
5355
msleep(pb->post_pwm_on_delay);
@@ -69,7 +71,8 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
6971
if (pb->pwm_off_delay)
7072
msleep(pb->pwm_off_delay);
7173

72-
regulator_disable(pb->power_supply);
74+
if (pb->power_supply)
75+
regulator_disable(pb->power_supply);
7376
pb->enabled = false;
7477
}
7578

@@ -109,8 +112,16 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
109112
pwm_backlight_power_off(pb);
110113

111114
pwm_get_state(pb->pwm, &state);
112-
state.enabled = false;
113115
state.duty_cycle = 0;
116+
/*
117+
* We cannot assume a disabled PWM to drive its output to the
118+
* inactive state. If we have an enable GPIO and/or a regulator
119+
* we assume that this isn't relevant and we can disable the PWM
120+
* to save power. If however there is neither an enable GPIO nor
121+
* a regulator keep the PWM on be sure to get a constant
122+
* inactive output.
123+
*/
124+
state.enabled = !pb->power_supply && !pb->enable_gpio;
114125
pwm_apply_state(pb->pwm, &state);
115126
}
116127

@@ -408,7 +419,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
408419
if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
409420
active = false;
410421

411-
if (!regulator_is_enabled(pb->power_supply))
422+
if (pb->power_supply && !regulator_is_enabled(pb->power_supply))
412423
active = false;
413424

414425
if (!pwm_is_enabled(pb->pwm))
@@ -489,10 +500,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)
489500
goto err_alloc;
490501
}
491502

492-
pb->power_supply = devm_regulator_get(&pdev->dev, "power");
503+
pb->power_supply = devm_regulator_get_optional(&pdev->dev, "power");
493504
if (IS_ERR(pb->power_supply)) {
494505
ret = PTR_ERR(pb->power_supply);
495-
goto err_alloc;
506+
if (ret == -ENODEV)
507+
pb->power_supply = NULL;
508+
else
509+
goto err_alloc;
496510
}
497511

498512
pb->pwm = devm_pwm_get(&pdev->dev, NULL);

0 commit comments

Comments
 (0)