aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2010-04-30 12:03:57 -0400
committerJonathan Corbet <corbet@lwn.net>2010-05-07 19:17:40 -0400
commit8bbf50fe9c0fb8d83b993ae6d88a4ce27d81b999 (patch)
treee49180692af9f2a2ccb5455dc1265509c129aa72 /drivers/video
parent27fe971d08b43f649358745a55f3c48ac6f413f8 (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')
-rw-r--r--drivers/video/via/via-core.c35
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 */
454static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) 454static 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;
487out_unmap:
488 iounmap(vdev->engine_mmio);
489 return ret;
476} 490}
477 491
478static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) 492static 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
583out_subdevs: 596out_subdevs: