File tree Expand file tree Collapse file tree 4 files changed +38
-0
lines changed Expand file tree Collapse file tree 4 files changed +38
-0
lines changed Original file line number Diff line number Diff line change @@ -1109,6 +1109,8 @@ static void device_complete(struct device *dev, pm_message_t state)
1109
1109
device_unlock (dev );
1110
1110
1111
1111
out :
1112
+ /* If enabling runtime PM for the device is blocked, unblock it. */
1113
+ pm_runtime_unblock (dev );
1112
1114
pm_runtime_put (dev );
1113
1115
}
1114
1116
@@ -1815,6 +1817,13 @@ static int device_prepare(struct device *dev, pm_message_t state)
1815
1817
* it again during the complete phase.
1816
1818
*/
1817
1819
pm_runtime_get_noresume (dev );
1820
+ /*
1821
+ * If runtime PM is disabled for the device at this point and it has
1822
+ * never been enabled so far, it should not be enabled until this system
1823
+ * suspend-resume cycle is complete, so prepare to trigger a warning on
1824
+ * subsequent attempts to enable it.
1825
+ */
1826
+ pm_runtime_block_if_disabled (dev );
1818
1827
1819
1828
if (dev -> power .syscore )
1820
1829
return 0 ;
Original file line number Diff line number Diff line change @@ -1460,6 +1460,26 @@ int pm_runtime_barrier(struct device *dev)
1460
1460
}
1461
1461
EXPORT_SYMBOL_GPL (pm_runtime_barrier );
1462
1462
1463
+ void pm_runtime_block_if_disabled (struct device * dev )
1464
+ {
1465
+ spin_lock_irq (& dev -> power .lock );
1466
+
1467
+ if (dev -> power .disable_depth && dev -> power .last_status == RPM_INVALID )
1468
+ dev -> power .last_status = RPM_BLOCKED ;
1469
+
1470
+ spin_unlock_irq (& dev -> power .lock );
1471
+ }
1472
+
1473
+ void pm_runtime_unblock (struct device * dev )
1474
+ {
1475
+ spin_lock_irq (& dev -> power .lock );
1476
+
1477
+ if (dev -> power .last_status == RPM_BLOCKED )
1478
+ dev -> power .last_status = RPM_INVALID ;
1479
+
1480
+ spin_unlock_irq (& dev -> power .lock );
1481
+ }
1482
+
1463
1483
void __pm_runtime_disable (struct device * dev , bool check_resume )
1464
1484
{
1465
1485
spin_lock_irq (& dev -> power .lock );
@@ -1518,6 +1538,10 @@ void pm_runtime_enable(struct device *dev)
1518
1538
if (-- dev -> power .disable_depth > 0 )
1519
1539
goto out ;
1520
1540
1541
+ if (dev -> power .last_status == RPM_BLOCKED ) {
1542
+ dev_warn (dev , "Attempt to enable runtime PM when it is blocked\n" );
1543
+ dump_stack ();
1544
+ }
1521
1545
dev -> power .last_status = RPM_INVALID ;
1522
1546
dev -> power .accounting_timestamp = ktime_get_mono_fast_ns ();
1523
1547
Original file line number Diff line number Diff line change @@ -597,6 +597,7 @@ enum rpm_status {
597
597
RPM_RESUMING ,
598
598
RPM_SUSPENDED ,
599
599
RPM_SUSPENDING ,
600
+ RPM_BLOCKED ,
600
601
};
601
602
602
603
/*
Original file line number Diff line number Diff line change @@ -77,6 +77,8 @@ extern int pm_runtime_get_if_in_use(struct device *dev);
77
77
extern int pm_schedule_suspend (struct device * dev , unsigned int delay );
78
78
extern int __pm_runtime_set_status (struct device * dev , unsigned int status );
79
79
extern int pm_runtime_barrier (struct device * dev );
80
+ extern void pm_runtime_block_if_disabled (struct device * dev );
81
+ extern void pm_runtime_unblock (struct device * dev );
80
82
extern void pm_runtime_enable (struct device * dev );
81
83
extern void __pm_runtime_disable (struct device * dev , bool check_resume );
82
84
extern void pm_runtime_allow (struct device * dev );
@@ -271,6 +273,8 @@ static inline int pm_runtime_get_if_active(struct device *dev)
271
273
static inline int __pm_runtime_set_status (struct device * dev ,
272
274
unsigned int status ) { return 0 ; }
273
275
static inline int pm_runtime_barrier (struct device * dev ) { return 0 ; }
276
+ static inline void pm_runtime_block_if_disabled (struct device * dev ) {}
277
+ static inline void pm_runtime_unblock (struct device * dev ) {}
274
278
static inline void pm_runtime_enable (struct device * dev ) {}
275
279
static inline void __pm_runtime_disable (struct device * dev , bool c ) {}
276
280
static inline void pm_runtime_allow (struct device * dev ) {}
You can’t perform that action at this time.
0 commit comments