@@ -1354,6 +1354,7 @@ int pci_power_up(struct pci_dev *dev)
13541354/**
13551355 * pci_set_full_power_state - Put a PCI device into D0 and update its state
13561356 * @dev: PCI device to power up
1357+ * @locked: whether pci_bus_sem is held
13571358 *
13581359 * Call pci_power_up() to put @dev into D0, read from its PCI_PM_CTRL register
13591360 * to confirm the state change, restore its BARs if they might be lost and
@@ -1363,7 +1364,7 @@ int pci_power_up(struct pci_dev *dev)
13631364 * to D0, it is more efficient to use pci_power_up() directly instead of this
13641365 * function.
13651366 */
1366- static int pci_set_full_power_state (struct pci_dev * dev )
1367+ static int pci_set_full_power_state (struct pci_dev * dev , bool locked )
13671368{
13681369 u16 pmcsr ;
13691370 int ret ;
@@ -1399,7 +1400,7 @@ static int pci_set_full_power_state(struct pci_dev *dev)
13991400 }
14001401
14011402 if (dev -> bus -> self )
1402- pcie_aspm_pm_state_change (dev -> bus -> self );
1403+ pcie_aspm_pm_state_change (dev -> bus -> self , locked );
14031404
14041405 return 0 ;
14051406}
@@ -1428,10 +1429,22 @@ void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
14281429 pci_walk_bus (bus , __pci_dev_set_current_state , & state );
14291430}
14301431
1432+ static void __pci_bus_set_current_state (struct pci_bus * bus , pci_power_t state , bool locked )
1433+ {
1434+ if (!bus )
1435+ return ;
1436+
1437+ if (locked )
1438+ pci_walk_bus_locked (bus , __pci_dev_set_current_state , & state );
1439+ else
1440+ pci_walk_bus (bus , __pci_dev_set_current_state , & state );
1441+ }
1442+
14311443/**
14321444 * pci_set_low_power_state - Put a PCI device into a low-power state.
14331445 * @dev: PCI device to handle.
14341446 * @state: PCI power state (D1, D2, D3hot) to put the device into.
1447+ * @locked: whether pci_bus_sem is held
14351448 *
14361449 * Use the device's PCI_PM_CTRL register to put it into a low-power state.
14371450 *
@@ -1442,7 +1455,7 @@ void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
14421455 * 0 if device already is in the requested state.
14431456 * 0 if device's power state has been successfully changed.
14441457 */
1445- static int pci_set_low_power_state (struct pci_dev * dev , pci_power_t state )
1458+ static int pci_set_low_power_state (struct pci_dev * dev , pci_power_t state , bool locked )
14461459{
14471460 u16 pmcsr ;
14481461
@@ -1496,29 +1509,12 @@ static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state)
14961509 pci_power_name (state ));
14971510
14981511 if (dev -> bus -> self )
1499- pcie_aspm_pm_state_change (dev -> bus -> self );
1512+ pcie_aspm_pm_state_change (dev -> bus -> self , locked );
15001513
15011514 return 0 ;
15021515}
15031516
1504- /**
1505- * pci_set_power_state - Set the power state of a PCI device
1506- * @dev: PCI device to handle.
1507- * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
1508- *
1509- * Transition a device to a new power state, using the platform firmware and/or
1510- * the device's PCI PM registers.
1511- *
1512- * RETURN VALUE:
1513- * -EINVAL if the requested state is invalid.
1514- * -EIO if device does not support PCI PM or its PM capabilities register has a
1515- * wrong version, or device doesn't support the requested state.
1516- * 0 if the transition is to D1 or D2 but D1 and D2 are not supported.
1517- * 0 if device already is in the requested state.
1518- * 0 if the transition is to D3 but D3 is not supported.
1519- * 0 if device's power state has been successfully changed.
1520- */
1521- int pci_set_power_state (struct pci_dev * dev , pci_power_t state )
1517+ static int __pci_set_power_state (struct pci_dev * dev , pci_power_t state , bool locked )
15221518{
15231519 int error ;
15241520
@@ -1542,7 +1538,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
15421538 return 0 ;
15431539
15441540 if (state == PCI_D0 )
1545- return pci_set_full_power_state (dev );
1541+ return pci_set_full_power_state (dev , locked );
15461542
15471543 /*
15481544 * This device is quirked not to be put into D3, so don't put it in
@@ -1556,25 +1552,55 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
15561552 * To put the device in D3cold, put it into D3hot in the native
15571553 * way, then put it into D3cold using platform ops.
15581554 */
1559- error = pci_set_low_power_state (dev , PCI_D3hot );
1555+ error = pci_set_low_power_state (dev , PCI_D3hot , locked );
15601556
15611557 if (pci_platform_power_transition (dev , PCI_D3cold ))
15621558 return error ;
15631559
15641560 /* Powering off a bridge may power off the whole hierarchy */
15651561 if (dev -> current_state == PCI_D3cold )
1566- pci_bus_set_current_state (dev -> subordinate , PCI_D3cold );
1562+ __pci_bus_set_current_state (dev -> subordinate , PCI_D3cold , locked );
15671563 } else {
1568- error = pci_set_low_power_state (dev , state );
1564+ error = pci_set_low_power_state (dev , state , locked );
15691565
15701566 if (pci_platform_power_transition (dev , state ))
15711567 return error ;
15721568 }
15731569
15741570 return 0 ;
15751571}
1572+
1573+ /**
1574+ * pci_set_power_state - Set the power state of a PCI device
1575+ * @dev: PCI device to handle.
1576+ * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
1577+ *
1578+ * Transition a device to a new power state, using the platform firmware and/or
1579+ * the device's PCI PM registers.
1580+ *
1581+ * RETURN VALUE:
1582+ * -EINVAL if the requested state is invalid.
1583+ * -EIO if device does not support PCI PM or its PM capabilities register has a
1584+ * wrong version, or device doesn't support the requested state.
1585+ * 0 if the transition is to D1 or D2 but D1 and D2 are not supported.
1586+ * 0 if device already is in the requested state.
1587+ * 0 if the transition is to D3 but D3 is not supported.
1588+ * 0 if device's power state has been successfully changed.
1589+ */
1590+ int pci_set_power_state (struct pci_dev * dev , pci_power_t state )
1591+ {
1592+ return __pci_set_power_state (dev , state , false);
1593+ }
15761594EXPORT_SYMBOL (pci_set_power_state );
15771595
1596+ int pci_set_power_state_locked (struct pci_dev * dev , pci_power_t state )
1597+ {
1598+ lockdep_assert_held (& pci_bus_sem );
1599+
1600+ return __pci_set_power_state (dev , state , true);
1601+ }
1602+ EXPORT_SYMBOL (pci_set_power_state_locked );
1603+
15781604#define PCI_EXP_SAVE_REGS 7
15791605
15801606static struct pci_cap_saved_state * _pci_find_saved_cap (struct pci_dev * pci_dev ,
0 commit comments