diff options
author | Jonathan Corbet <corbet@lwn.net> | 2010-04-30 12:03:57 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2010-05-07 19:17:40 -0400 |
commit | 8bbf50fe9c0fb8d83b993ae6d88a4ce27d81b999 (patch) | |
tree | e49180692af9f2a2ccb5455dc1265509c129aa72 /drivers/video/via | |
parent | 27fe971d08b43f649358745a55f3c48ac6f413f8 (diff) |
viafb: Fix initialization error paths
Properly localize error cleanup, and make sure that the iomem regions are
unmapped if framebuffer initialization fails.
Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/video/via')
-rw-r--r-- | drivers/video/via/via-core.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 9929bb1549b6..188c0022dcb4 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c | |||
@@ -453,26 +453,40 @@ static int viafb_get_fb_size_from_pci(int chip_type) | |||
453 | */ | 453 | */ |
454 | static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) | 454 | static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) |
455 | { | 455 | { |
456 | int ret; | ||
456 | /* | 457 | /* |
457 | * Hook up to the device registers. | 458 | * Hook up to the device registers. Note that we soldier |
459 | * on if it fails; the framebuffer can operate (without | ||
460 | * acceleration) without this region. | ||
458 | */ | 461 | */ |
459 | vdev->engine_start = pci_resource_start(vdev->pdev, 1); | 462 | vdev->engine_start = pci_resource_start(vdev->pdev, 1); |
460 | vdev->engine_len = pci_resource_len(vdev->pdev, 1); | 463 | vdev->engine_len = pci_resource_len(vdev->pdev, 1); |
461 | /* If this fails, others will notice later */ | ||
462 | vdev->engine_mmio = ioremap_nocache(vdev->engine_start, | 464 | vdev->engine_mmio = ioremap_nocache(vdev->engine_start, |
463 | vdev->engine_len); | 465 | vdev->engine_len); |
464 | 466 | if (vdev->engine_mmio == NULL) | |
467 | dev_err(&vdev->pdev->dev, | ||
468 | "Unable to map engine MMIO; operation will be " | ||
469 | "slow and crippled.\n"); | ||
465 | /* | 470 | /* |
466 | * Likewise with I/O memory. | 471 | * Map in framebuffer memory. For now, failure here is |
472 | * fatal. Unfortunately, in the absence of significant | ||
473 | * vmalloc space, failure here is also entirely plausible. | ||
474 | * Eventually we want to move away from mapping this | ||
475 | * entire region. | ||
467 | */ | 476 | */ |
468 | vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); | 477 | vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); |
469 | vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); | 478 | ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); |
470 | if (vdev->fbmem_len < 0) | 479 | if (ret < 0) |
471 | return vdev->fbmem_len; | 480 | goto out_unmap; |
472 | vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); | 481 | vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); |
473 | if (vdev->fbmem == NULL) | 482 | if (vdev->fbmem == NULL) { |
474 | return -ENOMEM; | 483 | ret = -ENOMEM; |
484 | goto out_unmap; | ||
485 | } | ||
475 | return 0; | 486 | return 0; |
487 | out_unmap: | ||
488 | iounmap(vdev->engine_mmio); | ||
489 | return ret; | ||
476 | } | 490 | } |
477 | 491 | ||
478 | static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) | 492 | static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) |
@@ -572,12 +586,11 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
572 | viafb_int_init(); | 586 | viafb_int_init(); |
573 | via_setup_subdevs(&global_dev); | 587 | via_setup_subdevs(&global_dev); |
574 | /* | 588 | /* |
575 | * Set up the framebuffer. | 589 | * Set up the framebuffer device |
576 | */ | 590 | */ |
577 | ret = via_fb_pci_probe(&global_dev); | 591 | ret = via_fb_pci_probe(&global_dev); |
578 | if (ret) | 592 | if (ret) |
579 | goto out_subdevs; | 593 | goto out_subdevs; |
580 | |||
581 | return 0; | 594 | return 0; |
582 | 595 | ||
583 | out_subdevs: | 596 | out_subdevs: |