Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

backlight: pwm_bl: Configure pwm only once per backlight toggle

When the function pwm_backlight_update_status() was called with
brightness > 0, pwm_get_state() was called twice (once directly and once
in compute_duty_cycle). Also pwm_apply_state() was called twice (once in
pwm_backlight_power_on() and once directly).

Optimize this to do both calls only once.

Note that with this affects the order of regulator and PWM setup. It's
not expected to have a relevant effect on hardware. The rationale for
this is that the regulator (and the GPIO) are reasonable to switch in
pwm_backlight_power_on()/pwm_backlight_power_off() but the PWM has
nothing to do with power. (The post_pwm_on_delay and pwm_off_delay are
still there though.)

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230120120018.161103-2-u.kleine-koenig@pengutronix.de

authored by

Uwe Kleine-König and committed by
Lee Jones
00e7e698 744fc2da

+10 -18
+10 -18
drivers/video/backlight/pwm_bl.c
··· 40 40 41 41 static void pwm_backlight_power_on(struct pwm_bl_data *pb) 42 42 { 43 - struct pwm_state state; 44 43 int err; 45 44 46 - pwm_get_state(pb->pwm, &state); 47 45 if (pb->enabled) 48 46 return; 49 47 50 48 err = regulator_enable(pb->power_supply); 51 49 if (err < 0) 52 50 dev_err(pb->dev, "failed to enable power supply\n"); 53 - 54 - state.enabled = true; 55 - pwm_apply_state(pb->pwm, &state); 56 51 57 52 if (pb->post_pwm_on_delay) 58 53 msleep(pb->post_pwm_on_delay); ··· 60 65 61 66 static void pwm_backlight_power_off(struct pwm_bl_data *pb) 62 67 { 63 - struct pwm_state state; 64 - 65 - pwm_get_state(pb->pwm, &state); 66 68 if (!pb->enabled) 67 69 return; 68 70 ··· 69 77 if (pb->pwm_off_delay) 70 78 msleep(pb->pwm_off_delay); 71 79 72 - state.enabled = false; 73 - state.duty_cycle = 0; 74 - pwm_apply_state(pb->pwm, &state); 75 - 76 80 regulator_disable(pb->power_supply); 77 81 pb->enabled = false; 78 82 } 79 83 80 - static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) 84 + static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness, struct pwm_state *state) 81 85 { 82 86 unsigned int lth = pb->lth_brightness; 83 - struct pwm_state state; 84 87 u64 duty_cycle; 85 - 86 - pwm_get_state(pb->pwm, &state); 87 88 88 89 if (pb->levels) 89 90 duty_cycle = pb->levels[brightness]; 90 91 else 91 92 duty_cycle = brightness; 92 93 93 - duty_cycle *= state.period - lth; 94 + duty_cycle *= state->period - lth; 94 95 do_div(duty_cycle, pb->scale); 95 96 96 97 return duty_cycle + lth; ··· 100 115 101 116 if (brightness > 0) { 102 117 pwm_get_state(pb->pwm, &state); 103 - state.duty_cycle = compute_duty_cycle(pb, brightness); 118 + state.duty_cycle = compute_duty_cycle(pb, brightness, &state); 119 + state.enabled = true; 104 120 pwm_apply_state(pb->pwm, &state); 121 + 105 122 pwm_backlight_power_on(pb); 106 123 } else { 107 124 pwm_backlight_power_off(pb); 125 + 126 + pwm_get_state(pb->pwm, &state); 127 + state.enabled = false; 128 + state.duty_cycle = 0; 129 + pwm_apply_state(pb->pwm, &state); 108 130 } 109 131 110 132 if (pb->notify_after)