diff mbox series

drm/tegra: Fix regulator_get_optional() misuse

Message ID 20191105125943.34729-1-broonie@kernel.org (mailing list archive)
State New, archived
Headers show
Series drm/tegra: Fix regulator_get_optional() misuse | expand

Commit Message

Mark Brown Nov. 5, 2019, 12:59 p.m. UTC
The tegra driver requests a supply using regulator_get_optional()
but both the name of the supply and the usage pattern suggest that it is
being used for the main power for the device and is not at all optional
for the device for function, there is no meaningful handling for absent
supplies.  Such regulators should use the vanilla regulator_get()
interface, it will ensure that even if a supply is not described in the
system integration one will be provided in software.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/gpu/drm/tegra/dpaux.c | 32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

Comments

Thierry Reding Nov. 5, 2019, 1:15 p.m. UTC | #1
On Tue, Nov 05, 2019 at 12:59:42PM +0000, Mark Brown wrote:
> The tegra driver requests a supply using regulator_get_optional()
> but both the name of the supply and the usage pattern suggest that it is
> being used for the main power for the device and is not at all optional
> for the device for function, there is no meaningful handling for absent
> supplies.  Such regulators should use the vanilla regulator_get()
> interface, it will ensure that even if a supply is not described in the
> system integration one will be provided in software.
> 
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  drivers/gpu/drm/tegra/dpaux.c | 32 ++++++++++++--------------------
>  1 file changed, 12 insertions(+), 20 deletions(-)

It is in fact optional in this case. This code remains solely for
backwards compatibility with old DTBs because back at the time the VDD
supply was associated with the DPAUX block where it should've really
been associated with the eDP panel.

See also this commit for some background:

commit f3b0d8793c1619074d0ece2e1a7f64ea37eaf394
Author: Thierry Reding <treding@nvidia.com>
Date:   Wed Jun 5 10:48:01 2019 +0200

    drm/tegra: dpaux: Make VDD supply optional

    The VDD supply is only needed to supply power to eDP panels connected to
    DPAUX. Technically that supply should be dealt with in the panel driver,
    but for backwards-compatibility we need to keep this around anyway.

    Also as a bit of background: the reason for why this supply is attached
    to DPAUX is to make sure the panel is properly powered early on so that
    it can generate a hotplug pulse at the appropriate time. This may no
    longer be required given the support for deferred fbdev setup that was
    "recently" introduced in DRM/KMS.

    Signed-off-by: Thierry Reding <treding@nvidia.com>

Thierry
Mark Brown Nov. 5, 2019, 1:24 p.m. UTC | #2
On Tue, Nov 05, 2019 at 02:15:11PM +0100, Thierry Reding wrote:

> It is in fact optional in this case. This code remains solely for
> backwards compatibility with old DTBs because back at the time the VDD
> supply was associated with the DPAUX block where it should've really
> been associated with the eDP panel.

That should really have some documentation, and in any case would be
better implemented by using the supply_alias feature to remap the supply
to the panel device so that we're using the same code path when actually
managing the regulator either way.
diff mbox series

Patch

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 622cdf1ad246..38686f56ea2f 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -505,18 +505,14 @@  static int tegra_dpaux_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
+	dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd");
 	if (IS_ERR(dpaux->vdd)) {
-		if (PTR_ERR(dpaux->vdd) != -ENODEV) {
-			if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
-				dev_err(&pdev->dev,
-					"failed to get VDD supply: %ld\n",
-					PTR_ERR(dpaux->vdd));
-
-			return PTR_ERR(dpaux->vdd);
-		}
+		if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"failed to get VDD supply: %ld\n",
+				PTR_ERR(dpaux->vdd));
 
-		dpaux->vdd = NULL;
+		return PTR_ERR(dpaux->vdd);
 	}
 
 	platform_set_drvdata(pdev, dpaux);
@@ -731,11 +727,9 @@  int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
 	if (output->panel) {
 		enum drm_connector_status status;
 
-		if (dpaux->vdd) {
-			err = regulator_enable(dpaux->vdd);
-			if (err < 0)
-				return err;
-		}
+		err = regulator_enable(dpaux->vdd);
+		if (err < 0)
+			return err;
 
 		timeout = jiffies + msecs_to_jiffies(250);
 
@@ -767,11 +761,9 @@  int drm_dp_aux_detach(struct drm_dp_aux *aux)
 	if (dpaux->output->panel) {
 		enum drm_connector_status status;
 
-		if (dpaux->vdd) {
-			err = regulator_disable(dpaux->vdd);
-			if (err < 0)
-				return err;
-		}
+		err = regulator_disable(dpaux->vdd);
+		if (err < 0)
+			return err;
 
 		timeout = jiffies + msecs_to_jiffies(250);