diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index 1449b854f2d4..6f9c379353b8 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -18,6 +18,17 @@ if CPU_IDLE config CPU_IDLE_MULTIPLE_DRIVERS bool +config QGKI_CPUIDLE_FAILED_STAT + bool "Record failed attempts at entering idle states" + depends on QGKI + help + CPU idle maintains statistics for successful entry to each idle + state. It is also useful to record statistics of failure to + enter each idle state. + + Save and report the failed statistics in sysfs along with usage + statistics. + config CPU_IDLE_GOV_LADDER bool "Ladder governor (for periodic timer tick)" diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 8b113c30d507..7a7aeb2d23e5 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -291,6 +291,9 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, } } else { dev->last_residency = 0; +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + dev->states_usage[index].failed++; +#endif } return entered_state; diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index f8747322b3c7..12c1152fb1a0 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -297,6 +297,9 @@ define_show_state_function(target_residency) define_show_state_function(power_usage) define_show_state_ull_function(usage) define_show_state_ull_function(time) +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT +define_show_state_ull_function(failed) +#endif define_show_state_str_function(name) define_show_state_str_function(desc) define_show_state_ull_function(disable) @@ -310,6 +313,9 @@ define_one_state_ro(latency, show_state_exit_latency); define_one_state_ro(residency, show_state_target_residency); define_one_state_ro(power, show_state_power_usage); define_one_state_ro(usage, show_state_usage); +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT +define_one_state_ro(failed, show_state_failed); +#endif define_one_state_ro(time, show_state_time); define_one_state_rw(disable, show_state_disable, store_state_disable); define_one_state_ro(above, show_state_above); @@ -322,6 +328,9 @@ static struct attribute *cpuidle_state_default_attrs[] = { &attr_residency.attr, &attr_power.attr, &attr_usage.attr, +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + &attr_failed.attr, +#endif &attr_time.attr, &attr_disable.attr, &attr_above.attr, diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 372fa432bcad..f41780933063 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -35,6 +35,9 @@ struct cpuidle_state_usage { unsigned long long time; /* in US */ unsigned long long above; /* Number of times it's been too deep */ unsigned long long below; /* Number of times it's been too shallow */ +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + unsigned long long failed; /* Number of times it failed to enter */ +#endif #ifdef CONFIG_SUSPEND unsigned long long s2idle_usage; unsigned long long s2idle_time; /* in US */