@@ -310,6 +310,7 @@ struct brcm_pcie {
310
310
void (* bridge_sw_init_set )(struct brcm_pcie * pcie , u32 val );
311
311
bool refusal_mode ;
312
312
struct subdev_regulators * sr ;
313
+ bool ep_wakeup_capable ;
313
314
};
314
315
315
316
/*
@@ -1278,9 +1279,21 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
1278
1279
pcie -> bridge_sw_init_set (pcie , 1 );
1279
1280
}
1280
1281
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
+
1281
1293
static int brcm_pcie_suspend (struct device * dev )
1282
1294
{
1283
1295
struct brcm_pcie * pcie = dev_get_drvdata (dev );
1296
+ struct pci_host_bridge * bridge = pci_host_bridge_from_priv (pcie );
1284
1297
int ret ;
1285
1298
1286
1299
brcm_pcie_turn_off (pcie );
@@ -1299,11 +1312,22 @@ static int brcm_pcie_suspend(struct device *dev)
1299
1312
}
1300
1313
1301
1314
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
+ }
1307
1331
}
1308
1332
}
1309
1333
clk_disable_unprepare (pcie -> clk );
@@ -1324,10 +1348,21 @@ static int brcm_pcie_resume(struct device *dev)
1324
1348
return ret ;
1325
1349
1326
1350
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
+ }
1331
1366
}
1332
1367
}
1333
1368
0 commit comments