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 | |
| 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>
| -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) |
