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)
11091109 device_unlock (dev );
11101110
11111111out :
1112+ /* If enabling runtime PM for the device is blocked, unblock it. */
1113+ pm_runtime_unblock (dev );
11121114 pm_runtime_put (dev );
11131115}
11141116
@@ -1815,6 +1817,13 @@ static int device_prepare(struct device *dev, pm_message_t state)
18151817 * it again during the complete phase.
18161818 */
18171819 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 );
18181827
18191828 if (dev -> power .syscore )
18201829 return 0 ;
Original file line number Diff line number Diff line change @@ -1460,6 +1460,26 @@ int pm_runtime_barrier(struct device *dev)
14601460}
14611461EXPORT_SYMBOL_GPL (pm_runtime_barrier );
14621462
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+
14631483void __pm_runtime_disable (struct device * dev , bool check_resume )
14641484{
14651485 spin_lock_irq (& dev -> power .lock );
@@ -1518,6 +1538,10 @@ void pm_runtime_enable(struct device *dev)
15181538 if (-- dev -> power .disable_depth > 0 )
15191539 goto out ;
15201540
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+ }
15211545 dev -> power .last_status = RPM_INVALID ;
15221546 dev -> power .accounting_timestamp = ktime_get_mono_fast_ns ();
15231547
Original file line number Diff line number Diff line change @@ -597,6 +597,7 @@ enum rpm_status {
597597 RPM_RESUMING ,
598598 RPM_SUSPENDED ,
599599 RPM_SUSPENDING ,
600+ RPM_BLOCKED ,
600601};
601602
602603/*
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);
7777extern int pm_schedule_suspend (struct device * dev , unsigned int delay );
7878extern int __pm_runtime_set_status (struct device * dev , unsigned int status );
7979extern 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 );
8082extern void pm_runtime_enable (struct device * dev );
8183extern void __pm_runtime_disable (struct device * dev , bool check_resume );
8284extern void pm_runtime_allow (struct device * dev );
@@ -271,6 +273,8 @@ static inline int pm_runtime_get_if_active(struct device *dev)
271273static inline int __pm_runtime_set_status (struct device * dev ,
272274 unsigned int status ) { return 0 ; }
273275static 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 ) {}
274278static inline void pm_runtime_enable (struct device * dev ) {}
275279static inline void __pm_runtime_disable (struct device * dev , bool c ) {}
276280static inline void pm_runtime_allow (struct device * dev ) {}
You can’t perform that action at this time.
0 commit comments