diff --git a/drivers/thermal/cpu_budget_cooling.c b/drivers/thermal/cpu_budget_cooling.c index 2a2aad7..c78060d 100755 --- a/drivers/thermal/cpu_budget_cooling.c +++ b/drivers/thermal/cpu_budget_cooling.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "thermal_core.h" #define CREATE_TRACE_POINTS @@ -59,6 +60,7 @@ static LIST_HEAD(cooling_cpufreq_list); static DEFINE_IDR(cpu_budget_idr); static DEFINE_MUTEX(cooling_cpu_budget_lock); static unsigned int cpu_budget_dev_count; +static int corekeeper_enabled; static struct cpu_budget_cooling_device* notify_device=NULL; /** * get_idr - function to get a unique id. @@ -124,6 +126,21 @@ static int get_any_online_cpu(const cpumask_t *mask) } return lastcpu; } +static int get_any_offline_cpu(const cpumask_t *mask) +{ + int cpu,lastcpu=0xffff; + + for_each_cpu(cpu, mask) { + if (!cpu_online(cpu)) + { + if(lastcpu == 0xffff) + lastcpu = cpu; + else if(cpu >lastcpu) + lastcpu = cpu; + } + } + return lastcpu; +} static int get_online_cpu(const cpumask_t *mask) { int cpu,num =0; @@ -151,6 +168,7 @@ EXPORT_SYMBOL(register_budget_cooling_notifier); #ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE extern int autohotplug_update_room(unsigned int c0min,unsigned int c1min,unsigned int c0max,unsigned int c1max); #endif +static int old_cooling_state = 0; int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) { int ret = 0; @@ -160,10 +178,12 @@ int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) unsigned int c0_online=0,c1_online=0; unsigned int c0_takedown=0,c1_takedown=0; unsigned int c0_max,c1_max,c0_min,c1_min; + unsigned int c0_bringup=0,c1_bringup=0; #endif struct cpumask *cluster0_cpus = &cpu_budget_device->cluster0_cpus; struct cpumask *cluster1_cpus = &cpu_budget_device->cluster1_cpus; struct cpufreq_policy policy; + int cooling_state = cpu_budget_device->cpu_budget_state; ret = 0; #ifdef CONFIG_HOTPLUG_CPU @@ -185,6 +205,22 @@ int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) c0_max:cpu_budget_device->cluster0_num_floor; c0_takedown = (c0_online > c0_max)?(c0_online - c0_max):0; c1_takedown = (c1_online > c1_max)?(c1_online - c1_max):0; +#ifdef CONFIG_ARCH_SUN8IW7 + if (corekeeper_enabled && (cooling_state < old_cooling_state) && (c0_takedown + c1_takedown == 0)) + { + /* pr_info("CPU Budget:plugging cores, old state %d, new state %d\n",old_cooling_state,cooling_state); */ + switch (cooling_state) + { + case 2: + case 1: + case 0: + c0_bringup = (c0_online < c0_max) ? c0_max - c0_online : 0; + c1_bringup = (c1_online < c1_max) ? c1_max - c1_online : 0; + break; + } + } + old_cooling_state = cooling_state; +#endif while(c1_takedown) { cpuid = get_any_online_cpu(&cpu_budget_device->cluster1_cpus); @@ -209,6 +245,26 @@ int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) } c0_takedown--; } + while(c0_bringup) + { + cpuid = get_any_offline_cpu(&cpu_budget_device->cluster0_cpus); + if (cpuid < nr_cpu_ids) + { + pr_info("CPU Budget:Try to up cpu %d, cluster0 online %d, limit %d\n",cpuid,c0_online,cpu_budget_device->cluster0_num_limit); + ret = work_on_cpu(BOOT_CPU,(long(*)(void *))cpu_up,(void *)cpuid); + } + c0_bringup--; + } + while(c1_bringup) + { + cpuid = get_any_offline_cpu(&cpu_budget_device->cluster1_cpus); + if (cpuid < nr_cpu_ids) + { + pr_info("CPU Budget:Try to up cpu %d, cluster1 online %d, limit %d\n",cpuid,c1_online,cpu_budget_device->cluster1_num_limit); + ret = work_on_cpu(BOOT_CPU,(long(*)(void *))cpu_up,(void *)cpuid); + } + c1_bringup--; + } #endif #ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE autohotplug_update_room(c0_min,c1_min,c0_max,c1_max); @@ -460,6 +516,17 @@ struct thermal_cooling_device *cpu_budget_cooling_register( int ret = 0, i; struct cpufreq_policy policy; + /* get corekeeper state */ + script_item_u val; + script_item_value_type_e type; + + type = script_get_item("corekeeper", "corekeeper_enabled", &val); + if (SCIRPT_ITEM_VALUE_TYPE_INT == type) { + corekeeper_enabled = !!val.val; + if (corekeeper_enabled) + pr_info("CPU Budget:corekeeper enabled\n"); + } + /*Verify that all the clip cpus have same freq_min, freq_max limit*/ for_each_cpu(i, cluster0_cpus) { /*continue if cpufreq policy not found and not return error*/