Merge tag 'backlight-next-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / cpuidle / cpuidle.c
index 83af15f..ef2ea1b 100644 (file)
@@ -368,6 +368,19 @@ void cpuidle_reflect(struct cpuidle_device *dev, int index)
                cpuidle_curr_governor->reflect(dev, index);
 }
 
+/*
+ * Min polling interval of 10usec is a guess. It is assuming that
+ * for most users, the time for a single ping-pong workload like
+ * perf bench pipe would generally complete within 10usec but
+ * this is hardware dependant. Actual time can be estimated with
+ *
+ * perf bench sched pipe -l 10000
+ *
+ * Run multiple times to avoid cpufreq effects.
+ */
+#define CPUIDLE_POLL_MIN 10000
+#define CPUIDLE_POLL_MAX (TICK_NSEC / 16)
+
 /**
  * cpuidle_poll_time - return amount of time to poll for,
  * governors can override dev->poll_limit_ns if necessary
@@ -382,15 +395,23 @@ u64 cpuidle_poll_time(struct cpuidle_driver *drv,
        int i;
        u64 limit_ns;
 
+       BUILD_BUG_ON(CPUIDLE_POLL_MIN > CPUIDLE_POLL_MAX);
+
        if (dev->poll_limit_ns)
                return dev->poll_limit_ns;
 
-       limit_ns = TICK_NSEC;
+       limit_ns = CPUIDLE_POLL_MAX;
        for (i = 1; i < drv->state_count; i++) {
+               u64 state_limit;
+
                if (dev->states_usage[i].disable)
                        continue;
 
-               limit_ns = drv->states[i].target_residency_ns;
+               state_limit = drv->states[i].target_residency_ns;
+               if (state_limit < CPUIDLE_POLL_MIN)
+                       continue;
+
+               limit_ns = min_t(u64, state_limit, CPUIDLE_POLL_MAX);
                break;
        }