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 <linux/cpu.h>
 #include <linux/cpumask.h>
 #include <linux/cpu_budget_cooling.h>
+#include <mach/sys_config.h>
 #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*/