diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2009-12-14 15:58:39 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2009-12-16 02:05:20 -0500 |
commit | c5804be0627508487bd9eacebf9de7f807e5d4e7 (patch) | |
tree | d8b6c13f6ecad5053f72b90eb822b025087612e8 /drivers | |
parent | 13c5443b515109f175bb9917c578a7ae973f6851 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 73 |
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 | |||
445 | out_irq: | ||
446 | drm_irq_uninstall(dev); | ||
447 | out_fifo: | ||
448 | engine->fifo.takedown(dev); | ||
449 | out_graph: | ||
450 | engine->graph.takedown(dev); | ||
451 | out_fb: | ||
452 | engine->fb.takedown(dev); | ||
453 | out_timer: | ||
454 | engine->timer.takedown(dev); | ||
455 | out_mc: | ||
456 | engine->mc.takedown(dev); | ||
457 | out_gpuobj: | ||
458 | nouveau_gpuobj_takedown(dev); | ||
459 | out_mem: | ||
460 | nouveau_mem_close(dev); | ||
461 | out_instmem: | ||
462 | engine->instmem.takedown(dev); | ||
463 | out_gpuobj_early: | ||
464 | nouveau_gpuobj_late_takedown(dev); | ||
465 | out_bios: | ||
466 | nouveau_bios_takedown(dev); | ||
467 | out: | ||
468 | vga_client_register(dev->pdev, NULL, NULL, NULL); | ||
469 | return ret; | ||
447 | } | 470 | } |
448 | 471 | ||
449 | static void nouveau_card_takedown(struct drm_device *dev) | 472 | static void nouveau_card_takedown(struct drm_device *dev) |