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 | { |