aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/intr_remapping.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/intr_remapping.c')
-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