diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2010-10-01 04:21:49 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-01 07:08:51 -0400 |
commit | 7a1c2f6c8d8485af5ac6c2a313f6a7162207a4af (patch) | |
tree | 867f60ced7f7742dc2f4a2010d32b516e90ea411 /drivers | |
parent | 30c78bb838b26ec7997515844c0c734e454b3cba (diff) |
vmwgfx: Enable use of the vblank system
This is to avoid accessing uninitialized data during
drm_irq_uninstall and vblank ioctls. At the same time, enable error check from
drm_kms_init which previously appeared to ignore all errors.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 27 |
4 files changed, 49 insertions, 31 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 23e29f3a0c33..6bbe703e7d97 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -374,17 +374,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
374 | 374 | ||
375 | dev->dev_private = dev_priv; | 375 | dev->dev_private = dev_priv; |
376 | 376 | ||
377 | if (!dev->devname) | ||
378 | dev->devname = vmw_devname; | ||
379 | |||
380 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
381 | ret = drm_irq_install(dev); | ||
382 | if (unlikely(ret != 0)) { | ||
383 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
384 | goto out_no_irq; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); | 377 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); |
389 | dev_priv->stealth = (ret != 0); | 378 | dev_priv->stealth = (ret != 0); |
390 | if (dev_priv->stealth) { | 379 | if (dev_priv->stealth) { |
@@ -400,7 +389,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
400 | goto out_no_device; | 389 | goto out_no_device; |
401 | } | 390 | } |
402 | } | 391 | } |
403 | vmw_kms_init(dev_priv); | 392 | ret = vmw_kms_init(dev_priv); |
393 | if (unlikely(ret != 0)) | ||
394 | goto out_no_kms; | ||
404 | vmw_overlay_init(dev_priv); | 395 | vmw_overlay_init(dev_priv); |
405 | if (dev_priv->enable_fb) { | 396 | if (dev_priv->enable_fb) { |
406 | ret = vmw_3d_resource_inc(dev_priv); | 397 | ret = vmw_3d_resource_inc(dev_priv); |
@@ -416,24 +407,37 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
416 | "running the device in SVGA mode yet.\n"); | 407 | "running the device in SVGA mode yet.\n"); |
417 | } | 408 | } |
418 | 409 | ||
410 | if (!dev->devname) | ||
411 | dev->devname = vmw_devname; | ||
412 | |||
413 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
414 | ret = drm_irq_install(dev); | ||
415 | if (unlikely(ret != 0)) { | ||
416 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
417 | goto out_no_irq; | ||
418 | } | ||
419 | } | ||
420 | |||
419 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 421 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
420 | register_pm_notifier(&dev_priv->pm_nb); | 422 | register_pm_notifier(&dev_priv->pm_nb); |
421 | 423 | ||
422 | return 0; | 424 | return 0; |
423 | 425 | ||
426 | out_no_irq: | ||
427 | if (dev_priv->enable_fb) { | ||
428 | vmw_fb_close(dev_priv); | ||
429 | vmw_kms_restore_vga(dev_priv); | ||
430 | vmw_3d_resource_dec(dev_priv); | ||
431 | } | ||
424 | out_no_fifo: | 432 | out_no_fifo: |
425 | vmw_overlay_close(dev_priv); | 433 | vmw_overlay_close(dev_priv); |
426 | vmw_kms_close(dev_priv); | 434 | vmw_kms_close(dev_priv); |
435 | out_no_kms: | ||
427 | if (dev_priv->stealth) | 436 | if (dev_priv->stealth) |
428 | pci_release_region(dev->pdev, 2); | 437 | pci_release_region(dev->pdev, 2); |
429 | else | 438 | else |
430 | pci_release_regions(dev->pdev); | 439 | pci_release_regions(dev->pdev); |
431 | out_no_device: | 440 | out_no_device: |
432 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
433 | drm_irq_uninstall(dev_priv->dev); | ||
434 | if (dev->devname == vmw_devname) | ||
435 | dev->devname = NULL; | ||
436 | out_no_irq: | ||
437 | ttm_object_device_release(&dev_priv->tdev); | 441 | ttm_object_device_release(&dev_priv->tdev); |
438 | out_err4: | 442 | out_err4: |
439 | iounmap(dev_priv->mmio_virt); | 443 | iounmap(dev_priv->mmio_virt); |
@@ -460,6 +464,10 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
460 | 464 | ||
461 | unregister_pm_notifier(&dev_priv->pm_nb); | 465 | unregister_pm_notifier(&dev_priv->pm_nb); |
462 | 466 | ||
467 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
468 | drm_irq_uninstall(dev_priv->dev); | ||
469 | if (dev->devname == vmw_devname) | ||
470 | dev->devname = NULL; | ||
463 | if (dev_priv->enable_fb) { | 471 | if (dev_priv->enable_fb) { |
464 | vmw_fb_close(dev_priv); | 472 | vmw_fb_close(dev_priv); |
465 | vmw_kms_restore_vga(dev_priv); | 473 | vmw_kms_restore_vga(dev_priv); |
@@ -472,10 +480,6 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
472 | else | 480 | else |
473 | pci_release_regions(dev->pdev); | 481 | pci_release_regions(dev->pdev); |
474 | 482 | ||
475 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
476 | drm_irq_uninstall(dev_priv->dev); | ||
477 | if (dev->devname == vmw_devname) | ||
478 | dev->devname = NULL; | ||
479 | ttm_object_device_release(&dev_priv->tdev); | 483 | ttm_object_device_release(&dev_priv->tdev); |
480 | iounmap(dev_priv->mmio_virt); | 484 | iounmap(dev_priv->mmio_virt); |
481 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 485 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
@@ -798,6 +802,7 @@ static struct drm_driver driver = { | |||
798 | .irq_postinstall = vmw_irq_postinstall, | 802 | .irq_postinstall = vmw_irq_postinstall, |
799 | .irq_uninstall = vmw_irq_uninstall, | 803 | .irq_uninstall = vmw_irq_uninstall, |
800 | .irq_handler = vmw_irq_handler, | 804 | .irq_handler = vmw_irq_handler, |
805 | .get_vblank_counter = vmw_get_vblank_counter, | ||
801 | .reclaim_buffers_locked = NULL, | 806 | .reclaim_buffers_locked = NULL, |
802 | .get_map_ofs = drm_core_get_map_ofs, | 807 | .get_map_ofs = drm_core_get_map_ofs, |
803 | .get_reg_ofs = drm_core_get_reg_ofs, | 808 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 9142454cc91e..58de6393f611 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -518,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
518 | unsigned bbp, unsigned depth); | 518 | unsigned bbp, unsigned depth); |
519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
520 | struct drm_file *file_priv); | 520 | struct drm_file *file_priv); |
521 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | ||
521 | 522 | ||
522 | /** | 523 | /** |
523 | * Overlay control - vmwgfx_overlay.c | 524 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 1636e9ba81a1..e882ba099f0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -996,3 +996,8 @@ out_unlock: | |||
996 | ttm_read_unlock(&vmaster->lock); | 996 | ttm_read_unlock(&vmaster->lock); |
997 | return ret; | 997 | return ret; |
998 | } | 998 | } |
999 | |||
1000 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) | ||
1001 | { | ||
1002 | return 0; | ||
1003 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 7083b1a24df3..11cb39e3accb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include "vmwgfx_kms.h" | 28 | #include "vmwgfx_kms.h" |
29 | 29 | ||
30 | #define VMWGFX_LDU_NUM_DU 8 | ||
31 | |||
30 | #define vmw_crtc_to_ldu(x) \ | 32 | #define vmw_crtc_to_ldu(x) \ |
31 | container_of(x, struct vmw_legacy_display_unit, base.crtc) | 33 | container_of(x, struct vmw_legacy_display_unit, base.crtc) |
32 | #define vmw_encoder_to_ldu(x) \ | 34 | #define vmw_encoder_to_ldu(x) \ |
@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
536 | 538 | ||
537 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | 539 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) |
538 | { | 540 | { |
541 | struct drm_device *dev = dev_priv->dev; | ||
542 | int i; | ||
543 | int ret; | ||
544 | |||
539 | if (dev_priv->ldu_priv) { | 545 | if (dev_priv->ldu_priv) { |
540 | DRM_INFO("ldu system already on\n"); | 546 | DRM_INFO("ldu system already on\n"); |
541 | return -EINVAL; | 547 | return -EINVAL; |
@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
553 | 559 | ||
554 | drm_mode_create_dirty_info_property(dev_priv->dev); | 560 | drm_mode_create_dirty_info_property(dev_priv->dev); |
555 | 561 | ||
556 | vmw_ldu_init(dev_priv, 0); | ||
557 | /* for old hardware without multimon only enable one display */ | ||
558 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { | 562 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { |
559 | vmw_ldu_init(dev_priv, 1); | 563 | for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) |
560 | vmw_ldu_init(dev_priv, 2); | 564 | vmw_ldu_init(dev_priv, i); |
561 | vmw_ldu_init(dev_priv, 3); | 565 | ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); |
562 | vmw_ldu_init(dev_priv, 4); | 566 | } else { |
563 | vmw_ldu_init(dev_priv, 5); | 567 | /* for old hardware without multimon only enable one display */ |
564 | vmw_ldu_init(dev_priv, 6); | 568 | vmw_ldu_init(dev_priv, 0); |
565 | vmw_ldu_init(dev_priv, 7); | 569 | ret = drm_vblank_init(dev, 1); |
566 | } | 570 | } |
567 | 571 | ||
568 | return 0; | 572 | return ret; |
569 | } | 573 | } |
570 | 574 | ||
571 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | 575 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) |
572 | { | 576 | { |
577 | struct drm_device *dev = dev_priv->dev; | ||
578 | |||
579 | drm_vblank_cleanup(dev); | ||
573 | if (!dev_priv->ldu_priv) | 580 | if (!dev_priv->ldu_priv) |
574 | return -ENOSYS; | 581 | return -ENOSYS; |
575 | 582 | ||