@@ -583,7 +583,7 @@ static void pciehp_ignore_dpc_link_change(struct controller *ctrl,
583583 * the corresponding link change may have been ignored above.
584584 * Synthesize it to ensure that it is acted on.
585585 */
586- down_read (& ctrl -> reset_lock );
586+ down_read_nested (& ctrl -> reset_lock , ctrl -> depth );
587587 if (!pciehp_check_link_active (ctrl ))
588588 pciehp_request (ctrl , PCI_EXP_SLTSTA_DLLSC );
589589 up_read (& ctrl -> reset_lock );
@@ -642,6 +642,8 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
642642 */
643643 if (ctrl -> power_fault_detected )
644644 status &= ~PCI_EXP_SLTSTA_PFD ;
645+ else if (status & PCI_EXP_SLTSTA_PFD )
646+ ctrl -> power_fault_detected = true;
645647
646648 events |= status ;
647649 if (!events ) {
@@ -651,7 +653,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
651653 }
652654
653655 if (status ) {
654- pcie_capability_write_word (pdev , PCI_EXP_SLTSTA , events );
656+ pcie_capability_write_word (pdev , PCI_EXP_SLTSTA , status );
655657
656658 /*
657659 * In MSI mode, all event bits must be zero before the port
@@ -725,8 +727,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
725727 }
726728
727729 /* Check Power Fault Detected */
728- if ((events & PCI_EXP_SLTSTA_PFD ) && !ctrl -> power_fault_detected ) {
729- ctrl -> power_fault_detected = 1 ;
730+ if (events & PCI_EXP_SLTSTA_PFD ) {
730731 ctrl_err (ctrl , "Slot(%s): Power fault\n" , slot_name (ctrl ));
731732 pciehp_set_indicators (ctrl , PCI_EXP_SLTCTL_PWR_IND_OFF ,
732733 PCI_EXP_SLTCTL_ATTN_IND_ON );
@@ -746,7 +747,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
746747 * Disable requests have higher priority than Presence Detect Changed
747748 * or Data Link Layer State Changed events.
748749 */
749- down_read (& ctrl -> reset_lock );
750+ down_read_nested (& ctrl -> reset_lock , ctrl -> depth );
750751 if (events & DISABLE_SLOT )
751752 pciehp_handle_disable_request (ctrl );
752753 else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC ))
@@ -906,7 +907,7 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe)
906907 if (probe )
907908 return 0 ;
908909
909- down_write (& ctrl -> reset_lock );
910+ down_write_nested (& ctrl -> reset_lock , ctrl -> depth );
910911
911912 if (!ATTN_BUTTN (ctrl )) {
912913 ctrl_mask |= PCI_EXP_SLTCTL_PDCE ;
@@ -962,6 +963,20 @@ static inline void dbg_ctrl(struct controller *ctrl)
962963
963964#define FLAG (x , y ) (((x) & (y)) ? '+' : '-')
964965
966+ static inline int pcie_hotplug_depth (struct pci_dev * dev )
967+ {
968+ struct pci_bus * bus = dev -> bus ;
969+ int depth = 0 ;
970+
971+ while (bus -> parent ) {
972+ bus = bus -> parent ;
973+ if (bus -> self && bus -> self -> is_hotplug_bridge )
974+ depth ++ ;
975+ }
976+
977+ return depth ;
978+ }
979+
965980struct controller * pcie_init (struct pcie_device * dev )
966981{
967982 struct controller * ctrl ;
@@ -975,6 +990,7 @@ struct controller *pcie_init(struct pcie_device *dev)
975990 return NULL ;
976991
977992 ctrl -> pcie = dev ;
993+ ctrl -> depth = pcie_hotplug_depth (dev -> port );
978994 pcie_capability_read_dword (pdev , PCI_EXP_SLTCAP , & slot_cap );
979995
980996 if (pdev -> hotplug_user_indicators )
0 commit comments