static int lapic_suspend(struct sys_device *dev, pm_message_t state) { unsigned long flags; int maxlvt; if (!apic_pm_state.active) return 0; maxlvt = lapic_get_maxlvt(); apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); if (maxlvt >= 4) apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); #ifdef CONFIG_X86_THERMAL_VECTOR if (maxlvt >= 5) apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); #endif local_irq_save(flags); disable_local_APIC(); if (intr_remapping_enabled) disable_intr_remapping(); local_irq_restore(flags); return 0; }
int __init enable_intr_remapping(int eim) { struct dmar_drhd_unit *drhd; int setup = 0; for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; /* * Clear previous faults. */ dmar_fault(-1, iommu); /* * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ disable_intr_remapping(iommu); dmar_disable_qi(iommu); } /* * check for the Interrupt-remapping support */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); return -1; } } /* * Enable queued invalidation for all the DRHD's. */ for_each_drhd_unit(drhd) { int ret; struct intel_iommu *iommu = drhd->iommu; ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); return -1; } } /* * Setup Interrupt-remapping for all the DRHD's now. */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (setup_intr_remapping(iommu, eim)) goto error; setup = 1; } if (!setup) goto error; intr_remapping_enabled = 1; return 0; error: /* * handle error condition gracefully here! */ return -1; }