Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[pandora-kernel.git] / arch / x86 / kernel / amd_iommu_init.c
index 246d727..bfc8453 100644 (file)
@@ -137,6 +137,7 @@ int amd_iommus_present;
 
 /* IOMMUs have a non-present cache? */
 bool amd_iommu_np_cache __read_mostly;
+bool amd_iommu_iotlb_sup __read_mostly = true;
 
 /*
  * The ACPI table parsing functions set this variable on an error
@@ -180,6 +181,12 @@ static u32 dev_table_size; /* size of the device table */
 static u32 alias_table_size;   /* size of the alias table */
 static u32 rlookup_table_size; /* size if the rlookup table */
 
+/*
+ * This function flushes all internal caches of
+ * the IOMMU used by this driver.
+ */
+extern void iommu_flush_all_caches(struct amd_iommu *iommu);
+
 static inline void update_last_devid(u16 devid)
 {
        if (devid > amd_iommu_last_bdf)
@@ -293,9 +300,23 @@ static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
 /* Function to enable the hardware */
 static void iommu_enable(struct amd_iommu *iommu)
 {
-       printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n",
+       static const char * const feat_str[] = {
+               "PreF", "PPR", "X2APIC", "NX", "GT", "[5]",
+               "IA", "GA", "HE", "PC", NULL
+       };
+       int i;
+
+       printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx",
               dev_name(&iommu->dev->dev), iommu->cap_ptr);
 
+       if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
+               printk(KERN_CONT " extended features: ");
+               for (i = 0; feat_str[i]; ++i)
+                       if (iommu_feature(iommu, (1ULL << i)))
+                               printk(KERN_CONT " %s", feat_str[i]);
+       }
+       printk(KERN_CONT "\n");
+
        iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
 }
 
@@ -651,7 +672,7 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
 static void __init init_iommu_from_pci(struct amd_iommu *iommu)
 {
        int cap_ptr = iommu->cap_ptr;
-       u32 range, misc;
+       u32 range, misc, low, high;
        int i, j;
 
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
@@ -667,6 +688,15 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
                                        MMIO_GET_LD(range));
        iommu->evt_msi_num = MMIO_MSI_NUM(misc);
 
+       if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
+               amd_iommu_iotlb_sup = false;
+
+       /* read extended feature bits */
+       low  = readl(iommu->mmio_base + MMIO_EXT_FEATURES);
+       high = readl(iommu->mmio_base + MMIO_EXT_FEATURES + 4);
+
+       iommu->features = ((u64)high << 32) | low;
+
        if (!is_rd890_iommu(iommu->dev))
                return;
 
@@ -701,8 +731,8 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
 {
        u8 *p = (u8 *)h;
        u8 *end = p, flags = 0;
-       u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
-       u32 ext_flags = 0;
+       u16 devid = 0, devid_start = 0, devid_to = 0;
+       u32 dev_i, ext_flags = 0;
        bool alias = false;
        struct ivhd_entry *e;
 
@@ -857,7 +887,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
 /* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
-       u16 i;
+       u32 i;
 
        for (i = iommu->first_device; i <= iommu->last_device; ++i)
                set_iommu_for_device(iommu, i);
@@ -1004,10 +1034,11 @@ static int iommu_setup_msi(struct amd_iommu *iommu)
        if (pci_enable_msi(iommu->dev))
                return 1;
 
-       r = request_irq(iommu->dev->irq, amd_iommu_int_handler,
-                       IRQF_SAMPLE_RANDOM,
-                       "AMD-Vi",
-                       NULL);
+       r = request_threaded_irq(iommu->dev->irq,
+                                amd_iommu_int_handler,
+                                amd_iommu_int_thread,
+                                0, "AMD-Vi",
+                                iommu->dev);
 
        if (r) {
                pci_disable_msi(iommu->dev);
@@ -1146,7 +1177,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
  */
 static void init_device_table(void)
 {
-       u16 devid;
+       u32 devid;
 
        for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
                set_dev_entry_bit(devid, DEV_ENTRY_VALID);
@@ -1244,6 +1275,7 @@ static void enable_iommus(void)
                iommu_set_exclusion_range(iommu);
                iommu_init_msi(iommu);
                iommu_enable(iommu);
+               iommu_flush_all_caches(iommu);
        }
 }
 
@@ -1274,8 +1306,8 @@ static void amd_iommu_resume(void)
         * we have to flush after the IOMMUs are enabled because a
         * disabled IOMMU will never execute the commands we send
         */
-       amd_iommu_flush_all_devices();
-       amd_iommu_flush_all_domains();
+       for_each_iommu(iommu)
+               iommu_flush_all_caches(iommu);
 }
 
 static int amd_iommu_suspend(void)