Merge commit 'v2.6.31-rc1' into dmaengine
[pandora-kernel.git] / arch / x86 / kernel / amd_iommu_init.c
index 238989e..10b2acc 100644 (file)
@@ -260,6 +260,14 @@ static void iommu_enable(struct amd_iommu *iommu)
 
 static void iommu_disable(struct amd_iommu *iommu)
 {
+       /* Disable command buffer */
+       iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);
+
+       /* Disable event logging and event interrupts */
+       iommu_feature_disable(iommu, CONTROL_EVT_INT_EN);
+       iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
+
+       /* Disable IOMMU hardware itself */
        iommu_feature_disable(iommu, CONTROL_IOMMU_EN);
 }
 
@@ -478,6 +486,10 @@ static void iommu_enable_event_buffer(struct amd_iommu *iommu)
        memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET,
                    &entry, sizeof(entry));
 
+       /* set head and tail to zero manually */
+       writel(0x00, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
+       writel(0x00, iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
+
        iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
 }
 
@@ -1042,6 +1054,7 @@ static void enable_iommus(void)
        struct amd_iommu *iommu;
 
        for_each_iommu(iommu) {
+               iommu_disable(iommu);
                iommu_set_device_table(iommu);
                iommu_enable_command_buffer(iommu);
                iommu_enable_event_buffer(iommu);
@@ -1066,12 +1079,6 @@ static void disable_iommus(void)
 
 static int amd_iommu_resume(struct sys_device *dev)
 {
-       /*
-        * Disable IOMMUs before reprogramming the hardware registers.
-        * IOMMU is still enabled from the resume kernel.
-        */
-       disable_iommus();
-
        /* re-load the hardware */
        enable_iommus();
 
@@ -1079,8 +1086,8 @@ static int amd_iommu_resume(struct sys_device *dev)
         * we have to flush after the IOMMUs are enabled because a
         * disabled IOMMU will never execute the commands we send
         */
-       amd_iommu_flush_all_domains();
        amd_iommu_flush_all_devices();
+       amd_iommu_flush_all_domains();
 
        return 0;
 }
@@ -1273,6 +1280,11 @@ free:
        goto out;
 }
 
+void amd_iommu_shutdown(void)
+{
+       disable_iommus();
+}
+
 /****************************************************************************
  *
  * Early detect code. This code runs at IOMMU detection time in the DMA