On 02/25/2016 03:34 AM, Thierry Reding wrote: > From: Thierry Reding <treding@xxxxxxxxxx> > > The error cleanup paths aren't quite correct and will crash upon > deferred probe. > > Cc: stable@xxxxxxxxxxxxxxx # v4.3+ > Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> Reviewed-by: Ben Skeggs <bskeggs@xxxxxxxxxx> > --- > drivers/gpu/drm/nouveau/nouveau_platform.c | 2 +- > drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 40 ++++++++++++++++------ > 2 files changed, 30 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c > index 8a70cec59bcd..2dfe58af12e4 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_platform.c > +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c > @@ -24,7 +24,7 @@ > static int nouveau_platform_probe(struct platform_device *pdev) > { > const struct nvkm_device_tegra_func *func; > - struct nvkm_device *device; > + struct nvkm_device *device = NULL; > struct drm_device *drm; > int ret; > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > index 7f8a42721eb2..e7e581d6a8ff 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > @@ -252,32 +252,40 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, > > if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) > return -ENOMEM; > - *pdevice = &tdev->device; > + > tdev->func = func; > tdev->pdev = pdev; > tdev->irq = -1; > > tdev->vdd = devm_regulator_get(&pdev->dev, "vdd"); > - if (IS_ERR(tdev->vdd)) > - return PTR_ERR(tdev->vdd); > + if (IS_ERR(tdev->vdd)) { > + ret = PTR_ERR(tdev->vdd); > + goto free; > + } > > tdev->rst = devm_reset_control_get(&pdev->dev, "gpu"); > - if (IS_ERR(tdev->rst)) > - return PTR_ERR(tdev->rst); > + if (IS_ERR(tdev->rst)) { > + ret = PTR_ERR(tdev->rst); > + goto free; > + } > > tdev->clk = devm_clk_get(&pdev->dev, "gpu"); > - if (IS_ERR(tdev->clk)) > - return PTR_ERR(tdev->clk); > + if (IS_ERR(tdev->clk)) { > + ret = PTR_ERR(tdev->clk); > + goto free; > + } > > tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); > - if (IS_ERR(tdev->clk_pwr)) > - return PTR_ERR(tdev->clk_pwr); > + if (IS_ERR(tdev->clk_pwr)) { > + ret = PTR_ERR(tdev->clk_pwr); > + goto free; > + } > > nvkm_device_tegra_probe_iommu(tdev); > > ret = nvkm_device_tegra_power_up(tdev); > if (ret) > - return ret; > + goto remove; > > tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value; > ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev, > @@ -285,9 +293,19 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, > cfg, dbg, detect, mmio, subdev_mask, > &tdev->device); > if (ret) > - return ret; > + goto powerdown; > + > + *pdevice = &tdev->device; > > return 0; > + > +powerdown: > + nvkm_device_tegra_power_down(tdev); > +remove: > + nvkm_device_tegra_remove_iommu(tdev); > +free: > + kfree(tdev); > + return ret; > } > #else > int >
Attachment:
signature.asc
Description: OpenPGP digital signature