diff options
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 8 | ||||
| -rw-r--r-- | arch/x86/pci/i386.c | 4 | ||||
| -rw-r--r-- | drivers/pci/intel-iommu.c | 6 | ||||
| -rw-r--r-- | drivers/pci/pci-acpi.c | 109 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 1 |
5 files changed, 89 insertions, 39 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 0c37f16b6950..c5ef1af8e79d 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
| @@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 385 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) | 385 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) |
| 386 | return memory; | 386 | return memory; |
| 387 | 387 | ||
| 388 | if (!dev) | 388 | if (!dev) { |
| 389 | dev = &fallback_dev; | 389 | dev = &fallback_dev; |
| 390 | gfp |= GFP_DMA; | ||
| 391 | } | ||
| 390 | dma_mask = dev->coherent_dma_mask; | 392 | dma_mask = dev->coherent_dma_mask; |
| 391 | if (dma_mask == 0) | 393 | if (dma_mask == 0) |
| 392 | dma_mask = DMA_32BIT_MASK; | 394 | dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK; |
| 393 | 395 | ||
| 394 | /* Device not DMA able */ | 396 | /* Device not DMA able */ |
| 395 | if (dev->dma_mask == NULL) | 397 | if (dev->dma_mask == NULL) |
| @@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 403 | larger than 16MB and in this case we have a chance of | 405 | larger than 16MB and in this case we have a chance of |
| 404 | finding fitting memory in the next higher zone first. If | 406 | finding fitting memory in the next higher zone first. If |
| 405 | not retry with true GFP_DMA. -AK */ | 407 | not retry with true GFP_DMA. -AK */ |
| 406 | if (dma_mask <= DMA_32BIT_MASK) | 408 | if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA)) |
| 407 | gfp |= GFP_DMA32; | 409 | gfp |= GFP_DMA32; |
| 408 | #endif | 410 | #endif |
| 409 | 411 | ||
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 8af0f0bae2af..10fb308fded8 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
| @@ -301,15 +301,13 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
| 301 | prot = pgprot_val(vma->vm_page_prot); | 301 | prot = pgprot_val(vma->vm_page_prot); |
| 302 | if (pat_wc_enabled && write_combine) | 302 | if (pat_wc_enabled && write_combine) |
| 303 | prot |= _PAGE_CACHE_WC; | 303 | prot |= _PAGE_CACHE_WC; |
| 304 | else if (pat_wc_enabled) | 304 | else if (pat_wc_enabled || boot_cpu_data.x86 > 3) |
| 305 | /* | 305 | /* |
| 306 | * ioremap() and ioremap_nocache() defaults to UC MINUS for now. | 306 | * ioremap() and ioremap_nocache() defaults to UC MINUS for now. |
| 307 | * To avoid attribute conflicts, request UC MINUS here | 307 | * To avoid attribute conflicts, request UC MINUS here |
| 308 | * aswell. | 308 | * aswell. |
| 309 | */ | 309 | */ |
| 310 | prot |= _PAGE_CACHE_UC_MINUS; | 310 | prot |= _PAGE_CACHE_UC_MINUS; |
| 311 | else if (boot_cpu_data.x86 > 3) | ||
| 312 | prot |= _PAGE_CACHE_UC; | ||
| 313 | 311 | ||
| 314 | vma->vm_page_prot = __pgprot(prot); | 312 | vma->vm_page_prot = __pgprot(prot); |
| 315 | 313 | ||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 1fd8bb765702..66c0fd21894b 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
| @@ -49,7 +49,7 @@ | |||
| 49 | 49 | ||
| 50 | #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 | 50 | #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 |
| 51 | 51 | ||
| 52 | #define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ | 52 | #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */ |
| 53 | 53 | ||
| 54 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) | 54 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) |
| 55 | 55 | ||
| @@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) | |||
| 490 | 490 | ||
| 491 | #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ | 491 | #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ |
| 492 | {\ | 492 | {\ |
| 493 | unsigned long start_time = jiffies;\ | 493 | cycles_t start_time = get_cycles();\ |
| 494 | while (1) {\ | 494 | while (1) {\ |
| 495 | sts = op (iommu->reg + offset);\ | 495 | sts = op (iommu->reg + offset);\ |
| 496 | if (cond)\ | 496 | if (cond)\ |
| 497 | break;\ | 497 | break;\ |
| 498 | if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\ | 498 | if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\ |
| 499 | panic("DMAR hardware is malfunctioning\n");\ | 499 | panic("DMAR hardware is malfunctioning\n");\ |
| 500 | cpu_relax();\ | 500 | cpu_relax();\ |
| 501 | }\ | 501 | }\ |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 72f7476930c8..9d6fc8e6285d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -19,8 +19,31 @@ | |||
| 19 | #include <linux/pci-acpi.h> | 19 | #include <linux/pci-acpi.h> |
| 20 | #include "pci.h" | 20 | #include "pci.h" |
| 21 | 21 | ||
| 22 | static u32 ctrlset_buf[3] = {0, 0, 0}; | 22 | struct acpi_osc_data { |
| 23 | static u32 global_ctrlsets = 0; | 23 | acpi_handle handle; |
| 24 | u32 ctrlset_buf[3]; | ||
| 25 | u32 global_ctrlsets; | ||
| 26 | struct list_head sibiling; | ||
| 27 | }; | ||
| 28 | static LIST_HEAD(acpi_osc_data_list); | ||
| 29 | |||
| 30 | static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle) | ||
| 31 | { | ||
| 32 | struct acpi_osc_data *data; | ||
| 33 | |||
| 34 | list_for_each_entry(data, &acpi_osc_data_list, sibiling) { | ||
| 35 | if (data->handle == handle) | ||
| 36 | return data; | ||
| 37 | } | ||
| 38 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 39 | if (!data) | ||
| 40 | return NULL; | ||
| 41 | INIT_LIST_HEAD(&data->sibiling); | ||
| 42 | data->handle = handle; | ||
| 43 | list_add_tail(&data->sibiling, &acpi_osc_data_list); | ||
| 44 | return data; | ||
| 45 | } | ||
| 46 | |||
| 24 | static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; | 47 | static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; |
| 25 | 48 | ||
| 26 | static acpi_status | 49 | static acpi_status |
| @@ -37,8 +60,27 @@ acpi_query_osc ( | |||
| 37 | union acpi_object *out_obj; | 60 | union acpi_object *out_obj; |
| 38 | u32 osc_dw0; | 61 | u32 osc_dw0; |
| 39 | acpi_status *ret_status = (acpi_status *)retval; | 62 | acpi_status *ret_status = (acpi_status *)retval; |
| 63 | struct acpi_osc_data *osc_data; | ||
| 64 | u32 flags = (unsigned long)context, temp; | ||
| 65 | acpi_handle tmp; | ||
| 66 | |||
| 67 | status = acpi_get_handle(handle, "_OSC", &tmp); | ||
| 68 | if (ACPI_FAILURE(status)) | ||
| 69 | return status; | ||
| 70 | |||
| 71 | osc_data = acpi_get_osc_data(handle); | ||
| 72 | if (!osc_data) { | ||
| 73 | printk(KERN_ERR "acpi osc data array is full\n"); | ||
| 74 | return AE_ERROR; | ||
| 75 | } | ||
| 76 | |||
| 77 | osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS); | ||
| 78 | |||
| 79 | /* do _OSC query for all possible controls */ | ||
| 80 | temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE]; | ||
| 81 | osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | ||
| 82 | osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | ||
| 40 | 83 | ||
| 41 | |||
| 42 | /* Setting up input parameters */ | 84 | /* Setting up input parameters */ |
| 43 | input.count = 4; | 85 | input.count = 4; |
| 44 | input.pointer = in_params; | 86 | input.pointer = in_params; |
| @@ -51,13 +93,11 @@ acpi_query_osc ( | |||
| 51 | in_params[2].integer.value = 3; | 93 | in_params[2].integer.value = 3; |
| 52 | in_params[3].type = ACPI_TYPE_BUFFER; | 94 | in_params[3].type = ACPI_TYPE_BUFFER; |
| 53 | in_params[3].buffer.length = 12; | 95 | in_params[3].buffer.length = 12; |
| 54 | in_params[3].buffer.pointer = (u8 *)context; | 96 | in_params[3].buffer.pointer = (u8 *)osc_data->ctrlset_buf; |
| 55 | 97 | ||
| 56 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); | 98 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); |
| 57 | if (ACPI_FAILURE (status)) { | 99 | if (ACPI_FAILURE(status)) |
| 58 | *ret_status = status; | 100 | goto out_nofree; |
| 59 | return status; | ||
| 60 | } | ||
| 61 | out_obj = output.pointer; | 101 | out_obj = output.pointer; |
| 62 | 102 | ||
| 63 | if (out_obj->type != ACPI_TYPE_BUFFER) { | 103 | if (out_obj->type != ACPI_TYPE_BUFFER) { |
| @@ -76,7 +116,8 @@ acpi_query_osc ( | |||
| 76 | printk(KERN_DEBUG "_OSC invalid revision\n"); | 116 | printk(KERN_DEBUG "_OSC invalid revision\n"); |
| 77 | if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { | 117 | if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { |
| 78 | /* Update Global Control Set */ | 118 | /* Update Global Control Set */ |
| 79 | global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8)); | 119 | osc_data->global_ctrlsets = |
| 120 | *((u32 *)(out_obj->buffer.pointer + 8)); | ||
| 80 | status = AE_OK; | 121 | status = AE_OK; |
| 81 | goto query_osc_out; | 122 | goto query_osc_out; |
| 82 | } | 123 | } |
| @@ -85,12 +126,21 @@ acpi_query_osc ( | |||
| 85 | } | 126 | } |
| 86 | 127 | ||
| 87 | /* Update Global Control Set */ | 128 | /* Update Global Control Set */ |
| 88 | global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); | 129 | osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); |
| 89 | status = AE_OK; | 130 | status = AE_OK; |
| 90 | 131 | ||
| 91 | query_osc_out: | 132 | query_osc_out: |
| 92 | kfree(output.pointer); | 133 | kfree(output.pointer); |
| 134 | out_nofree: | ||
| 93 | *ret_status = status; | 135 | *ret_status = status; |
| 136 | |||
| 137 | osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; | ||
| 138 | osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp; | ||
| 139 | if (ACPI_FAILURE(status)) { | ||
| 140 | /* no osc support at all */ | ||
| 141 | osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0; | ||
| 142 | } | ||
| 143 | |||
| 94 | return status; | 144 | return status; |
| 95 | } | 145 | } |
| 96 | 146 | ||
| @@ -165,28 +215,15 @@ run_osc_out: | |||
| 165 | **/ | 215 | **/ |
| 166 | acpi_status __pci_osc_support_set(u32 flags, const char *hid) | 216 | acpi_status __pci_osc_support_set(u32 flags, const char *hid) |
| 167 | { | 217 | { |
| 168 | u32 temp; | 218 | acpi_status retval = AE_NOT_FOUND; |
| 169 | acpi_status retval; | ||
| 170 | 219 | ||
| 171 | if (!(flags & OSC_SUPPORT_MASKS)) { | 220 | if (!(flags & OSC_SUPPORT_MASKS)) { |
| 172 | return AE_TYPE; | 221 | return AE_TYPE; |
| 173 | } | 222 | } |
| 174 | ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS); | ||
| 175 | |||
| 176 | /* do _OSC query for all possible controls */ | ||
| 177 | temp = ctrlset_buf[OSC_CONTROL_TYPE]; | ||
| 178 | ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | ||
| 179 | ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | ||
| 180 | acpi_get_devices(hid, | 223 | acpi_get_devices(hid, |
| 181 | acpi_query_osc, | 224 | acpi_query_osc, |
| 182 | ctrlset_buf, | 225 | (void *)(unsigned long)flags, |
| 183 | (void **) &retval ); | 226 | (void **) &retval ); |
| 184 | ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; | ||
| 185 | ctrlset_buf[OSC_CONTROL_TYPE] = temp; | ||
| 186 | if (ACPI_FAILURE(retval)) { | ||
| 187 | /* no osc support at all */ | ||
| 188 | ctrlset_buf[OSC_SUPPORT_TYPE] = 0; | ||
| 189 | } | ||
| 190 | return AE_OK; | 227 | return AE_OK; |
| 191 | } | 228 | } |
| 192 | 229 | ||
| @@ -201,19 +238,31 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) | |||
| 201 | { | 238 | { |
| 202 | acpi_status status; | 239 | acpi_status status; |
| 203 | u32 ctrlset; | 240 | u32 ctrlset; |
| 241 | acpi_handle tmp; | ||
| 242 | struct acpi_osc_data *osc_data; | ||
| 243 | |||
| 244 | status = acpi_get_handle(handle, "_OSC", &tmp); | ||
| 245 | if (ACPI_FAILURE(status)) | ||
| 246 | return status; | ||
| 247 | |||
| 248 | osc_data = acpi_get_osc_data(handle); | ||
| 249 | if (!osc_data) { | ||
| 250 | printk(KERN_ERR "acpi osc data array is full\n"); | ||
| 251 | return AE_ERROR; | ||
| 252 | } | ||
| 204 | 253 | ||
| 205 | ctrlset = (flags & OSC_CONTROL_MASKS); | 254 | ctrlset = (flags & OSC_CONTROL_MASKS); |
| 206 | if (!ctrlset) { | 255 | if (!ctrlset) { |
| 207 | return AE_TYPE; | 256 | return AE_TYPE; |
| 208 | } | 257 | } |
| 209 | if (ctrlset_buf[OSC_SUPPORT_TYPE] && | 258 | if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] && |
| 210 | ((global_ctrlsets & ctrlset) != ctrlset)) { | 259 | ((osc_data->global_ctrlsets & ctrlset) != ctrlset)) { |
| 211 | return AE_SUPPORT; | 260 | return AE_SUPPORT; |
| 212 | } | 261 | } |
| 213 | ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; | 262 | osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; |
| 214 | status = acpi_run_osc(handle, ctrlset_buf); | 263 | status = acpi_run_osc(handle, osc_data->ctrlset_buf); |
| 215 | if (ACPI_FAILURE (status)) { | 264 | if (ACPI_FAILURE (status)) { |
| 216 | ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; | 265 | osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; |
| 217 | } | 266 | } |
| 218 | 267 | ||
| 219 | return status; | 268 | return status; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index afd914ebe215..f2d9c770f51a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -1826,6 +1826,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | |||
| 1826 | } | 1826 | } |
| 1827 | } | 1827 | } |
| 1828 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); | 1828 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); |
| 1829 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); | ||
| 1829 | 1830 | ||
| 1830 | static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) | 1831 | static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) |
| 1831 | { | 1832 | { |
