For ECs that support it, the EC returns the number of slp_s0 transitions and whether or not there was a timeout in the resume response. Expose the last resume result to usermode via debugfs so that usermode can detect and report S0ix timeouts.
Unified · Split
| @@ -32,3 +32,25 @@ Description: · 31 unmodified lines | |||
| 32 | is used for synchronizing the AP host time with the EC | 32 | is used for synchronizing the AP host time with the EC |
| 33 | log. An error is returned if the command is not supported | 33 | log. An error is returned if the command is not supported |
| 34 | by the EC or there is a communication problem. | 34 | by the EC or there is a communication problem. |
| 35 | |||
| 36 | What: /sys/kernel/debug/<cros-ec-device>/last_resume_result | ||
| 37 | Date: June 2019 | ||
| 38 | KernelVersion: 5.3 | ||
| 39 | Description: | ||
| 40 | Some ECs have a feature where they will track transitions to | ||
| 41 | the (Intel) processor's SLP_S0 line, in order to detect cases | ||
| 42 | where a system failed to go into S0ix. When the system resumes, | ||
| 43 | an EC with this feature will return a summary of SLP_S0 | ||
| 44 | transitions that occurred. The last_resume_result file returns | ||
| 45 | the most recent response from the AP's resume message to the EC. | ||
| 46 | |||
| 47 | The bottom 31 bits contain a count of the number of SLP_S0 | ||
| 48 | transitions that occurred since the suspend message was | ||
| 49 | received. Bit 31 is set if the EC attempted to wake the | ||
| 50 | system due to a timeout when watching for SLP_S0 transitions. | ||
| 51 | Callers can use this to detect a wake from the EC due to | ||
| 52 | S0ix timeouts. The result will be zero if no suspend | ||
| 53 | transitions have been attempted, or the EC does not support | ||
| 54 | this feature. | ||
| 55 | |||
| 56 | Output will be in the format: "0x%08x\n". | ||
| @@ -110,12 +110,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | /* For now, report failure to transition to S0ix with a warning. */ | 111 | /* For now, report failure to transition to S0ix with a warning. */ |
| 112 | if (ret >= 0 && ec_dev->host_sleep_v1 && | 112 | if (ret >= 0 && ec_dev->host_sleep_v1 && |
| 113 | (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) | 113 | (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) { |
| 114 | ec_dev->last_resume_result = | ||
| 115 | buf.u.resp1.resume_response.sleep_transitions; | ||
| 116 | |||
| 114 | WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions & | 117 | WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions & |
| 115 | EC_HOST_RESUME_SLEEP_TIMEOUT, | 118 | EC_HOST_RESUME_SLEEP_TIMEOUT, |
| 116 | "EC detected sleep transition timeout. Total slp_s0 transitions: %d", | 119 | "EC detected sleep transition timeout. Total slp_s0 transitions: %d", |
| 117 | buf.u.resp1.resume_response.sleep_transitions & | 120 | buf.u.resp1.resume_response.sleep_transitions & |
| 118 | EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK); | 121 | EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK); |
| 122 | } | ||
| 119 | 123 | ||
| 120 | return ret; | 124 | return ret; |
| 121 | } | 125 | } |
| @@ -447,6 +447,9 @@ static int cros_ec_debugfs_probe(struct platform_device *pd) · 446 unmodified lines | |||
| 447 | debugfs_create_file("uptime", 0444, debug_info->dir, debug_info, | 447 | debugfs_create_file("uptime", 0444, debug_info->dir, debug_info, |
| 448 | &cros_ec_uptime_fops); | 448 | &cros_ec_uptime_fops); |
| 449 | 449 | ||
| 450 | debugfs_create_x32("last_resume_result", 0444, debug_info->dir, | ||
| 451 | &ec->ec_dev->last_resume_result); | ||
| 452 | |||
| 450 | ec->debug_info = debug_info; | 453 | ec->debug_info = debug_info; |
| 451 | 454 | ||
| 452 | dev_set_drvdata(&pd->dev, ec); | 455 | dev_set_drvdata(&pd->dev, ec); |
| @@ -163,6 +163,7 @@ struct cros_ec_device { · 162 unmodified lines | |||
| 163 | struct ec_response_get_next_event_v1 event_data; | 163 | struct ec_response_get_next_event_v1 event_data; |
| 164 | int event_size; | 164 | int event_size; |
| 165 | u32 host_event_wake_mask; | 165 | u32 host_event_wake_mask; |
| 166 | u32 last_resume_result; | ||
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | /** | 169 | /** |