]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/idle/intel_idle.c
Merge tag 'efi-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / idle / intel_idle.c
index 7833e650789f815fca66db5ab786a89ceb6f4eed..d55606608ac8c30fb3b19eb6cd3c9f634fa20301 100644 (file)
@@ -63,6 +63,7 @@ static struct cpuidle_driver intel_idle_driver = {
 };
 /* intel_idle.max_cstate=0 disables driver */
 static int max_cstate = CPUIDLE_STATE_MAX - 1;
+static unsigned int disabled_states_mask;
 
 static unsigned int mwait_substates;
 
@@ -1131,6 +1132,10 @@ static bool no_acpi __read_mostly;
 module_param(no_acpi, bool, 0444);
 MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list");
 
+static bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */
+module_param_named(use_acpi, force_use_acpi, bool, 0444);
+MODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list");
+
 static struct acpi_processor_power acpi_state_table __initdata;
 
 /**
@@ -1230,6 +1235,9 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
                if (cx->type > ACPI_STATE_C2)
                        state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
 
+               if (disabled_states_mask & BIT(cstate))
+                       state->flags |= CPUIDLE_FLAG_OFF;
+
                state->enter = intel_idle;
                state->enter_s2idle = intel_idle_s2idle;
        }
@@ -1258,6 +1266,8 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
        return true;
 }
 #else /* !CONFIG_ACPI_PROCESSOR_CSTATE */
+#define force_use_acpi (false)
+
 static inline bool intel_idle_acpi_cst_extract(void) { return false; }
 static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
 static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
@@ -1460,8 +1470,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
                /* Structure copy. */
                drv->states[drv->state_count] = cpuidle_state_table[cstate];
 
-               if (icpu->use_acpi && intel_idle_off_by_default(mwait_hint) &&
-                   !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))
+               if ((disabled_states_mask & BIT(drv->state_count)) ||
+                   ((icpu->use_acpi || force_use_acpi) &&
+                    intel_idle_off_by_default(mwait_hint) &&
+                    !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
                        drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF;
 
                drv->state_count++;
@@ -1480,6 +1492,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
 static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)
 {
        cpuidle_poll_state_init(drv);
+
+       if (disabled_states_mask & BIT(0))
+               drv->states[0].flags |= CPUIDLE_FLAG_OFF;
+
        drv->state_count = 1;
 
        if (icpu)
@@ -1607,7 +1623,7 @@ static int __init intel_idle_init(void)
        icpu = (const struct idle_cpu *)id->driver_data;
        if (icpu) {
                cpuidle_state_table = icpu->state_table;
-               if (icpu->use_acpi)
+               if (icpu->use_acpi || force_use_acpi)
                        intel_idle_acpi_cst_extract();
        } else if (!intel_idle_acpi_cst_extract()) {
                return -ENODEV;
@@ -1660,3 +1676,11 @@ device_initcall(intel_idle_init);
  * is the easiest way (currently) to continue doing that.
  */
 module_param(max_cstate, int, 0444);
+/*
+ * The positions of the bits that are set in this number are the indices of the
+ * idle states to be disabled by default (as reflected by the names of the
+ * corresponding idle state directories in sysfs, "state0", "state1" ...
+ * "state<i>" ..., where <i> is the index of the given state).
+ */
+module_param_named(states_off, disabled_states_mask, uint, 0444);
+MODULE_PARM_DESC(states_off, "Mask of disabled idle states");