aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2016-02-24 12:34:43 -0500
committerDave Airlie <airlied@redhat.com>2016-02-24 21:20:59 -0500
commit870571a5698b2e9d0f4d2e5c6245967b582aab45 (patch)
tree07007eaad18c24e2edaa7cb2396fb6561125d8f0
parent398cb0c93b18b625703db30d874351e6d4cc645a (diff)
drm/nouveau: platform: Fix deferred probe
The error cleanup paths aren't quite correct and will crash upon deferred probe. Cc: stable@vger.kernel.org # v4.3+ Reviewed-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_platform.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c40
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 @@
24static int nouveau_platform_probe(struct platform_device *pdev) 24static int nouveau_platform_probe(struct platform_device *pdev)
25{ 25{
26 const struct nvkm_device_tegra_func *func; 26 const struct nvkm_device_tegra_func *func;
27 struct nvkm_device *device; 27 struct nvkm_device *device = NULL;
28 struct drm_device *drm; 28 struct drm_device *drm;
29 int ret; 29 int ret;
30 30
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,
252 252
253 if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) 253 if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
254 return -ENOMEM; 254 return -ENOMEM;
255 *pdevice = &tdev->device; 255
256 tdev->func = func; 256 tdev->func = func;
257 tdev->pdev = pdev; 257 tdev->pdev = pdev;
258 tdev->irq = -1; 258 tdev->irq = -1;
259 259
260 tdev->vdd = devm_regulator_get(&pdev->dev, "vdd"); 260 tdev->vdd = devm_regulator_get(&pdev->dev, "vdd");
261 if (IS_ERR(tdev->vdd)) 261 if (IS_ERR(tdev->vdd)) {
262 return PTR_ERR(tdev->vdd); 262 ret = PTR_ERR(tdev->vdd);
263 goto free;
264 }
263 265
264 tdev->rst = devm_reset_control_get(&pdev->dev, "gpu"); 266 tdev->rst = devm_reset_control_get(&pdev->dev, "gpu");
265 if (IS_ERR(tdev->rst)) 267 if (IS_ERR(tdev->rst)) {
266 return PTR_ERR(tdev->rst); 268 ret = PTR_ERR(tdev->rst);
269 goto free;
270 }
267 271
268 tdev->clk = devm_clk_get(&pdev->dev, "gpu"); 272 tdev->clk = devm_clk_get(&pdev->dev, "gpu");
269 if (IS_ERR(tdev->clk)) 273 if (IS_ERR(tdev->clk)) {
270 return PTR_ERR(tdev->clk); 274 ret = PTR_ERR(tdev->clk);
275 goto free;
276 }
271 277
272 tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); 278 tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
273 if (IS_ERR(tdev->clk_pwr)) 279 if (IS_ERR(tdev->clk_pwr)) {
274 return PTR_ERR(tdev->clk_pwr); 280 ret = PTR_ERR(tdev->clk_pwr);
281 goto free;
282 }
275 283
276 nvkm_device_tegra_probe_iommu(tdev); 284 nvkm_device_tegra_probe_iommu(tdev);
277 285
278 ret = nvkm_device_tegra_power_up(tdev); 286 ret = nvkm_device_tegra_power_up(tdev);
279 if (ret) 287 if (ret)
280 return ret; 288 goto remove;
281 289
282 tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value; 290 tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value;
283 ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev, 291 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,
285 cfg, dbg, detect, mmio, subdev_mask, 293 cfg, dbg, detect, mmio, subdev_mask,
286 &tdev->device); 294 &tdev->device);
287 if (ret) 295 if (ret)
288 return ret; 296 goto powerdown;
297
298 *pdevice = &tdev->device;
289 299
290 return 0; 300 return 0;
301
302powerdown:
303 nvkm_device_tegra_power_down(tdev);
304remove:
305 nvkm_device_tegra_remove_iommu(tdev);
306free:
307 kfree(tdev);
308 return ret;
291} 309}
292#else 310#else
293int 311int