@@ -73,6 +73,7 @@ struct acpi_power_resource {
7373 u32 system_level ;
7474 u32 order ;
7575 unsigned int ref_count ;
76+ bool wakeup_enabled ;
7677 struct mutex resource_lock ;
7778};
7879
@@ -272,11 +273,9 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
272273 return 0 ;
273274}
274275
275- static int acpi_power_on (struct acpi_power_resource * resource )
276+ static int acpi_power_on_unlocked (struct acpi_power_resource * resource )
276277{
277- int result = 0 ;;
278-
279- mutex_lock (& resource -> resource_lock );
278+ int result = 0 ;
280279
281280 if (resource -> ref_count ++ ) {
282281 ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,
@@ -293,9 +292,16 @@ static int acpi_power_on(struct acpi_power_resource *resource)
293292 schedule_work (& dep -> work );
294293 }
295294 }
295+ return result ;
296+ }
296297
297- mutex_unlock (& resource -> resource_lock );
298+ static int acpi_power_on (struct acpi_power_resource * resource )
299+ {
300+ int result ;
298301
302+ mutex_lock (& resource -> resource_lock );
303+ result = acpi_power_on_unlocked (resource );
304+ mutex_unlock (& resource -> resource_lock );
299305 return result ;
300306}
301307
@@ -313,17 +319,15 @@ static int __acpi_power_off(struct acpi_power_resource *resource)
313319 return 0 ;
314320}
315321
316- static int acpi_power_off (struct acpi_power_resource * resource )
322+ static int acpi_power_off_unlocked (struct acpi_power_resource * resource )
317323{
318324 int result = 0 ;
319325
320- mutex_lock (& resource -> resource_lock );
321-
322326 if (!resource -> ref_count ) {
323327 ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,
324328 "Power resource [%s] already off" ,
325329 resource -> name ));
326- goto unlock ;
330+ return 0 ;
327331 }
328332
329333 if (-- resource -> ref_count ) {
@@ -335,10 +339,16 @@ static int acpi_power_off(struct acpi_power_resource *resource)
335339 if (result )
336340 resource -> ref_count ++ ;
337341 }
342+ return result ;
343+ }
338344
339- unlock :
340- mutex_unlock (& resource -> resource_lock );
345+ static int acpi_power_off (struct acpi_power_resource * resource )
346+ {
347+ int result ;
341348
349+ mutex_lock (& resource -> resource_lock );
350+ result = acpi_power_off_unlocked (resource );
351+ mutex_unlock (& resource -> resource_lock );
342352 return result ;
343353}
344354
@@ -521,18 +531,35 @@ void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
521531 }
522532}
523533
524- int acpi_power_min_system_level (struct list_head * list )
534+ int acpi_power_wakeup_list_init (struct list_head * list , int * system_level_p )
525535{
526536 struct acpi_power_resource_entry * entry ;
527537 int system_level = 5 ;
528538
529539 list_for_each_entry (entry , list , node ) {
530540 struct acpi_power_resource * resource = entry -> resource ;
541+ acpi_handle handle = resource -> device .handle ;
542+ int result ;
543+ int state ;
531544
545+ mutex_lock (& resource -> resource_lock );
546+
547+ result = acpi_power_get_state (handle , & state );
548+ if (result ) {
549+ mutex_unlock (& resource -> resource_lock );
550+ return result ;
551+ }
552+ if (state == ACPI_POWER_RESOURCE_STATE_ON ) {
553+ resource -> ref_count ++ ;
554+ resource -> wakeup_enabled = true;
555+ }
532556 if (system_level > resource -> system_level )
533557 system_level = resource -> system_level ;
558+
559+ mutex_unlock (& resource -> resource_lock );
534560 }
535- return system_level ;
561+ * system_level_p = system_level ;
562+ return 0 ;
536563}
537564
538565/* --------------------------------------------------------------------------
@@ -610,6 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
610637 */
611638int acpi_enable_wakeup_device_power (struct acpi_device * dev , int sleep_state )
612639{
640+ struct acpi_power_resource_entry * entry ;
613641 int err = 0 ;
614642
615643 if (!dev || !dev -> wakeup .flags .valid )
@@ -620,17 +648,31 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
620648 if (dev -> wakeup .prepare_count ++ )
621649 goto out ;
622650
623- err = acpi_power_on_list (& dev -> wakeup .resources );
624- if (err ) {
625- dev_err (& dev -> dev , "Cannot turn wakeup power resources on\n" );
626- dev -> wakeup .flags .valid = 0 ;
627- } else {
628- /*
629- * Passing 3 as the third argument below means the device may be
630- * put into arbitrary power state afterward.
631- */
632- err = acpi_device_sleep_wake (dev , 1 , sleep_state , 3 );
651+ list_for_each_entry (entry , & dev -> wakeup .resources , node ) {
652+ struct acpi_power_resource * resource = entry -> resource ;
653+
654+ mutex_lock (& resource -> resource_lock );
655+
656+ if (!resource -> wakeup_enabled ) {
657+ err = acpi_power_on_unlocked (resource );
658+ if (!err )
659+ resource -> wakeup_enabled = true;
660+ }
661+
662+ mutex_unlock (& resource -> resource_lock );
663+
664+ if (err ) {
665+ dev_err (& dev -> dev ,
666+ "Cannot turn wakeup power resources on\n" );
667+ dev -> wakeup .flags .valid = 0 ;
668+ goto out ;
669+ }
633670 }
671+ /*
672+ * Passing 3 as the third argument below means the device may be
673+ * put into arbitrary power state afterward.
674+ */
675+ err = acpi_device_sleep_wake (dev , 1 , sleep_state , 3 );
634676 if (err )
635677 dev -> wakeup .prepare_count = 0 ;
636678
@@ -647,6 +689,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
647689 */
648690int acpi_disable_wakeup_device_power (struct acpi_device * dev )
649691{
692+ struct acpi_power_resource_entry * entry ;
650693 int err = 0 ;
651694
652695 if (!dev || !dev -> wakeup .flags .valid )
@@ -668,10 +711,25 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
668711 if (err )
669712 goto out ;
670713
671- err = acpi_power_off_list (& dev -> wakeup .resources );
672- if (err ) {
673- dev_err (& dev -> dev , "Cannot turn wakeup power resources off\n" );
674- dev -> wakeup .flags .valid = 0 ;
714+ list_for_each_entry (entry , & dev -> wakeup .resources , node ) {
715+ struct acpi_power_resource * resource = entry -> resource ;
716+
717+ mutex_lock (& resource -> resource_lock );
718+
719+ if (resource -> wakeup_enabled ) {
720+ err = acpi_power_off_unlocked (resource );
721+ if (!err )
722+ resource -> wakeup_enabled = false;
723+ }
724+
725+ mutex_unlock (& resource -> resource_lock );
726+
727+ if (err ) {
728+ dev_err (& dev -> dev ,
729+ "Cannot turn wakeup power resources off\n" );
730+ dev -> wakeup .flags .valid = 0 ;
731+ break ;
732+ }
675733 }
676734
677735 out :
0 commit comments