Skip to content

Commit b79b608

Browse files
committed
drm/tegra: sor: Fix AUX device reference leak
In the case where the AUX provides an I2C-over-AUX DDC channel, a reference is taken on the AUX parent device of the DDC channel rather than the DDC channel like it would be for regular I2C controllers. To make sure the correct reference is dropped, move the unreferencing code into the SOR driver and make sure not to drop the I2C adapter reference in that case. Signed-off-by: Thierry Reding <[email protected]>
1 parent 1d15a10 commit b79b608

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

drivers/gpu/drm/tegra/output.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,10 @@ int tegra_output_probe(struct tegra_output *output)
180180

181181
void tegra_output_remove(struct tegra_output *output)
182182
{
183-
int connector_type = output->connector.connector_type;
184-
185183
if (output->hpd_gpio)
186184
free_irq(output->hpd_irq, output);
187185

188-
if (connector_type != DRM_MODE_CONNECTOR_eDP &&
189-
connector_type != DRM_MODE_CONNECTOR_DisplayPort && output->ddc)
186+
if (output->ddc)
190187
i2c_put_adapter(output->ddc);
191188
}
192189

drivers/gpu/drm/tegra/sor.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,12 +3745,8 @@ static int tegra_sor_probe(struct platform_device *pdev)
37453745
if (!sor->aux)
37463746
return -EPROBE_DEFER;
37473747

3748-
if (get_device(sor->aux->dev)) {
3749-
if (try_module_get(sor->aux->dev->driver->owner))
3750-
sor->output.ddc = &sor->aux->ddc;
3751-
else
3752-
put_device(sor->aux->dev);
3753-
}
3748+
if (get_device(sor->aux->dev))
3749+
sor->output.ddc = &sor->aux->ddc;
37543750
}
37553751

37563752
if (!sor->aux) {
@@ -3778,12 +3774,13 @@ static int tegra_sor_probe(struct platform_device *pdev)
37783774

37793775
err = tegra_sor_parse_dt(sor);
37803776
if (err < 0)
3781-
return err;
3777+
goto put_aux;
37823778

37833779
err = tegra_output_probe(&sor->output);
3784-
if (err < 0)
3785-
return dev_err_probe(&pdev->dev, err,
3786-
"failed to probe output\n");
3780+
if (err < 0) {
3781+
dev_err_probe(&pdev->dev, err, "failed to probe output\n");
3782+
goto put_aux;
3783+
}
37873784

37883785
if (sor->ops && sor->ops->probe) {
37893786
err = sor->ops->probe(sor);
@@ -3970,7 +3967,14 @@ static int tegra_sor_probe(struct platform_device *pdev)
39703967
host1x_client_exit(&sor->client);
39713968
pm_runtime_disable(&pdev->dev);
39723969
remove:
3970+
if (sor->aux)
3971+
sor->output.ddc = NULL;
3972+
39733973
tegra_output_remove(&sor->output);
3974+
put_aux:
3975+
if (sor->aux)
3976+
put_device(sor->aux->dev);
3977+
39743978
return err;
39753979
}
39763980

@@ -3988,6 +3992,11 @@ static int tegra_sor_remove(struct platform_device *pdev)
39883992

39893993
pm_runtime_disable(&pdev->dev);
39903994

3995+
if (sor->aux) {
3996+
put_device(sor->aux->dev);
3997+
sor->output.ddc = NULL;
3998+
}
3999+
39914000
tegra_output_remove(&sor->output);
39924001

39934002
return 0;

0 commit comments

Comments
 (0)