@@ -310,6 +310,7 @@ struct brcm_pcie {
310310 void (* bridge_sw_init_set )(struct brcm_pcie * pcie , u32 val );
311311 bool refusal_mode ;
312312 struct subdev_regulators * sr ;
313+ bool ep_wakeup_capable ;
313314};
314315
315316/*
@@ -1278,9 +1279,21 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
12781279 pcie -> bridge_sw_init_set (pcie , 1 );
12791280}
12801281
1282+ static int pci_dev_may_wakeup (struct pci_dev * dev , void * data )
1283+ {
1284+ bool * ret = data ;
1285+
1286+ if (device_may_wakeup (& dev -> dev )) {
1287+ * ret = true;
1288+ dev_info (& dev -> dev , "disable cancelled for wake-up device\n" );
1289+ }
1290+ return (int ) * ret ;
1291+ }
1292+
12811293static int brcm_pcie_suspend (struct device * dev )
12821294{
12831295 struct brcm_pcie * pcie = dev_get_drvdata (dev );
1296+ struct pci_host_bridge * bridge = pci_host_bridge_from_priv (pcie );
12841297 int ret ;
12851298
12861299 brcm_pcie_turn_off (pcie );
@@ -1299,11 +1312,22 @@ static int brcm_pcie_suspend(struct device *dev)
12991312 }
13001313
13011314 if (pcie -> sr ) {
1302- ret = regulator_bulk_disable (pcie -> sr -> num_supplies , pcie -> sr -> supplies );
1303- if (ret ) {
1304- dev_err (dev , "Could not turn off regulators\n" );
1305- reset_control_reset (pcie -> rescal );
1306- return ret ;
1315+ /*
1316+ * Now turn off the regulators, but if at least one
1317+ * downstream device is enabled as a wake-up source, do not
1318+ * turn off regulators.
1319+ */
1320+ pcie -> ep_wakeup_capable = false;
1321+ pci_walk_bus (bridge -> bus , pci_dev_may_wakeup ,
1322+ & pcie -> ep_wakeup_capable );
1323+ if (!pcie -> ep_wakeup_capable ) {
1324+ ret = regulator_bulk_disable (pcie -> sr -> num_supplies ,
1325+ pcie -> sr -> supplies );
1326+ if (ret ) {
1327+ dev_err (dev , "Could not turn off regulators\n" );
1328+ reset_control_reset (pcie -> rescal );
1329+ return ret ;
1330+ }
13071331 }
13081332 }
13091333 clk_disable_unprepare (pcie -> clk );
@@ -1324,10 +1348,21 @@ static int brcm_pcie_resume(struct device *dev)
13241348 return ret ;
13251349
13261350 if (pcie -> sr ) {
1327- ret = regulator_bulk_enable (pcie -> sr -> num_supplies , pcie -> sr -> supplies );
1328- if (ret ) {
1329- dev_err (dev , "Could not turn on regulators\n" );
1330- goto err_disable_clk ;
1351+ if (pcie -> ep_wakeup_capable ) {
1352+ /*
1353+ * We are resuming from a suspend. In the suspend we
1354+ * did not disable the power supplies, so there is
1355+ * no need to enable them (and falsely increase their
1356+ * usage count).
1357+ */
1358+ pcie -> ep_wakeup_capable = false;
1359+ } else {
1360+ ret = regulator_bulk_enable (pcie -> sr -> num_supplies ,
1361+ pcie -> sr -> supplies );
1362+ if (ret ) {
1363+ dev_err (dev , "Could not turn on regulators\n" );
1364+ goto err_disable_clk ;
1365+ }
13311366 }
13321367 }
13331368
0 commit comments