diff --git a/drivers/thermal/sunxi_budget_cooling/sunxi-budget-cooling-hotplug.c b/drivers/thermal/sunxi_budget_cooling/sunxi-budget-cooling-hotplug.c index f5974b3..77d5d9c 100755 --- a/drivers/thermal/sunxi_budget_cooling/sunxi-budget-cooling-hotplug.c +++ b/drivers/thermal/sunxi_budget_cooling/sunxi-budget-cooling-hotplug.c @@ -12,6 +12,7 @@ #include "sunxi-budget-cooling.h" static int boot_cpu; +static u32 old_cooling_state; #ifdef CONFIG_CPU_AUTOHOTPLUG_ROOMAGE extern int autohotplug_roomage_limit(unsigned int cluster_id, unsigned int min, unsigned int max); #endif @@ -24,8 +25,23 @@ static int budget_get_any_online_cpu(const cpumask_t *mask) if ((cpu != boot_cpu) && cpu_online(cpu)){ if(lastcpu == 0xffff) lastcpu = cpu; - else if(cpu >lastcpu) - lastcpu = cpu; + else if(cpu >lastcpu) + lastcpu = cpu; + } + } + return lastcpu; +} + +static int budget_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; @@ -47,7 +63,7 @@ int sunxi_hotplug_update_state(struct sunxi_budget_cooling_device *cooling_devic s32 ret = 0; u32 online = 0, i = 0, cpuid; u32 max, min; - u32 takedown; + u32 takedown, bringup = 0; u32 cooling_state = cooling_device->cooling_state; unsigned long cpuid_l, flags; struct sunxi_budget_hotplug *hotplug = cooling_device->hotplug; @@ -76,6 +92,20 @@ int sunxi_hotplug_update_state(struct sunxi_budget_cooling_device *cooling_devic takedown = (online > max)?(online - max):0; + if ((cooling_state < old_cooling_state) && (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: + bringup = (online < max)?(max - online):0; + break; + } + } + old_cooling_state = cooling_state; + while(takedown){ cpuid = budget_get_any_online_cpu(&cooling_device->cluster_cpus[cluster]); if (cpuid < nr_cpu_ids){ @@ -86,6 +116,18 @@ int sunxi_hotplug_update_state(struct sunxi_budget_cooling_device *cooling_devic takedown--; } + while (bringup) { + cpuid = budget_get_any_offline_cpu(&cooling_device->cluster_cpus[cluster]); + if (cpuid < nr_cpu_ids) { + pr_info("CPU Budget:Try to up cpu %d, cluster%d online %d, max %d\n", cpuid, cluster, online, max); + cpuid_l = cpuid; + ret = work_on_cpu(boot_cpu, (long(*)(void *))cpu_up, (void *)cpuid_l); + if (unlikely(ret)) + pr_err("CPU Budget:Failed to bring up cpu %d\n", cpuid); + } + bringup--; + } + return ret; } EXPORT_SYMBOL(sunxi_hotplug_update_state);