diff options
author | Christian Koenig <christian.koenig@amd.com> | 2012-05-16 19:33:30 -0400 |
---|---|---|
committer | Christian König <deathsimple@vodafone.de> | 2012-06-21 03:38:50 -0400 |
commit | fb98257a9d9d2089972b18079d5bdd4412e107e2 (patch) | |
tree | 72f6115ccae023c1e6122bdd82cf310c8014de23 /drivers/gpu/drm/radeon/r100.c | |
parent | c20dc3698dc7ecf053e2bf77299ae5982c0c2c45 (diff) |
drm/radeon: apply Murphy's law to the kms irq code v3
1. It is really dangerous to have more than one
spinlock protecting the same information.
2. radeon_irq_set sometimes wasn't called with lock
protection, so it can happen that more than one
CPU would tamper with the irq regs at the same
time.
3. The pm.gui_idle variable was assuming that the 3D
engine wasn't becoming idle between testing the
register and setting the variable. So just remove
it and test the register directly.
v2: Also handle the hpd irq code the same way.
v3: Rename hpd parameter for clarification.
Signed-off-by: Christian Koenig <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 29 |
1 files changed, 6 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 415b7d8fbba2..e8fe4ae3bc23 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -567,43 +567,27 @@ void r100_hpd_init(struct radeon_device *rdev) | |||
567 | { | 567 | { |
568 | struct drm_device *dev = rdev->ddev; | 568 | struct drm_device *dev = rdev->ddev; |
569 | struct drm_connector *connector; | 569 | struct drm_connector *connector; |
570 | unsigned enable = 0; | ||
570 | 571 | ||
571 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 572 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
572 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 573 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
573 | switch (radeon_connector->hpd.hpd) { | 574 | enable |= 1 << radeon_connector->hpd.hpd; |
574 | case RADEON_HPD_1: | ||
575 | rdev->irq.hpd[0] = true; | ||
576 | break; | ||
577 | case RADEON_HPD_2: | ||
578 | rdev->irq.hpd[1] = true; | ||
579 | break; | ||
580 | default: | ||
581 | break; | ||
582 | } | ||
583 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 575 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
584 | } | 576 | } |
585 | if (rdev->irq.installed) | 577 | radeon_irq_kms_enable_hpd(rdev, enable); |
586 | r100_irq_set(rdev); | ||
587 | } | 578 | } |
588 | 579 | ||
589 | void r100_hpd_fini(struct radeon_device *rdev) | 580 | void r100_hpd_fini(struct radeon_device *rdev) |
590 | { | 581 | { |
591 | struct drm_device *dev = rdev->ddev; | 582 | struct drm_device *dev = rdev->ddev; |
592 | struct drm_connector *connector; | 583 | struct drm_connector *connector; |
584 | unsigned disable = 0; | ||
593 | 585 | ||
594 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 586 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
595 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 587 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
596 | switch (radeon_connector->hpd.hpd) { | 588 | disable |= 1 << radeon_connector->hpd.hpd; |
597 | case RADEON_HPD_1: | ||
598 | rdev->irq.hpd[0] = false; | ||
599 | break; | ||
600 | case RADEON_HPD_2: | ||
601 | rdev->irq.hpd[1] = false; | ||
602 | break; | ||
603 | default: | ||
604 | break; | ||
605 | } | ||
606 | } | 589 | } |
590 | radeon_irq_kms_disable_hpd(rdev, disable); | ||
607 | } | 591 | } |
608 | 592 | ||
609 | /* | 593 | /* |
@@ -782,7 +766,6 @@ int r100_irq_process(struct radeon_device *rdev) | |||
782 | /* gui idle interrupt */ | 766 | /* gui idle interrupt */ |
783 | if (status & RADEON_GUI_IDLE_STAT) { | 767 | if (status & RADEON_GUI_IDLE_STAT) { |
784 | rdev->irq.gui_idle_acked = true; | 768 | rdev->irq.gui_idle_acked = true; |
785 | rdev->pm.gui_idle = true; | ||
786 | wake_up(&rdev->irq.idle_queue); | 769 | wake_up(&rdev->irq.idle_queue); |
787 | } | 770 | } |
788 | /* Vertical blank interrupts */ | 771 | /* Vertical blank interrupts */ |