aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2009-12-14 15:58:39 -0500
committerBen Skeggs <bskeggs@redhat.com>2009-12-16 02:05:20 -0500
commitc5804be0627508487bd9eacebf9de7f807e5d4e7 (patch)
treed8b6c13f6ecad5053f72b90eb822b025087612e8
parent13c5443b515109f175bb9917c578a7ae973f6851 (diff)
drm/nouveau: Add proper error handling to nouveau_card_init
Signed-off-by: Marcin Koƛcielnicki <koriakin@0x04.net> Signed-off-by: Maarten Maathuis <madman2003@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 2ed41d339f6a..9fc582432da9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -317,7 +317,7 @@ nouveau_card_init(struct drm_device *dev)
317 /* Initialise internal driver API hooks */ 317 /* Initialise internal driver API hooks */
318 ret = nouveau_init_engine_ptrs(dev); 318 ret = nouveau_init_engine_ptrs(dev);
319 if (ret) 319 if (ret)
320 return ret; 320 goto out;
321 engine = &dev_priv->engine; 321 engine = &dev_priv->engine;
322 dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; 322 dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
323 323
@@ -325,12 +325,12 @@ nouveau_card_init(struct drm_device *dev)
325 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 325 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
326 ret = nouveau_bios_init(dev); 326 ret = nouveau_bios_init(dev);
327 if (ret) 327 if (ret)
328 return ret; 328 goto out;
329 } 329 }
330 330
331 ret = nouveau_gpuobj_early_init(dev); 331 ret = nouveau_gpuobj_early_init(dev);
332 if (ret) 332 if (ret)
333 return ret; 333 goto out_bios;
334 334
335 /* Initialise instance memory, must happen before mem_init so we 335 /* Initialise instance memory, must happen before mem_init so we
336 * know exactly how much VRAM we're able to use for "normal" 336 * know exactly how much VRAM we're able to use for "normal"
@@ -338,52 +338,52 @@ nouveau_card_init(struct drm_device *dev)
338 */ 338 */
339 ret = engine->instmem.init(dev); 339 ret = engine->instmem.init(dev);
340 if (ret) 340 if (ret)
341 return ret; 341 goto out_gpuobj_early;
342 342
343 /* Setup the memory manager */ 343 /* Setup the memory manager */
344 ret = nouveau_mem_init(dev); 344 ret = nouveau_mem_init(dev);
345 if (ret) 345 if (ret)
346 return ret; 346 goto out_instmem;
347 347
348 ret = nouveau_gpuobj_init(dev); 348 ret = nouveau_gpuobj_init(dev);
349 if (ret) 349 if (ret)
350 return ret; 350 goto out_mem;
351 351
352 /* PMC */ 352 /* PMC */
353 ret = engine->mc.init(dev); 353 ret = engine->mc.init(dev);
354 if (ret) 354 if (ret)
355 return ret; 355 goto out_gpuobj;
356 356
357 /* PTIMER */ 357 /* PTIMER */
358 ret = engine->timer.init(dev); 358 ret = engine->timer.init(dev);
359 if (ret) 359 if (ret)
360 return ret; 360 goto out_mc;
361 361
362 /* PFB */ 362 /* PFB */
363 ret = engine->fb.init(dev); 363 ret = engine->fb.init(dev);
364 if (ret) 364 if (ret)
365 return ret; 365 goto out_timer;
366 366
367 /* PGRAPH */ 367 /* PGRAPH */
368 ret = engine->graph.init(dev); 368 ret = engine->graph.init(dev);
369 if (ret) 369 if (ret)
370 return ret; 370 goto out_fb;
371 371
372 /* PFIFO */ 372 /* PFIFO */
373 ret = engine->fifo.init(dev); 373 ret = engine->fifo.init(dev);
374 if (ret) 374 if (ret)
375 return ret; 375 goto out_graph;
376 376
377 /* this call irq_preinstall, register irq handler and 377 /* this call irq_preinstall, register irq handler and
378 * call irq_postinstall 378 * call irq_postinstall
379 */ 379 */
380 ret = drm_irq_install(dev); 380 ret = drm_irq_install(dev);
381 if (ret) 381 if (ret)
382 return ret; 382 goto out_fifo;
383 383
384 ret = drm_vblank_init(dev, 0); 384 ret = drm_vblank_init(dev, 0);
385 if (ret) 385 if (ret)
386 return ret; 386 goto out_irq;
387 387
388 /* what about PVIDEO/PCRTC/PRAMDAC etc? */ 388 /* what about PVIDEO/PCRTC/PRAMDAC etc? */
389 389
@@ -391,7 +391,7 @@ nouveau_card_init(struct drm_device *dev)
391 (struct drm_file *)-2, 391 (struct drm_file *)-2,
392 NvDmaFB, NvDmaTT); 392 NvDmaFB, NvDmaTT);
393 if (ret) 393 if (ret)
394 return ret; 394 goto out_irq;
395 395
396 gpuobj = NULL; 396 gpuobj = NULL;
397 ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 397 ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
@@ -399,13 +399,13 @@ nouveau_card_init(struct drm_device *dev)
399 NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, 399 NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
400 &gpuobj); 400 &gpuobj);
401 if (ret) 401 if (ret)
402 return ret; 402 goto out_irq;
403 403
404 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, 404 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
405 gpuobj, NULL); 405 gpuobj, NULL);
406 if (ret) { 406 if (ret) {
407 nouveau_gpuobj_del(dev, &gpuobj); 407 nouveau_gpuobj_del(dev, &gpuobj);
408 return ret; 408 goto out_irq;
409 } 409 }
410 410
411 gpuobj = NULL; 411 gpuobj = NULL;
@@ -413,25 +413,22 @@ nouveau_card_init(struct drm_device *dev)
413 dev_priv->gart_info.aper_size, 413 dev_priv->gart_info.aper_size,
414 NV_DMA_ACCESS_RW, &gpuobj, NULL); 414 NV_DMA_ACCESS_RW, &gpuobj, NULL);
415 if (ret) 415 if (ret)
416 return ret; 416 goto out_irq;
417 417
418 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, 418 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
419 gpuobj, NULL); 419 gpuobj, NULL);
420 if (ret) { 420 if (ret) {
421 nouveau_gpuobj_del(dev, &gpuobj); 421 nouveau_gpuobj_del(dev, &gpuobj);
422 return ret; 422 goto out_irq;
423 } 423 }
424 424
425 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 425 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
426 if (dev_priv->card_type >= NV_50) { 426 if (dev_priv->card_type >= NV_50)
427 ret = nv50_display_create(dev); 427 ret = nv50_display_create(dev);
428 if (ret) 428 else
429 return ret;
430 } else {
431 ret = nv04_display_create(dev); 429 ret = nv04_display_create(dev);
432 if (ret) 430 if (ret)
433 return ret; 431 goto out_irq;
434 }
435 } 432 }
436 433
437 ret = nouveau_backlight_init(dev); 434 ret = nouveau_backlight_init(dev);
@@ -444,6 +441,32 @@ nouveau_card_init(struct drm_device *dev)
444 drm_helper_initial_config(dev); 441 drm_helper_initial_config(dev);
445 442
446 return 0; 443 return 0;
444
445out_irq:
446 drm_irq_uninstall(dev);
447out_fifo:
448 engine->fifo.takedown(dev);
449out_graph:
450 engine->graph.takedown(dev);
451out_fb:
452 engine->fb.takedown(dev);
453out_timer:
454 engine->timer.takedown(dev);
455out_mc:
456 engine->mc.takedown(dev);
457out_gpuobj:
458 nouveau_gpuobj_takedown(dev);
459out_mem:
460 nouveau_mem_close(dev);
461out_instmem:
462 engine->instmem.takedown(dev);
463out_gpuobj_early:
464 nouveau_gpuobj_late_takedown(dev);
465out_bios:
466 nouveau_bios_takedown(dev);
467out:
468 vga_client_register(dev->pdev, NULL, NULL, NULL);
469 return ret;
447} 470}
448 471
449static void nouveau_card_takedown(struct drm_device *dev) 472static void nouveau_card_takedown(struct drm_device *dev)