aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorFenghua Yu <fenghua.yu@intel.com>2009-03-27 17:22:44 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-04-03 16:45:59 -0400
commitb24696bc55f66fecc30715e003f10fc2555a9271 (patch)
tree3ef565bf041a06106a73d0b27ccc256845ef5644 /drivers/pci
parenteb4a52bc660ea835482c582eaaf4893742cbd160 (diff)
Intel IOMMU Suspend/Resume Support - Interrupt Remapping
This patch enables suspend/resume for interrupt remapping. During suspend, interrupt remapping is disabled. When resume, interrupt remapping is enabled again. Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/intr_remapping.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index b041a409f4a7..c26633d7e7da 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -470,7 +470,7 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
470/* 470/*
471 * Disable Interrupt Remapping. 471 * Disable Interrupt Remapping.
472 */ 472 */
473static void disable_intr_remapping(struct intel_iommu *iommu) 473static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
474{ 474{
475 unsigned long flags; 475 unsigned long flags;
476 u32 sts; 476 u32 sts;
@@ -478,6 +478,12 @@ static void disable_intr_remapping(struct intel_iommu *iommu)
478 if (!ecap_ir_support(iommu->ecap)) 478 if (!ecap_ir_support(iommu->ecap))
479 return; 479 return;
480 480
481 /*
482 * global invalidation of interrupt entry cache before disabling
483 * interrupt-remapping.
484 */
485 qi_global_iec(iommu);
486
481 spin_lock_irqsave(&iommu->register_lock, flags); 487 spin_lock_irqsave(&iommu->register_lock, flags);
482 488
483 sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); 489 sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
@@ -511,7 +517,7 @@ int __init enable_intr_remapping(int eim)
511 * Disable intr remapping and queued invalidation, if already 517 * Disable intr remapping and queued invalidation, if already
512 * enabled prior to OS handover. 518 * enabled prior to OS handover.
513 */ 519 */
514 disable_intr_remapping(iommu); 520 iommu_disable_intr_remapping(iommu);
515 521
516 dmar_disable_qi(iommu); 522 dmar_disable_qi(iommu);
517 } 523 }
@@ -639,3 +645,54 @@ int __init parse_ioapics_under_ir(void)
639 645
640 return ir_supported; 646 return ir_supported;
641} 647}
648
649void disable_intr_remapping(void)
650{
651 struct dmar_drhd_unit *drhd;
652 struct intel_iommu *iommu = NULL;
653
654 /*
655 * Disable Interrupt-remapping for all the DRHD's now.
656 */
657 for_each_iommu(iommu, drhd) {
658 if (!ecap_ir_support(iommu->ecap))
659 continue;
660
661 iommu_disable_intr_remapping(iommu);
662 }
663}
664
665int reenable_intr_remapping(int eim)
666{
667 struct dmar_drhd_unit *drhd;
668 int setup = 0;
669 struct intel_iommu *iommu = NULL;
670
671 for_each_iommu(iommu, drhd)
672 if (iommu->qi)
673 dmar_reenable_qi(iommu);
674
675 /*
676 * Setup Interrupt-remapping for all the DRHD's now.
677 */
678 for_each_iommu(iommu, drhd) {
679 if (!ecap_ir_support(iommu->ecap))
680 continue;
681
682 /* Set up interrupt remapping for iommu.*/
683 iommu_set_intr_remapping(iommu, eim);
684 setup = 1;
685 }
686
687 if (!setup)
688 goto error;
689
690 return 0;
691
692error:
693 /*
694 * handle error condition gracefully here!
695 */
696 return -1;
697}
698