|
@@ -44,8 +44,8 @@ void disable_cpuidle(void)
|
|
|
off = 1;
|
|
|
}
|
|
|
|
|
|
-static bool cpuidle_not_available(struct cpuidle_driver *drv,
|
|
|
- struct cpuidle_device *dev)
|
|
|
+bool cpuidle_not_available(struct cpuidle_driver *drv,
|
|
|
+ struct cpuidle_device *dev)
|
|
|
{
|
|
|
return off || !initialized || !drv || !dev || !dev->enabled;
|
|
|
}
|
|
@@ -72,14 +72,8 @@ int cpuidle_play_dead(void)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * cpuidle_find_deepest_state - Find deepest state meeting specific conditions.
|
|
|
- * @drv: cpuidle driver for the given CPU.
|
|
|
- * @dev: cpuidle device for the given CPU.
|
|
|
- * @freeze: Whether or not the state should be suitable for suspend-to-idle.
|
|
|
- */
|
|
|
-static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
|
|
|
- struct cpuidle_device *dev, bool freeze)
|
|
|
+static int find_deepest_state(struct cpuidle_driver *drv,
|
|
|
+ struct cpuidle_device *dev, bool freeze)
|
|
|
{
|
|
|
unsigned int latency_req = 0;
|
|
|
int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1;
|
|
@@ -98,6 +92,17 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * cpuidle_find_deepest_state - Find the deepest available idle state.
|
|
|
+ * @drv: cpuidle driver for the given CPU.
|
|
|
+ * @dev: cpuidle device for the given CPU.
|
|
|
+ */
|
|
|
+int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
|
|
|
+ struct cpuidle_device *dev)
|
|
|
+{
|
|
|
+ return find_deepest_state(drv, dev, false);
|
|
|
+}
|
|
|
+
|
|
|
static void enter_freeze_proper(struct cpuidle_driver *drv,
|
|
|
struct cpuidle_device *dev, int index)
|
|
|
{
|
|
@@ -119,46 +124,26 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,
|
|
|
|
|
|
/**
|
|
|
* cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle.
|
|
|
+ * @drv: cpuidle driver for the given CPU.
|
|
|
+ * @dev: cpuidle device for the given CPU.
|
|
|
*
|
|
|
* If there are states with the ->enter_freeze callback, find the deepest of
|
|
|
- * them and enter it with frozen tick. Otherwise, find the deepest state
|
|
|
- * available and enter it normally.
|
|
|
- *
|
|
|
- * Returns with enabled interrupts.
|
|
|
+ * them and enter it with frozen tick.
|
|
|
*/
|
|
|
-void cpuidle_enter_freeze(void)
|
|
|
+int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev)
|
|
|
{
|
|
|
- struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
|
|
|
- struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
|
|
|
int index;
|
|
|
|
|
|
- if (cpuidle_not_available(drv, dev))
|
|
|
- goto fallback;
|
|
|
-
|
|
|
/*
|
|
|
* Find the deepest state with ->enter_freeze present, which guarantees
|
|
|
* that interrupts won't be enabled when it exits and allows the tick to
|
|
|
* be frozen safely.
|
|
|
*/
|
|
|
- index = cpuidle_find_deepest_state(drv, dev, true);
|
|
|
- if (index >= 0) {
|
|
|
+ index = find_deepest_state(drv, dev, true);
|
|
|
+ if (index >= 0)
|
|
|
enter_freeze_proper(drv, dev, index);
|
|
|
- local_irq_enable();
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
- /*
|
|
|
- * It is not safe to freeze the tick, find the deepest state available
|
|
|
- * at all and try to enter it normally.
|
|
|
- */
|
|
|
- index = cpuidle_find_deepest_state(drv, dev, false);
|
|
|
- if (index >= 0) {
|
|
|
- cpuidle_enter(drv, dev, index);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- fallback:
|
|
|
- arch_cpu_idle();
|
|
|
+ return index;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -217,9 +202,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
|
|
*/
|
|
|
int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
|
|
|
{
|
|
|
- if (cpuidle_not_available(drv, dev))
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
return cpuidle_curr_governor->select(drv, dev);
|
|
|
}
|
|
|
|