aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/pci/intel_mid_pci.c10
-rw-r--r--arch/x86/pci/irq.c7
-rw-r--r--drivers/acpi/pci_irq.c11
-rw-r--r--include/linux/pci.h1
4 files changed, 25 insertions, 4 deletions
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c
index b9958c364075..44b9271580b5 100644
--- a/arch/x86/pci/intel_mid_pci.c
+++ b/arch/x86/pci/intel_mid_pci.c
@@ -210,6 +210,9 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
210{ 210{
211 int polarity; 211 int polarity;
212 212
213 if (dev->irq_managed && dev->irq > 0)
214 return 0;
215
213 if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) 216 if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
214 polarity = 0; /* active high */ 217 polarity = 0; /* active high */
215 else 218 else
@@ -224,13 +227,18 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
224 if (mp_map_gsi_to_irq(dev->irq, IOAPIC_MAP_ALLOC) < 0) 227 if (mp_map_gsi_to_irq(dev->irq, IOAPIC_MAP_ALLOC) < 0)
225 return -EBUSY; 228 return -EBUSY;
226 229
230 dev->irq_managed = 1;
231
227 return 0; 232 return 0;
228} 233}
229 234
230static void intel_mid_pci_irq_disable(struct pci_dev *dev) 235static void intel_mid_pci_irq_disable(struct pci_dev *dev)
231{ 236{
232 if (!mp_should_keep_irq(&dev->dev) && dev->irq > 0) 237 if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
238 dev->irq > 0) {
233 mp_unmap_irq(dev->irq); 239 mp_unmap_irq(dev->irq);
240 dev->irq_managed = 0;
241 }
234} 242}
235 243
236struct pci_ops intel_mid_pci_ops = { 244struct pci_ops intel_mid_pci_ops = {
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index cb50e281d838..99884588a47a 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1202,6 +1202,9 @@ static int pirq_enable_irq(struct pci_dev *dev)
1202 int irq; 1202 int irq;
1203 struct io_apic_irq_attr irq_attr; 1203 struct io_apic_irq_attr irq_attr;
1204 1204
1205 if (dev->irq_managed && dev->irq > 0)
1206 return 0;
1207
1205 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, 1208 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
1206 PCI_SLOT(dev->devfn), 1209 PCI_SLOT(dev->devfn),
1207 pin - 1, &irq_attr); 1210 pin - 1, &irq_attr);
@@ -1228,6 +1231,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
1228 } 1231 }
1229 dev = temp_dev; 1232 dev = temp_dev;
1230 if (irq >= 0) { 1233 if (irq >= 0) {
1234 dev->irq_managed = 1;
1231 dev->irq = irq; 1235 dev->irq = irq;
1232 dev_info(&dev->dev, "PCI->APIC IRQ transform: " 1236 dev_info(&dev->dev, "PCI->APIC IRQ transform: "
1233 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); 1237 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
@@ -1269,8 +1273,9 @@ bool mp_should_keep_irq(struct device *dev)
1269static void pirq_disable_irq(struct pci_dev *dev) 1273static void pirq_disable_irq(struct pci_dev *dev)
1270{ 1274{
1271 if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && 1275 if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
1272 dev->irq) { 1276 dev->irq_managed && dev->irq) {
1273 mp_unmap_irq(dev->irq); 1277 mp_unmap_irq(dev->irq);
1274 dev->irq = 0; 1278 dev->irq = 0;
1279 dev->irq_managed = 0;
1275 } 1280 }
1276} 1281}
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 6e6b80eb0bba..5f1fdca65e5f 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -413,6 +413,9 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
413 return 0; 413 return 0;
414 } 414 }
415 415
416 if (dev->irq_managed && dev->irq > 0)
417 return 0;
418
416 entry = acpi_pci_irq_lookup(dev, pin); 419 entry = acpi_pci_irq_lookup(dev, pin);
417 if (!entry) { 420 if (!entry) {
418 /* 421 /*
@@ -456,6 +459,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
456 return rc; 459 return rc;
457 } 460 }
458 dev->irq = rc; 461 dev->irq = rc;
462 dev->irq_managed = 1;
459 463
460 if (link) 464 if (link)
461 snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); 465 snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
@@ -478,7 +482,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
478 u8 pin; 482 u8 pin;
479 483
480 pin = dev->pin; 484 pin = dev->pin;
481 if (!pin) 485 if (!pin || !dev->irq_managed || dev->irq <= 0)
482 return; 486 return;
483 487
484 /* Keep IOAPIC pin configuration when suspending */ 488 /* Keep IOAPIC pin configuration when suspending */
@@ -506,6 +510,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
506 */ 510 */
507 511
508 dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); 512 dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
509 if (gsi >= 0 && dev->irq > 0) 513 if (gsi >= 0) {
510 acpi_unregister_gsi(gsi); 514 acpi_unregister_gsi(gsi);
515 dev->irq = 0;
516 dev->irq_managed = 0;
517 }
511} 518}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a523cee3abb5..c888c5e4e225 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -349,6 +349,7 @@ struct pci_dev {
349 unsigned int __aer_firmware_first:1; 349 unsigned int __aer_firmware_first:1;
350 unsigned int broken_intx_masking:1; 350 unsigned int broken_intx_masking:1;
351 unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ 351 unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */
352 unsigned int irq_managed:1;
352 pci_dev_flags_t dev_flags; 353 pci_dev_flags_t dev_flags;
353 atomic_t enable_cnt; /* pci_enable_device has been called */ 354 atomic_t enable_cnt; /* pci_enable_device has been called */
354 355