From: Peter Ujfalusi <hidden> Date: 2016-11-01 12:59:47
Hi,
Changes since v2:
- Do not change the way how the GPIO initially configured as input is handled.
Configure it as output and set it's state as active.
Changes since v1:
- Handling of the enable GPIO is reworked:
- Only change direction to output when the pin was input and in this case set
the GPIO line physical low
- With this change we can ensure that the enable GPIO is output so we do not
need to check the direction of it later on.
Cover letter:
3698d7e7d221 backlight: pwm_bl: Avoid backlight flicker when probed from DT
added support for avoiding backlight flickering, which in essence was designed
to not enable the baclkight when the driver loads, but let the user of the
backlight to enable it later on.
There are boards (like am437x-gp-evm) where we do not have valid GPIO to enable
the backlight (TPS61081DRC's EN pin is connected to V3_3D) and the regulator
is always on (VBAT in case of the gp-evm). In this board the logic to check the
GPIO state and the regulator is failing and the backlight will be enabled as
soon as the pwm_bl driver is loaded.
By extending the check to look at the PWM state this issue can be avoided and
the backlight will be enabled only when it's user is asking it to be enabled.
Regards,
Peter
---
Peter Ujfalusi (2):
backlight: pwm_bl: Move the checks for initial power state to a
separate function
backlight: pwm_bl: Check the pwm state for initial backlight power
state
drivers/video/backlight/pwm_bl.c | 57 ++++++++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 19 deletions(-)
--
2.10.2
From: Peter Ujfalusi <hidden> Date: 2016-11-01 12:59:53
If the pwm is not enabled the backlight initially should not be enabled
either if we have booted with DT and there is a phandle pointing to the
backlight node.
The patch extends the checks to decide if we should keep the backlight off
initially.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -215,6 +215,10 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)if(!regulator_is_enabled(pb->power_supply))returnFB_BLANK_POWERDOWN;+/* The pwm is disabled, keep it like this */+if(!pwm_is_enabled(pb->pwm))+returnFB_BLANK_POWERDOWN;+returnFB_BLANK_UNBLANK;}
From: Peter Ujfalusi <hidden> Date: 2016-11-01 12:59:55
Move the checks to select the initial state for the backlight to a new
function and document the checks we are doing.
With the separate function it is going to be easier to fix or improve the
initial power state configuration later and it is easier to read the code.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 53 ++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 19 deletions(-)
@@ -192,6 +192,32 @@ static int pwm_backlight_parse_dt(struct device *dev,}#endif+staticintpwm_backlight_initial_power_state(conststructpwm_bl_data*pb)+{+structdevice_node*node=pb->dev->of_node;++/* Not booted with device tree or no phandle link to the node */+if(!node||!node->phandle)+returnFB_BLANK_UNBLANK;++/*+*Ifthedriverisprobedfromthedevicetreeandthereisa+*phandlelinkpointingtothebacklightnode,itissafeto+*assumethatanotherdriverwillenablethebacklightatthe+*appropriatetime.Therefore,ifitisdisabled,keepitso.+*/++/* if the enable GPIO is disabled, do not enable the backlight */+if(pb->enable_gpio&&gpiod_get_value(pb->enable_gpio)=0)+returnFB_BLANK_POWERDOWN;++/* The regulator is disabled, do not enable the backlight */+if(!regulator_is_enabled(pb->power_supply))+returnFB_BLANK_POWERDOWN;++returnFB_BLANK_UNBLANK;+}+staticintpwm_backlight_probe(structplatform_device*pdev){structplatform_pwm_backlight_data*data=dev_get_platdata(&pdev->dev);
@@ -200,7 +226,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)structbacklight_device*bl;structdevice_node*node=pdev->dev.of_node;structpwm_bl_data*pb;-intinitial_blank=FB_BLANK_UNBLANK;structpwm_argspargs;intret;
@@ -267,20 +292,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)pb->enable_gpio=gpio_to_desc(data->enable_gpio);}-if(pb->enable_gpio){-/*-*Ifthedriverisprobedfromthedevicetreeandthereisa-*phandlelinkpointingtothebacklightnode,itissafeto-*assumethatanotherdriverwillenablethebacklightatthe-*appropriatetime.Therefore,ifitisdisabled,keepitso.-*/-if(node&&node->phandle&&-gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_OUT&&-gpiod_get_value(pb->enable_gpio)=0)-initial_blank=FB_BLANK_POWERDOWN;-else-gpiod_direction_output(pb->enable_gpio,1);-}+/*+*IftheGPIOisconfiguredasinput,changethedirectiontooutput+*andsettheGPIOasactive.+*/+if(pb->enable_gpio&&+gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_IN)+gpiod_direction_output(pb->enable_gpio,1);pb->power_supply=devm_regulator_get(&pdev->dev,"power");if(IS_ERR(pb->power_supply)){
@@ -288,9 +306,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)gotoerr_alloc;}-if(node&&node->phandle&&!regulator_is_enabled(pb->power_supply))-initial_blank=FB_BLANK_POWERDOWN;-pb->pwm=devm_pwm_get(&pdev->dev,NULL);if(IS_ERR(pb->pwm)&&PTR_ERR(pb->pwm)!=-EPROBE_DEFER&&!node){dev_err(&pdev->dev,"unable to request PWM, trying legacy API\n");
@@ -347,7 +362,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)}bl->props.brightness=data->dft_brightness;-bl->props.power=initial_blank;+bl->props.power=pwm_backlight_initial_power_state(pb);backlight_update_status(bl);platform_set_drvdata(pdev,bl);
From: Philipp Zabel <p.zabel@pengutronix.de> Date: 2016-11-01 13:10:38
Am Dienstag, den 01.11.2016, 14:59 +0200 schrieb Peter Ujfalusi:
Move the checks to select the initial state for the backlight to a new
function and document the checks we are doing.
With the separate function it is going to be easier to fix or improve the
initial power state configuration later and it is easier to read the code.
Signed-off-by: Peter Ujfalusi <redacted>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
@@ -192,6 +192,32 @@ static int pwm_backlight_parse_dt(struct device *dev,}#endif+staticintpwm_backlight_initial_power_state(conststructpwm_bl_data*pb)+{+structdevice_node*node=pb->dev->of_node;++/* Not booted with device tree or no phandle link to the node */+if(!node||!node->phandle)+returnFB_BLANK_UNBLANK;++/*+*Ifthedriverisprobedfromthedevicetreeandthereisa+*phandlelinkpointingtothebacklightnode,itissafeto+*assumethatanotherdriverwillenablethebacklightatthe+*appropriatetime.Therefore,ifitisdisabled,keepitso.+*/++/* if the enable GPIO is disabled, do not enable the backlight */+if(pb->enable_gpio&&gpiod_get_value(pb->enable_gpio)=0)+returnFB_BLANK_POWERDOWN;++/* The regulator is disabled, do not enable the backlight */+if(!regulator_is_enabled(pb->power_supply))+returnFB_BLANK_POWERDOWN;++returnFB_BLANK_UNBLANK;+}+staticintpwm_backlight_probe(structplatform_device*pdev){structplatform_pwm_backlight_data*data=dev_get_platdata(&pdev->dev);
@@ -200,7 +226,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)structbacklight_device*bl;structdevice_node*node=pdev->dev.of_node;structpwm_bl_data*pb;-intinitial_blank=FB_BLANK_UNBLANK;structpwm_argspargs;intret;
@@ -267,20 +292,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)pb->enable_gpio=gpio_to_desc(data->enable_gpio);}-if(pb->enable_gpio){-/*-*Ifthedriverisprobedfromthedevicetreeandthereisa-*phandlelinkpointingtothebacklightnode,itissafeto-*assumethatanotherdriverwillenablethebacklightatthe-*appropriatetime.Therefore,ifitisdisabled,keepitso.-*/-if(node&&node->phandle&&-gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_OUT&&-gpiod_get_value(pb->enable_gpio)=0)-initial_blank=FB_BLANK_POWERDOWN;-else-gpiod_direction_output(pb->enable_gpio,1);-}+/*+*IftheGPIOisconfiguredasinput,changethedirectiontooutput+*andsettheGPIOasactive.+*/+if(pb->enable_gpio&&+gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_IN)+gpiod_direction_output(pb->enable_gpio,1);pb->power_supply=devm_regulator_get(&pdev->dev,"power");if(IS_ERR(pb->power_supply)){
@@ -288,9 +306,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)gotoerr_alloc;}-if(node&&node->phandle&&!regulator_is_enabled(pb->power_supply))-initial_blank=FB_BLANK_POWERDOWN;-pb->pwm=devm_pwm_get(&pdev->dev,NULL);if(IS_ERR(pb->pwm)&&PTR_ERR(pb->pwm)!=-EPROBE_DEFER&&!node){dev_err(&pdev->dev,"unable to request PWM, trying legacy API\n");
@@ -347,7 +362,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)}bl->props.brightness=data->dft_brightness;-bl->props.power=initial_blank;+bl->props.power=pwm_backlight_initial_power_state(pb);backlight_update_status(bl);platform_set_drvdata(pdev,bl);
From: Philipp Zabel <p.zabel@pengutronix.de> Date: 2016-11-01 13:11:12
Am Dienstag, den 01.11.2016, 14:59 +0200 schrieb Peter Ujfalusi:
If the pwm is not enabled the backlight initially should not be enabled
either if we have booted with DT and there is a phandle pointing to the
backlight node.
The patch extends the checks to decide if we should keep the backlight off
initially.
Signed-off-by: Peter Ujfalusi <redacted>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
From: Lee Jones <hidden> Date: 2016-11-18 14:46:38
Thierry, Jingoo,
Please have your say.
quoted hunk
Move the checks to select the initial state for the backlight to a new
function and document the checks we are doing.
With the separate function it is going to be easier to fix or improve the
initial power state configuration later and it is easier to read the code.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 53 ++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 19 deletions(-)
@@ -192,6 +192,32 @@ static int pwm_backlight_parse_dt(struct device *dev,}#endif+staticintpwm_backlight_initial_power_state(conststructpwm_bl_data*pb)+{+structdevice_node*node=pb->dev->of_node;++/* Not booted with device tree or no phandle link to the node */+if(!node||!node->phandle)+returnFB_BLANK_UNBLANK;++/*+*Ifthedriverisprobedfromthedevicetreeandthereisa+*phandlelinkpointingtothebacklightnode,itissafeto+*assumethatanotherdriverwillenablethebacklightatthe+*appropriatetime.Therefore,ifitisdisabled,keepitso.+*/++/* if the enable GPIO is disabled, do not enable the backlight */+if(pb->enable_gpio&&gpiod_get_value(pb->enable_gpio)=0)+returnFB_BLANK_POWERDOWN;++/* The regulator is disabled, do not enable the backlight */+if(!regulator_is_enabled(pb->power_supply))+returnFB_BLANK_POWERDOWN;++returnFB_BLANK_UNBLANK;+}+staticintpwm_backlight_probe(structplatform_device*pdev){structplatform_pwm_backlight_data*data=dev_get_platdata(&pdev->dev);
@@ -200,7 +226,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)structbacklight_device*bl;structdevice_node*node=pdev->dev.of_node;structpwm_bl_data*pb;-intinitial_blank=FB_BLANK_UNBLANK;structpwm_argspargs;intret;
@@ -267,20 +292,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)pb->enable_gpio=gpio_to_desc(data->enable_gpio);}-if(pb->enable_gpio){-/*-*Ifthedriverisprobedfromthedevicetreeandthereisa-*phandlelinkpointingtothebacklightnode,itissafeto-*assumethatanotherdriverwillenablethebacklightatthe-*appropriatetime.Therefore,ifitisdisabled,keepitso.-*/-if(node&&node->phandle&&-gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_OUT&&-gpiod_get_value(pb->enable_gpio)=0)-initial_blank=FB_BLANK_POWERDOWN;-else-gpiod_direction_output(pb->enable_gpio,1);-}+/*+*IftheGPIOisconfiguredasinput,changethedirectiontooutput+*andsettheGPIOasactive.+*/+if(pb->enable_gpio&&+gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_IN)+gpiod_direction_output(pb->enable_gpio,1);pb->power_supply=devm_regulator_get(&pdev->dev,"power");if(IS_ERR(pb->power_supply)){
@@ -288,9 +306,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)gotoerr_alloc;}-if(node&&node->phandle&&!regulator_is_enabled(pb->power_supply))-initial_blank=FB_BLANK_POWERDOWN;-pb->pwm=devm_pwm_get(&pdev->dev,NULL);if(IS_ERR(pb->pwm)&&PTR_ERR(pb->pwm)!=-EPROBE_DEFER&&!node){dev_err(&pdev->dev,"unable to request PWM, trying legacy API\n");
@@ -347,7 +362,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)}bl->props.brightness=data->dft_brightness;-bl->props.power=initial_blank;+bl->props.power=pwm_backlight_initial_power_state(pb);backlight_update_status(bl);platform_set_drvdata(pdev,bl);
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On Tue, Nov 01, 2016 at 02:59:32PM +0200, Peter Ujfalusi wrote:
quoted hunk
Move the checks to select the initial state for the backlight to a new
function and document the checks we are doing.
With the separate function it is going to be easier to fix or improve the
initial power state configuration later and it is easier to read the code.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 53 ++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 19 deletions(-)
@@ -192,6 +192,32 @@ static int pwm_backlight_parse_dt(struct device *dev,}#endif+staticintpwm_backlight_initial_power_state(conststructpwm_bl_data*pb)+{+structdevice_node*node=pb->dev->of_node;++/* Not booted with device tree or no phandle link to the node */+if(!node||!node->phandle)+returnFB_BLANK_UNBLANK;++/*+*Ifthedriverisprobedfromthedevicetreeandthereisa+*phandlelinkpointingtothebacklightnode,itissafeto+*assumethatanotherdriverwillenablethebacklightatthe+*appropriatetime.Therefore,ifitisdisabled,keepitso.+*/++/* if the enable GPIO is disabled, do not enable the backlight */+if(pb->enable_gpio&&gpiod_get_value(pb->enable_gpio)==0)+returnFB_BLANK_POWERDOWN;++/* The regulator is disabled, do not enable the backlight */+if(!regulator_is_enabled(pb->power_supply))+returnFB_BLANK_POWERDOWN;++returnFB_BLANK_UNBLANK;+}+staticintpwm_backlight_probe(structplatform_device*pdev){structplatform_pwm_backlight_data*data=dev_get_platdata(&pdev->dev);
@@ -200,7 +226,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)structbacklight_device*bl;structdevice_node*node=pdev->dev.of_node;structpwm_bl_data*pb;-intinitial_blank=FB_BLANK_UNBLANK;structpwm_argspargs;intret;
@@ -267,20 +292,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)pb->enable_gpio=gpio_to_desc(data->enable_gpio);}-if(pb->enable_gpio){-/*-*Ifthedriverisprobedfromthedevicetreeandthereisa-*phandlelinkpointingtothebacklightnode,itissafeto-*assumethatanotherdriverwillenablethebacklightatthe-*appropriatetime.Therefore,ifitisdisabled,keepitso.-*/-if(node&&node->phandle&&-gpiod_get_direction(pb->enable_gpio)==GPIOF_DIR_OUT&&-gpiod_get_value(pb->enable_gpio)==0)-initial_blank=FB_BLANK_POWERDOWN;-else-gpiod_direction_output(pb->enable_gpio,1);-}+/*+*IftheGPIOisconfiguredasinput,changethedirectiontooutput+*andsettheGPIOasactive.+*/+if(pb->enable_gpio&&+gpiod_get_direction(pb->enable_gpio)==GPIOF_DIR_IN)+gpiod_direction_output(pb->enable_gpio,1);
I'm confused about this. Isn't it redundant to check for the direction
if you're going to configure it as output either way? Why not just set
it as output unconditionally?
Also, is this not counterproductive? pwm_backlight_initial_power_state()
will check the value of the GPIO to determine whether or not to mark the
backlight as enabled. If we're setting this to active, then the check in
the initial state retrieval will only be false if the GPIO is an output
and inactive.
Oh wait... I guess that's exactly why you're doing this. =) Perhaps this
could be made somewhat clearer by beefing up the comment. As it is, the
comment /seems/ rather useless because it restates what the code does. I
think it'd be better to explain more verbosely what's going on, to avoid
confusing people like me.
Either way, though, the patch looks correct now that I understand it
properly, I'll leave it up to Lee if he wants to insist on a clarifying
comment.
Reviewed-by: Thierry Reding <redacted>
On Tue, Nov 01, 2016 at 02:59:33PM +0200, Peter Ujfalusi wrote:
quoted hunk
If the pwm is not enabled the backlight initially should not be enabled
either if we have booted with DT and there is a phandle pointing to the
backlight node.
The patch extends the checks to decide if we should keep the backlight off
initially.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -215,6 +215,10 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)if(!regulator_is_enabled(pb->power_supply))returnFB_BLANK_POWERDOWN;+/* The pwm is disabled, keep it like this */+if(!pwm_is_enabled(pb->pwm))+returnFB_BLANK_POWERDOWN;+returnFB_BLANK_UNBLANK;}
I prefer "PWM" instead of "pwm" in prose (comments and commit message)
because it's an abbreviation.
Otherwise this looks correct:
Reviewed-by: Thierry Reding <redacted>
From: Peter Ujfalusi <hidden> Date: 2016-11-22 13:33:19
On 11/21/2016 10:10 AM, Thierry Reding wrote:
On Tue, Nov 01, 2016 at 02:59:32PM +0200, Peter Ujfalusi wrote:
quoted
Move the checks to select the initial state for the backlight to a new
function and document the checks we are doing.
With the separate function it is going to be easier to fix or improve the
initial power state configuration later and it is easier to read the code.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/video/backlight/pwm_bl.c | 53 ++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 19 deletions(-)
@@ -192,6 +192,32 @@ static int pwm_backlight_parse_dt(struct device *dev,}#endif+staticintpwm_backlight_initial_power_state(conststructpwm_bl_data*pb)+{+structdevice_node*node=pb->dev->of_node;++/* Not booted with device tree or no phandle link to the node */+if(!node||!node->phandle)+returnFB_BLANK_UNBLANK;++/*+*Ifthedriverisprobedfromthedevicetreeandthereisa+*phandlelinkpointingtothebacklightnode,itissafeto+*assumethatanotherdriverwillenablethebacklightatthe+*appropriatetime.Therefore,ifitisdisabled,keepitso.+*/++/* if the enable GPIO is disabled, do not enable the backlight */+if(pb->enable_gpio&&gpiod_get_value(pb->enable_gpio)=0)+returnFB_BLANK_POWERDOWN;++/* The regulator is disabled, do not enable the backlight */+if(!regulator_is_enabled(pb->power_supply))+returnFB_BLANK_POWERDOWN;++returnFB_BLANK_UNBLANK;+}+staticintpwm_backlight_probe(structplatform_device*pdev){structplatform_pwm_backlight_data*data=dev_get_platdata(&pdev->dev);
@@ -200,7 +226,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)structbacklight_device*bl;structdevice_node*node=pdev->dev.of_node;structpwm_bl_data*pb;-intinitial_blank=FB_BLANK_UNBLANK;structpwm_argspargs;intret;
@@ -267,20 +292,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)pb->enable_gpio=gpio_to_desc(data->enable_gpio);}-if(pb->enable_gpio){-/*-*Ifthedriverisprobedfromthedevicetreeandthereisa-*phandlelinkpointingtothebacklightnode,itissafeto-*assumethatanotherdriverwillenablethebacklightatthe-*appropriatetime.Therefore,ifitisdisabled,keepitso.-*/-if(node&&node->phandle&&-gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_OUT&&-gpiod_get_value(pb->enable_gpio)=0)-initial_blank=FB_BLANK_POWERDOWN;-else-gpiod_direction_output(pb->enable_gpio,1);-}+/*+*IftheGPIOisconfiguredasinput,changethedirectiontooutput+*andsettheGPIOasactive.+*/+if(pb->enable_gpio&&+gpiod_get_direction(pb->enable_gpio)=GPIOF_DIR_IN)+gpiod_direction_output(pb->enable_gpio,1);
I'm confused about this. Isn't it redundant to check for the direction
if you're going to configure it as output either way? Why not just set
it as output unconditionally?
Also, is this not counterproductive? pwm_backlight_initial_power_state()
will check the value of the GPIO to determine whether or not to mark the
backlight as enabled. If we're setting this to active, then the check in
the initial state retrieval will only be false if the GPIO is an output
and inactive.
Oh wait... I guess that's exactly why you're doing this. =) Perhaps this
could be made somewhat clearer by beefing up the comment. As it is, the
comment /seems/ rather useless because it restates what the code does. I
think it'd be better to explain more verbosely what's going on, to avoid
confusing people like me.
Extending the commit to:
/*
* If the GPIO is configured as input, 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.
*/
Either way, though, the patch looks correct now that I understand it
properly, I'll leave it up to Lee if he wants to insist on a clarifying
comment.
Reviewed-by: Thierry Reding <redacted>