Просмотр исходного кода

Merge branch 'pci/hotplug' into next

* pci/hotplug:
  PCI: pciehp: Leave power indicator on when enabling already-enabled slot
  PCI: pciehp: Prioritize data-link event over presence detect
  PCI: cpqphp: Add missing call to pci_disable_device()
Bjorn Helgaas 8 лет назад
Родитель
Сommit
4617aedbd2
3 измененных файлов с 15 добавлено и 11 удалено
  1. 2 1
      drivers/pci/hotplug/cpqphp_core.c
  2. 1 1
      drivers/pci/hotplug/pciehp_ctrl.c
  3. 12 9
      drivers/pci/hotplug/pciehp_hpc.c

+ 2 - 1
drivers/pci/hotplug/cpqphp_core.c

@@ -867,7 +867,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 */
 	 */
 	if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {
 	if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {
 		err(msg_HPC_not_supported);
 		err(msg_HPC_not_supported);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto err_disable_device;
 	}
 	}
 
 
 	/* TODO: This code can be made to support non-Compaq or Intel
 	/* TODO: This code can be made to support non-Compaq or Intel

+ 1 - 1
drivers/pci/hotplug/pciehp_ctrl.c

@@ -410,7 +410,7 @@ int pciehp_enable_slot(struct slot *p_slot)
 		if (getstatus) {
 		if (getstatus) {
 			ctrl_info(ctrl, "Slot(%s): Already enabled\n",
 			ctrl_info(ctrl, "Slot(%s): Already enabled\n",
 				  slot_name(p_slot));
 				  slot_name(p_slot));
-			return -EINVAL;
+			return 0;
 		}
 		}
 	}
 	}
 
 

+ 12 - 9
drivers/pci/hotplug/pciehp_hpc.c

@@ -620,8 +620,18 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
 		pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
 		pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
 	}
 	}
 
 
-	/* Check Presence Detect Changed */
-	if (events & PCI_EXP_SLTSTA_PDC) {
+	/*
+	 * Check Link Status Changed at higher precedence than Presence
+	 * Detect Changed.  The PDS value may be set to "card present" from
+	 * out-of-band detection, which may be in conflict with a Link Down
+	 * and cause the wrong event to queue.
+	 */
+	if (events & PCI_EXP_SLTSTA_DLLSC) {
+		ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot),
+			  link ? "Up" : "Down");
+		pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :
+					     INT_LINK_DOWN);
+	} else if (events & PCI_EXP_SLTSTA_PDC) {
 		present = !!(status & PCI_EXP_SLTSTA_PDS);
 		present = !!(status & PCI_EXP_SLTSTA_PDS);
 		ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot),
 		ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot),
 			  present ? "" : "not ");
 			  present ? "" : "not ");
@@ -636,13 +646,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
 		pciehp_queue_interrupt_event(slot, INT_POWER_FAULT);
 		pciehp_queue_interrupt_event(slot, INT_POWER_FAULT);
 	}
 	}
 
 
-	if (events & PCI_EXP_SLTSTA_DLLSC) {
-		ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot),
-			  link ? "Up" : "Down");
-		pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :
-					     INT_LINK_DOWN);
-	}
-
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }