diff options
Diffstat (limited to 'drivers/pci')
| -rw-r--r-- | drivers/pci/intel-iommu.c | 6 | ||||
| -rw-r--r-- | drivers/pci/intr_remapping.c | 77 | ||||
| -rw-r--r-- | drivers/pci/msi.c | 55 | ||||
| -rw-r--r-- | drivers/pci/pci-acpi.c | 15 | ||||
| -rw-r--r-- | drivers/pci/pci-sysfs.c | 4 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 6 | ||||
| -rw-r--r-- | drivers/pci/pcie/aspm.c | 29 | ||||
| -rw-r--r-- | drivers/pci/probe.c | 4 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 17 | ||||
| -rw-r--r-- | drivers/pci/slot.c | 1 |
10 files changed, 176 insertions, 38 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index a2692724b68f..5c8baa43ac9c 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
| @@ -1655,12 +1655,14 @@ int __init init_dmars(void) | |||
| 1655 | iommu->flush.flush_context = __iommu_flush_context; | 1655 | iommu->flush.flush_context = __iommu_flush_context; |
| 1656 | iommu->flush.flush_iotlb = __iommu_flush_iotlb; | 1656 | iommu->flush.flush_iotlb = __iommu_flush_iotlb; |
| 1657 | printk(KERN_INFO "IOMMU 0x%Lx: using Register based " | 1657 | printk(KERN_INFO "IOMMU 0x%Lx: using Register based " |
| 1658 | "invalidation\n", drhd->reg_base_addr); | 1658 | "invalidation\n", |
| 1659 | (unsigned long long)drhd->reg_base_addr); | ||
| 1659 | } else { | 1660 | } else { |
| 1660 | iommu->flush.flush_context = qi_flush_context; | 1661 | iommu->flush.flush_context = qi_flush_context; |
| 1661 | iommu->flush.flush_iotlb = qi_flush_iotlb; | 1662 | iommu->flush.flush_iotlb = qi_flush_iotlb; |
| 1662 | printk(KERN_INFO "IOMMU 0x%Lx: using Queued " | 1663 | printk(KERN_INFO "IOMMU 0x%Lx: using Queued " |
| 1663 | "invalidation\n", drhd->reg_base_addr); | 1664 | "invalidation\n", |
| 1665 | (unsigned long long)drhd->reg_base_addr); | ||
| 1664 | } | 1666 | } |
| 1665 | } | 1667 | } |
| 1666 | 1668 | ||
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 2de5a3238c94..f78371b22529 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
| 6 | #include <linux/irq.h> | 6 | #include <linux/irq.h> |
| 7 | #include <asm/io_apic.h> | 7 | #include <asm/io_apic.h> |
| 8 | #include <asm/smp.h> | ||
| 8 | #include <linux/intel-iommu.h> | 9 | #include <linux/intel-iommu.h> |
| 9 | #include "intr_remapping.h" | 10 | #include "intr_remapping.h" |
| 10 | 11 | ||
| @@ -19,17 +20,75 @@ struct irq_2_iommu { | |||
| 19 | u8 irte_mask; | 20 | u8 irte_mask; |
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 22 | static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; | 23 | #ifdef CONFIG_SPARSE_IRQ |
| 24 | static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu) | ||
| 25 | { | ||
| 26 | struct irq_2_iommu *iommu; | ||
| 27 | int node; | ||
| 28 | |||
| 29 | node = cpu_to_node(cpu); | ||
| 30 | |||
| 31 | iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node); | ||
| 32 | printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node); | ||
| 33 | |||
| 34 | return iommu; | ||
| 35 | } | ||
| 23 | 36 | ||
| 24 | static struct irq_2_iommu *irq_2_iommu(unsigned int irq) | 37 | static struct irq_2_iommu *irq_2_iommu(unsigned int irq) |
| 25 | { | 38 | { |
| 26 | return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL; | 39 | struct irq_desc *desc; |
| 40 | |||
| 41 | desc = irq_to_desc(irq); | ||
| 42 | |||
| 43 | if (WARN_ON_ONCE(!desc)) | ||
| 44 | return NULL; | ||
| 45 | |||
| 46 | return desc->irq_2_iommu; | ||
| 47 | } | ||
| 48 | |||
| 49 | static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu) | ||
| 50 | { | ||
| 51 | struct irq_desc *desc; | ||
| 52 | struct irq_2_iommu *irq_iommu; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * alloc irq desc if not allocated already. | ||
| 56 | */ | ||
| 57 | desc = irq_to_desc_alloc_cpu(irq, cpu); | ||
| 58 | if (!desc) { | ||
| 59 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); | ||
| 60 | return NULL; | ||
| 61 | } | ||
| 62 | |||
| 63 | irq_iommu = desc->irq_2_iommu; | ||
| 64 | |||
| 65 | if (!irq_iommu) | ||
| 66 | desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu); | ||
| 67 | |||
| 68 | return desc->irq_2_iommu; | ||
| 27 | } | 69 | } |
| 28 | 70 | ||
| 29 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) | 71 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) |
| 30 | { | 72 | { |
| 73 | return irq_2_iommu_alloc_cpu(irq, boot_cpu_id); | ||
| 74 | } | ||
| 75 | |||
| 76 | #else /* !CONFIG_SPARSE_IRQ */ | ||
| 77 | |||
| 78 | static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; | ||
| 79 | |||
| 80 | static struct irq_2_iommu *irq_2_iommu(unsigned int irq) | ||
| 81 | { | ||
| 82 | if (irq < nr_irqs) | ||
| 83 | return &irq_2_iommuX[irq]; | ||
| 84 | |||
| 85 | return NULL; | ||
| 86 | } | ||
| 87 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) | ||
| 88 | { | ||
| 31 | return irq_2_iommu(irq); | 89 | return irq_2_iommu(irq); |
| 32 | } | 90 | } |
| 91 | #endif | ||
| 33 | 92 | ||
| 34 | static DEFINE_SPINLOCK(irq_2_ir_lock); | 93 | static DEFINE_SPINLOCK(irq_2_ir_lock); |
| 35 | 94 | ||
| @@ -86,9 +145,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
| 86 | if (!count) | 145 | if (!count) |
| 87 | return -1; | 146 | return -1; |
| 88 | 147 | ||
| 148 | #ifndef CONFIG_SPARSE_IRQ | ||
| 89 | /* protect irq_2_iommu_alloc later */ | 149 | /* protect irq_2_iommu_alloc later */ |
| 90 | if (irq >= nr_irqs) | 150 | if (irq >= nr_irqs) |
| 91 | return -1; | 151 | return -1; |
| 152 | #endif | ||
| 92 | 153 | ||
| 93 | /* | 154 | /* |
| 94 | * start the IRTE search from index 0. | 155 | * start the IRTE search from index 0. |
| @@ -130,6 +191,12 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
| 130 | table->base[i].present = 1; | 191 | table->base[i].present = 1; |
| 131 | 192 | ||
| 132 | irq_iommu = irq_2_iommu_alloc(irq); | 193 | irq_iommu = irq_2_iommu_alloc(irq); |
| 194 | if (!irq_iommu) { | ||
| 195 | spin_unlock(&irq_2_ir_lock); | ||
| 196 | printk(KERN_ERR "can't allocate irq_2_iommu\n"); | ||
| 197 | return -1; | ||
| 198 | } | ||
| 199 | |||
| 133 | irq_iommu->iommu = iommu; | 200 | irq_iommu->iommu = iommu; |
| 134 | irq_iommu->irte_index = index; | 201 | irq_iommu->irte_index = index; |
| 135 | irq_iommu->sub_handle = 0; | 202 | irq_iommu->sub_handle = 0; |
| @@ -177,6 +244,12 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | |||
| 177 | 244 | ||
| 178 | irq_iommu = irq_2_iommu_alloc(irq); | 245 | irq_iommu = irq_2_iommu_alloc(irq); |
| 179 | 246 | ||
| 247 | if (!irq_iommu) { | ||
| 248 | spin_unlock(&irq_2_ir_lock); | ||
| 249 | printk(KERN_ERR "can't allocate irq_2_iommu\n"); | ||
| 250 | return -1; | ||
| 251 | } | ||
| 252 | |||
| 180 | irq_iommu->iommu = iommu; | 253 | irq_iommu->iommu = iommu; |
| 181 | irq_iommu->irte_index = index; | 254 | irq_iommu->irte_index = index; |
| 182 | irq_iommu->sub_handle = subhandle; | 255 | irq_iommu->sub_handle = subhandle; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 74801f7df9c9..11a51f8ed3b3 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -103,11 +103,11 @@ static void msix_set_enable(struct pci_dev *dev, int enable) | |||
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static void msix_flush_writes(unsigned int irq) | 106 | static void msix_flush_writes(struct irq_desc *desc) |
| 107 | { | 107 | { |
| 108 | struct msi_desc *entry; | 108 | struct msi_desc *entry; |
| 109 | 109 | ||
| 110 | entry = get_irq_msi(irq); | 110 | entry = get_irq_desc_msi(desc); |
| 111 | BUG_ON(!entry || !entry->dev); | 111 | BUG_ON(!entry || !entry->dev); |
| 112 | switch (entry->msi_attrib.type) { | 112 | switch (entry->msi_attrib.type) { |
| 113 | case PCI_CAP_ID_MSI: | 113 | case PCI_CAP_ID_MSI: |
| @@ -135,11 +135,11 @@ static void msix_flush_writes(unsigned int irq) | |||
| 135 | * Returns 1 if it succeeded in masking the interrupt and 0 if the device | 135 | * Returns 1 if it succeeded in masking the interrupt and 0 if the device |
| 136 | * doesn't support MSI masking. | 136 | * doesn't support MSI masking. |
| 137 | */ | 137 | */ |
| 138 | static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag) | 138 | static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag) |
| 139 | { | 139 | { |
| 140 | struct msi_desc *entry; | 140 | struct msi_desc *entry; |
| 141 | 141 | ||
| 142 | entry = get_irq_msi(irq); | 142 | entry = get_irq_desc_msi(desc); |
| 143 | BUG_ON(!entry || !entry->dev); | 143 | BUG_ON(!entry || !entry->dev); |
| 144 | switch (entry->msi_attrib.type) { | 144 | switch (entry->msi_attrib.type) { |
| 145 | case PCI_CAP_ID_MSI: | 145 | case PCI_CAP_ID_MSI: |
| @@ -172,9 +172,9 @@ static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag) | |||
| 172 | return 1; | 172 | return 1; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) | 175 | void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) |
| 176 | { | 176 | { |
| 177 | struct msi_desc *entry = get_irq_msi(irq); | 177 | struct msi_desc *entry = get_irq_desc_msi(desc); |
| 178 | switch(entry->msi_attrib.type) { | 178 | switch(entry->msi_attrib.type) { |
| 179 | case PCI_CAP_ID_MSI: | 179 | case PCI_CAP_ID_MSI: |
| 180 | { | 180 | { |
| @@ -211,9 +211,16 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
| 211 | } | 211 | } |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | void write_msi_msg(unsigned int irq, struct msi_msg *msg) | 214 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) |
| 215 | { | 215 | { |
| 216 | struct msi_desc *entry = get_irq_msi(irq); | 216 | struct irq_desc *desc = irq_to_desc(irq); |
| 217 | |||
| 218 | read_msi_msg_desc(desc, msg); | ||
| 219 | } | ||
| 220 | |||
| 221 | void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) | ||
| 222 | { | ||
| 223 | struct msi_desc *entry = get_irq_desc_msi(desc); | ||
| 217 | switch (entry->msi_attrib.type) { | 224 | switch (entry->msi_attrib.type) { |
| 218 | case PCI_CAP_ID_MSI: | 225 | case PCI_CAP_ID_MSI: |
| 219 | { | 226 | { |
| @@ -252,21 +259,31 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
| 252 | entry->msg = *msg; | 259 | entry->msg = *msg; |
| 253 | } | 260 | } |
| 254 | 261 | ||
| 262 | void write_msi_msg(unsigned int irq, struct msi_msg *msg) | ||
| 263 | { | ||
| 264 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 265 | |||
| 266 | write_msi_msg_desc(desc, msg); | ||
| 267 | } | ||
| 268 | |||
| 255 | void mask_msi_irq(unsigned int irq) | 269 | void mask_msi_irq(unsigned int irq) |
| 256 | { | 270 | { |
| 257 | msi_set_mask_bits(irq, 1, 1); | 271 | struct irq_desc *desc = irq_to_desc(irq); |
| 258 | msix_flush_writes(irq); | 272 | |
| 273 | msi_set_mask_bits(desc, 1, 1); | ||
| 274 | msix_flush_writes(desc); | ||
| 259 | } | 275 | } |
| 260 | 276 | ||
| 261 | void unmask_msi_irq(unsigned int irq) | 277 | void unmask_msi_irq(unsigned int irq) |
| 262 | { | 278 | { |
| 263 | msi_set_mask_bits(irq, 1, 0); | 279 | struct irq_desc *desc = irq_to_desc(irq); |
| 264 | msix_flush_writes(irq); | 280 | |
| 281 | msi_set_mask_bits(desc, 1, 0); | ||
| 282 | msix_flush_writes(desc); | ||
| 265 | } | 283 | } |
| 266 | 284 | ||
| 267 | static int msi_free_irqs(struct pci_dev* dev); | 285 | static int msi_free_irqs(struct pci_dev* dev); |
| 268 | 286 | ||
| 269 | |||
| 270 | static struct msi_desc* alloc_msi_entry(void) | 287 | static struct msi_desc* alloc_msi_entry(void) |
| 271 | { | 288 | { |
| 272 | struct msi_desc *entry; | 289 | struct msi_desc *entry; |
| @@ -303,9 +320,11 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
| 303 | pci_intx_for_msi(dev, 0); | 320 | pci_intx_for_msi(dev, 0); |
| 304 | msi_set_enable(dev, 0); | 321 | msi_set_enable(dev, 0); |
| 305 | write_msi_msg(dev->irq, &entry->msg); | 322 | write_msi_msg(dev->irq, &entry->msg); |
| 306 | if (entry->msi_attrib.maskbit) | 323 | if (entry->msi_attrib.maskbit) { |
| 307 | msi_set_mask_bits(dev->irq, entry->msi_attrib.maskbits_mask, | 324 | struct irq_desc *desc = irq_to_desc(dev->irq); |
| 325 | msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask, | ||
| 308 | entry->msi_attrib.masked); | 326 | entry->msi_attrib.masked); |
| 327 | } | ||
| 309 | 328 | ||
| 310 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | 329 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); |
| 311 | control &= ~PCI_MSI_FLAGS_QSIZE; | 330 | control &= ~PCI_MSI_FLAGS_QSIZE; |
| @@ -327,8 +346,9 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
| 327 | msix_set_enable(dev, 0); | 346 | msix_set_enable(dev, 0); |
| 328 | 347 | ||
| 329 | list_for_each_entry(entry, &dev->msi_list, list) { | 348 | list_for_each_entry(entry, &dev->msi_list, list) { |
| 349 | struct irq_desc *desc = irq_to_desc(entry->irq); | ||
| 330 | write_msi_msg(entry->irq, &entry->msg); | 350 | write_msi_msg(entry->irq, &entry->msg); |
| 331 | msi_set_mask_bits(entry->irq, 1, entry->msi_attrib.masked); | 351 | msi_set_mask_bits(desc, 1, entry->msi_attrib.masked); |
| 332 | } | 352 | } |
| 333 | 353 | ||
| 334 | BUG_ON(list_empty(&dev->msi_list)); | 354 | BUG_ON(list_empty(&dev->msi_list)); |
| @@ -596,7 +616,8 @@ void pci_msi_shutdown(struct pci_dev* dev) | |||
| 596 | /* Return the the pci reset with msi irqs unmasked */ | 616 | /* Return the the pci reset with msi irqs unmasked */ |
| 597 | if (entry->msi_attrib.maskbit) { | 617 | if (entry->msi_attrib.maskbit) { |
| 598 | u32 mask = entry->msi_attrib.maskbits_mask; | 618 | u32 mask = entry->msi_attrib.maskbits_mask; |
| 599 | msi_set_mask_bits(dev->irq, mask, ~mask); | 619 | struct irq_desc *desc = irq_to_desc(dev->irq); |
| 620 | msi_set_mask_bits(desc, mask, ~mask); | ||
| 600 | } | 621 | } |
| 601 | if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) | 622 | if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) |
| 602 | return; | 623 | return; |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index b3a63edb6901..ae5ec76dca77 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -63,7 +63,7 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
| 63 | union acpi_object in_params[4]; | 63 | union acpi_object in_params[4]; |
| 64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | 64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; |
| 65 | union acpi_object *out_obj; | 65 | union acpi_object *out_obj; |
| 66 | u32 osc_dw0, flags = osc_args->capbuf[OSC_QUERY_TYPE]; | 66 | u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE]; |
| 67 | 67 | ||
| 68 | /* Setting up input parameters */ | 68 | /* Setting up input parameters */ |
| 69 | input.count = 4; | 69 | input.count = 4; |
| @@ -92,15 +92,16 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
| 92 | status = AE_TYPE; | 92 | status = AE_TYPE; |
| 93 | goto out_kfree; | 93 | goto out_kfree; |
| 94 | } | 94 | } |
| 95 | osc_dw0 = *((u32 *)out_obj->buffer.pointer); | 95 | /* Need to ignore the bit0 in result code */ |
| 96 | if (osc_dw0) { | 96 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
| 97 | if (osc_dw0 & OSC_REQUEST_ERROR) | 97 | if (errors) { |
| 98 | if (errors & OSC_REQUEST_ERROR) | ||
| 98 | printk(KERN_DEBUG "_OSC request fails\n"); | 99 | printk(KERN_DEBUG "_OSC request fails\n"); |
| 99 | if (osc_dw0 & OSC_INVALID_UUID_ERROR) | 100 | if (errors & OSC_INVALID_UUID_ERROR) |
| 100 | printk(KERN_DEBUG "_OSC invalid UUID\n"); | 101 | printk(KERN_DEBUG "_OSC invalid UUID\n"); |
| 101 | if (osc_dw0 & OSC_INVALID_REVISION_ERROR) | 102 | if (errors & OSC_INVALID_REVISION_ERROR) |
| 102 | printk(KERN_DEBUG "_OSC invalid revision\n"); | 103 | printk(KERN_DEBUG "_OSC invalid revision\n"); |
| 103 | if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { | 104 | if (errors & OSC_CAPABILITIES_MASK_ERROR) { |
| 104 | if (flags & OSC_QUERY_ENABLE) | 105 | if (flags & OSC_QUERY_ENABLE) |
| 105 | goto out_success; | 106 | goto out_success; |
| 106 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); | 107 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5d72866897a8..c88485860a0a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -74,7 +74,7 @@ static ssize_t local_cpus_show(struct device *dev, | |||
| 74 | int len; | 74 | int len; |
| 75 | 75 | ||
| 76 | mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); | 76 | mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); |
| 77 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); | 77 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, &mask); |
| 78 | buf[len++] = '\n'; | 78 | buf[len++] = '\n'; |
| 79 | buf[len] = '\0'; | 79 | buf[len] = '\0'; |
| 80 | return len; | 80 | return len; |
| @@ -88,7 +88,7 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
| 88 | int len; | 88 | int len; |
| 89 | 89 | ||
| 90 | mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); | 90 | mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); |
| 91 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); | 91 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, &mask); |
| 92 | buf[len++] = '\n'; | 92 | buf[len++] = '\n'; |
| 93 | buf[len] = '\0'; | 93 | buf[len] = '\0'; |
| 94 | return len; | 94 | return len; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 21f2ac639cab..061d1ee0046a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1832,7 +1832,7 @@ int pci_reset_function(struct pci_dev *dev) | |||
| 1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | 1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) |
| 1833 | return -ENOTTY; | 1833 | return -ENOTTY; |
| 1834 | 1834 | ||
| 1835 | if (!dev->msi_enabled && !dev->msix_enabled) | 1835 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
| 1836 | disable_irq(dev->irq); | 1836 | disable_irq(dev->irq); |
| 1837 | pci_save_state(dev); | 1837 | pci_save_state(dev); |
| 1838 | 1838 | ||
| @@ -1841,7 +1841,7 @@ int pci_reset_function(struct pci_dev *dev) | |||
| 1841 | r = pci_execute_reset_function(dev); | 1841 | r = pci_execute_reset_function(dev); |
| 1842 | 1842 | ||
| 1843 | pci_restore_state(dev); | 1843 | pci_restore_state(dev); |
| 1844 | if (!dev->msi_enabled && !dev->msix_enabled) | 1844 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
| 1845 | enable_irq(dev->irq); | 1845 | enable_irq(dev->irq); |
| 1846 | 1846 | ||
| 1847 | return r; | 1847 | return r; |
| @@ -2042,7 +2042,7 @@ static int __devinit pci_init(void) | |||
| 2042 | return 0; | 2042 | return 0; |
| 2043 | } | 2043 | } |
| 2044 | 2044 | ||
| 2045 | static int __devinit pci_setup(char *str) | 2045 | static int __init pci_setup(char *str) |
| 2046 | { | 2046 | { |
| 2047 | while (str) { | 2047 | while (str) { |
| 2048 | char *k = strchr(str, ','); | 2048 | char *k = strchr(str, ','); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 8f63f4c6b85f..9aad608bcf3f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/jiffies.h> | ||
| 19 | #include <linux/pci-aspm.h> | 20 | #include <linux/pci-aspm.h> |
| 20 | #include "../pci.h" | 21 | #include "../pci.h" |
| 21 | 22 | ||
| @@ -161,11 +162,12 @@ static void pcie_check_clock_pm(struct pci_dev *pdev) | |||
| 161 | */ | 162 | */ |
| 162 | static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | 163 | static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) |
| 163 | { | 164 | { |
| 164 | int pos, child_pos; | 165 | int pos, child_pos, i = 0; |
| 165 | u16 reg16 = 0; | 166 | u16 reg16 = 0; |
| 166 | struct pci_dev *child_dev; | 167 | struct pci_dev *child_dev; |
| 167 | int same_clock = 1; | 168 | int same_clock = 1; |
| 168 | 169 | unsigned long start_jiffies; | |
| 170 | u16 child_regs[8], parent_reg; | ||
| 169 | /* | 171 | /* |
| 170 | * all functions of a slot should have the same Slot Clock | 172 | * all functions of a slot should have the same Slot Clock |
| 171 | * Configuration, so just check one function | 173 | * Configuration, so just check one function |
| @@ -191,16 +193,19 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | |||
| 191 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | 193 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); |
| 192 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | 194 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, |
| 193 | ®16); | 195 | ®16); |
| 196 | child_regs[i] = reg16; | ||
| 194 | if (same_clock) | 197 | if (same_clock) |
| 195 | reg16 |= PCI_EXP_LNKCTL_CCC; | 198 | reg16 |= PCI_EXP_LNKCTL_CCC; |
| 196 | else | 199 | else |
| 197 | reg16 &= ~PCI_EXP_LNKCTL_CCC; | 200 | reg16 &= ~PCI_EXP_LNKCTL_CCC; |
| 198 | pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | 201 | pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, |
| 199 | reg16); | 202 | reg16); |
| 203 | i++; | ||
| 200 | } | 204 | } |
| 201 | 205 | ||
| 202 | /* Configure upstream component */ | 206 | /* Configure upstream component */ |
| 203 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | 207 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); |
| 208 | parent_reg = reg16; | ||
| 204 | if (same_clock) | 209 | if (same_clock) |
| 205 | reg16 |= PCI_EXP_LNKCTL_CCC; | 210 | reg16 |= PCI_EXP_LNKCTL_CCC; |
| 206 | else | 211 | else |
| @@ -212,12 +217,30 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | |||
| 212 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | 217 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); |
| 213 | 218 | ||
| 214 | /* Wait for link training end */ | 219 | /* Wait for link training end */ |
| 215 | while (1) { | 220 | /* break out after waiting for 1 second */ |
| 221 | start_jiffies = jiffies; | ||
| 222 | while ((jiffies - start_jiffies) < HZ) { | ||
| 216 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); | 223 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); |
| 217 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | 224 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) |
| 218 | break; | 225 | break; |
| 219 | cpu_relax(); | 226 | cpu_relax(); |
| 220 | } | 227 | } |
| 228 | /* training failed -> recover */ | ||
| 229 | if ((jiffies - start_jiffies) >= HZ) { | ||
| 230 | dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" | ||
| 231 | " common clock\n"); | ||
| 232 | i = 0; | ||
| 233 | list_for_each_entry(child_dev, &pdev->subordinate->devices, | ||
| 234 | bus_list) { | ||
| 235 | child_pos = pci_find_capability(child_dev, | ||
| 236 | PCI_CAP_ID_EXP); | ||
| 237 | pci_write_config_word(child_dev, | ||
| 238 | child_pos + PCI_EXP_LNKCTL, | ||
| 239 | child_regs[i]); | ||
| 240 | i++; | ||
| 241 | } | ||
| 242 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, parent_reg); | ||
| 243 | } | ||
| 221 | } | 244 | } |
| 222 | 245 | ||
| 223 | /* | 246 | /* |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 003a9b3c293f..5b3f5937ecf5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -55,8 +55,8 @@ static ssize_t pci_bus_show_cpuaffinity(struct device *dev, | |||
| 55 | 55 | ||
| 56 | cpumask = pcibus_to_cpumask(to_pci_bus(dev)); | 56 | cpumask = pcibus_to_cpumask(to_pci_bus(dev)); |
| 57 | ret = type? | 57 | ret = type? |
| 58 | cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask): | 58 | cpulist_scnprintf(buf, PAGE_SIZE-2, &cpumask) : |
| 59 | cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask); | 59 | cpumask_scnprintf(buf, PAGE_SIZE-2, &cpumask); |
| 60 | buf[ret++] = '\n'; | 60 | buf[ret++] = '\n'; |
| 61 | buf[ret] = '\0'; | 61 | buf[ret] = '\0'; |
| 62 | return ret; | 62 | return ret; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5049a47030ac..5f4f85f56cb7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
| 24 | #include <linux/kallsyms.h> | 24 | #include <linux/kallsyms.h> |
| 25 | #include <linux/dmi.h> | ||
| 25 | #include "pci.h" | 26 | #include "pci.h" |
| 26 | 27 | ||
| 27 | int isa_dma_bridge_buggy; | 28 | int isa_dma_bridge_buggy; |
| @@ -1828,6 +1829,22 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | |||
| 1828 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 1829 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, |
| 1829 | ht_enable_msi_mapping); | 1830 | ht_enable_msi_mapping); |
| 1830 | 1831 | ||
| 1832 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi | ||
| 1833 | * for the MCP55 NIC. It is not yet determined whether the msi problem | ||
| 1834 | * also affects other devices. As for now, turn off msi for this device. | ||
| 1835 | */ | ||
| 1836 | static void __devinit nvenet_msi_disable(struct pci_dev *dev) | ||
| 1837 | { | ||
| 1838 | if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { | ||
| 1839 | dev_info(&dev->dev, | ||
| 1840 | "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); | ||
| 1841 | dev->no_msi = 1; | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | ||
| 1845 | PCI_DEVICE_ID_NVIDIA_NVENET_15, | ||
| 1846 | nvenet_msi_disable); | ||
| 1847 | |||
| 1831 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 1848 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) |
| 1832 | { | 1849 | { |
| 1833 | struct pci_dev *host_bridge; | 1850 | struct pci_dev *host_bridge; |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 4dd1c3e157ae..5a8ccb4f604d 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
| @@ -253,6 +253,7 @@ placeholder: | |||
| 253 | __func__, pci_domain_nr(parent), parent->number, slot_nr); | 253 | __func__, pci_domain_nr(parent), parent->number, slot_nr); |
| 254 | 254 | ||
| 255 | out: | 255 | out: |
| 256 | kfree(slot_name); | ||
| 256 | up_write(&pci_bus_sem); | 257 | up_write(&pci_bus_sem); |
| 257 | return slot; | 258 | return slot; |
| 258 | err: | 259 | err: |
