Cap cpu frequency to LFM during boot upon low battery detection

To reduce the maximum peak current during boot the CPU frequency is capped. In
case of low battery during boot, OS Loader will pass an additional parameter to
kernel boot command line argument as "battlow". So if the battery is detected
critically low during boot then the kernel will cap maximum scaling cpu
frequency to LFM.

Change-Id: I2d478a48439c80c14abee25f84fc5cdee908b631
Tracked-On: https://jira01.devtools.intel.com/browse/IMINAN-20518
Signed-off-by: Albin B <albin.bala.krishnan@intel.com>
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 18448a7..5b5c2ad 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -79,6 +79,7 @@
 
 static struct cpufreq_driver acpi_cpufreq_driver;
 
+static bool battlow;
 static unsigned int acpi_pstate_strict;
 static struct msr __percpu *msrs;
 
@@ -644,6 +645,8 @@
 static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	unsigned int i;
+	unsigned int freq;
+	unsigned int cpufreqidx = 0;
 	unsigned int valid_states = 0;
 	unsigned int cpu = policy->cpu;
 	struct acpi_cpufreq_data *data;
@@ -789,6 +792,7 @@
 		    perf->states[i].core_frequency * 1000;
 		valid_states++;
 	}
+	cpufreqidx = valid_states - 1;
 	data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
 	perf->state = 0;
 
@@ -833,6 +837,22 @@
 	 */
 	data->resume = 1;
 
+	/**
+	 * Capping the cpu frequency to LFM during boot, if battery is detected
+	 * as critically low.
+	 */
+	if (battlow) {
+		freq = data->freq_table[cpufreqidx].frequency;
+		if (freq != CPUFREQ_ENTRY_INVALID) {
+			pr_info("CPU%u freq is capping to %uKHz\n", cpu, freq);
+			policy->max = freq;
+		} else {
+			pr_err("CPU%u table entry %u is invalid.\n",
+					cpu, cpufreqidx);
+			goto err_freqfree;
+		}
+	}
+
 	return result;
 
 err_freqfree:
@@ -897,6 +917,18 @@
 	.set_boost      = _store_boost,
 };
 
+/**
+ * set_battlow_status - enables "battlow" to cap the max scaling cpu frequency.
+ */
+static int __init set_battlow_status(char *unused)
+{
+	pr_notice("Low Battery detected! Frequency shall be capped.\n");
+	battlow = true;
+	return 0;
+}
+/* Checking "battlow" param on boot, whether battery is critically low or not */
+early_param("battlow", set_battlow_status);
+
 static void __init acpi_cpufreq_boost_init(void)
 {
 	if (boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)) {