/* * platform_cpu_die: shutdown a CPU * @cpu: */ void platform_cpu_die(unsigned int cpu) { int spurious = 0; HOTPLUG_INFO("platform_cpu_die, cpu: %d\n", cpu); #ifdef CONFIG_MTK_WD_KICKER wk_stop_kick_cpu(cpu); #endif /* * we're ready for shutdown now, so do it */ cpu_enter_lowpower(cpu); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(cpu); if (spurious) HOTPLUG_INFO("platform_do_lowpower, spurious wakeup call, cpu: %d, spurious: %d\n", cpu, spurious); }
/* * platform_cpu_die: shutdown a CPU * @cpu: */ void platform_cpu_die(unsigned int cpu) { int spurious = 0; struct wd_api *wd_api = NULL; HOTPLUG_INFO("platform_cpu_die, cpu: %d\n", cpu); get_wd_api(&wd_api); if (wd_api) wd_api->wd_cpu_hot_plug_off_notify(cpu); #ifdef CONFIG_MTK_SCHED_TRACERS trace_cpu_hotplug(cpu, 0, per_cpu(last_event_ts, cpu)); per_cpu(last_event_ts, cpu) = ns2usecs(ftrace_now(cpu)); #endif /* * we're ready for shutdown now, so do it */ cpu_enter_lowpower(cpu); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(cpu); if (spurious) HOTPLUG_INFO("platform_do_lowpower, spurious wakeup call, cpu: %d, spurious: %d\n", cpu, spurious); }
/* * platform_cpu_die: shutdown a CPU * @cpu: */ void platform_cpu_die(unsigned int cpu) { int spurious = 0; struct wd_api *wd_api = NULL; HOTPLUG_INFO("platform_cpu_die, cpu: %d\n", cpu); get_wd_api(&wd_api); if (wd_api) wd_api->wd_cpu_hot_plug_off_notify(cpu); /* * we're ready for shutdown now, so do it */ cpu_enter_lowpower(cpu); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(cpu); if (spurious) HOTPLUG_INFO("platform_do_lowpower, spurious wakeup call, cpu: %d, spurious: %d\n", cpu, spurious); }
/******************************* * kernel module init function ********************************/ static int __init mt_hotplug_mechanism_init(void) { struct proc_dir_entry *entry = NULL; struct proc_dir_entry *mt_hotplug_dir = NULL; int r = 0; HOTPLUG_INFO("mt_hotplug_mechanism_init\n"); mt_hotplug_dir = proc_mkdir("mt_hotplug", NULL); if (!mt_hotplug_dir) { HOTPLUG_INFO("mkdir /proc/mt_hotplug failed\n"); } else { entry = proc_create("test0", S_IRUGO | S_IWUSR | S_IWGRP, mt_hotplug_dir, &mt_hotplug_test0_fops); entry = proc_create("test1", S_IRUGO | S_IWUSR | S_IWGRP, mt_hotplug_dir, &mt_hotplug_test1_fops); entry = proc_create("memory_debug", S_IRUGO | S_IWUSR | S_IWGRP, mt_hotplug_dir, &mt_hotplug_memory_debug_fops); } #ifdef CONFIG_HAS_EARLYSUSPEND mt_hotplug_mechanism_early_suspend_handler.suspend = mt_hotplug_mechanism_early_suspend; mt_hotplug_mechanism_early_suspend_handler.resume = mt_hotplug_mechanism_late_resume; register_early_suspend(&mt_hotplug_mechanism_early_suspend_handler); #endif //#ifdef CONFIG_HAS_EARLYSUSPEND r = platform_driver_register(&mt_hotplug_mechanism_pdrv); if (r) HOTPLUG_INFO("platform_driver_register failed (%d)\n", r); return r; }
static void mt_hotplug_mechanism_early_suspend(struct early_suspend *h) { HOTPLUG_INFO("mt_hotplug_mechanism_early_suspend"); if (g_enable) { //int i = 0; #ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG mutex_lock(&hp_onoff_mutex); hp_disable_cpu_hp(1); #endif //for (i = (num_possible_cpus() - 1); i > 0; i--) //{ // if (cpu_online(i)) // cpu_down(i); //} if (num_online_cpus() != 1) { wake_lock_timeout(&hotplug_wake_lock, FORCE_CPU_OFF_WAKE_LOCK_TIME * HZ); schedule_delayed_work_on(0, &hotplug_delayed_work, FORCE_CPU_OFF_DELAYED_WORK_TIME * HZ); } #ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG mutex_unlock(&hp_onoff_mutex); #endif } g_cur_state = STATE_ENTER_EARLY_SUSPEND; return; }
void __cpuinit mt_smp_secondary_init(unsigned int cpu) { #if 0 struct wd_api *wd_api = NULL; //fix build error get_wd_api(&wd_api); if (wd_api) wd_api->wd_cpu_hot_plug_on_notify(cpu); #endif pr_debug("Slave cpu init\n"); HOTPLUG_INFO("platform_secondary_init, cpu: %d\n", cpu); mt_gic_secondary_init(); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); #if !defined (CONFIG_ARM_PSCI) //cannot enable in secure world fiq_glue_resume(); #endif //#if !defined (CONFIG_ARM_PSCI) /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void __cpuinit platform_secondary_init(unsigned int cpu) { printk(KERN_CRIT "Slave cpu init\n"); mt_gic_secondary_init(); HOTPLUG_INFO("platform_secondary_init, cpu: %d\n", cpu); pen_release = -1; smp_wmb(); #ifdef CONFIG_LOCAL_WDT printk("[WDK]cpu %d plug on platform_secondary_init++++++\n", cpu); wk_start_kick_cpu_hotplug(cpu); mtk_wdt_restart(WK_WDT_LOC_TYPE); mtk_wdt_restart(WK_WDT_EXT_TYPE); printk("[WDK]cpu %d plug on platform_secondary_init------\n", cpu); #endif fiq_glue_resume(); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
/************************************************************** * mt hotplug mechanism control interface for procfs memory_debug ***************************************************************/ static int mt_hotplug_mechanism_read_memory_debug(struct seq_file *m, void *v) { seq_printf(m, "[0x%08x]=0x%08x\n", g_memory_debug, REG_READ(g_memory_debug)); HOTPLUG_INFO("[0x%08x]=0x%08x\n", g_memory_debug, REG_READ(g_memory_debug)); return 0; }
/************************************************************** * mt hotplug mechanism control interface for procfs test0 ***************************************************************/ static int mt_hotplug_mechanism_read_test0(struct seq_file *m, void *v) { seq_printf(m, "%d\n", g_test0); HOTPLUG_INFO("mt_hotplug_mechanism_read_test0, hotplug_cpu_count: %d\n", atomic_read(&hotplug_cpu_count)); on_each_cpu((smp_call_func_t)dump_stack, NULL, 1); /* //TODO: add dump per core last pc for debug purpose mt_reg_sync_writel(8, MP0_DBG_CTRL); pr_emerg("CPU%u, MP0_DBG_CTRL: 0x%08x, MP0_DBG_FLAG: 0x%08x\n", 0, *(volatile u32 *)(MP0_DBG_CTRL), *(volatile u32 *)(MP0_DBG_FLAG)); mt_reg_sync_writel(9, MP0_DBG_CTRL); pr_emerg("CPU%u, MP0_DBG_CTRL: 0x%08x, MP0_DBG_FLAG: 0x%08x\n", 1, *(volatile u32 *)(MP0_DBG_CTRL), *(volatile u32 *)(MP0_DBG_FLAG)); mt_reg_sync_writel(10, MP0_DBG_CTRL); pr_emerg("CPU%u, MP0_DBG_CTRL: 0x%08x, MP0_DBG_FLAG: 0x%08x\n", 2, *(volatile u32 *)(MP0_DBG_CTRL), *(volatile u32 *)(MP0_DBG_FLAG)); mt_reg_sync_writel(11, MP0_DBG_CTRL); pr_emerg("CPU%u, MP0_DBG_CTRL: 0x%08x, MP0_DBG_FLAG: 0x%08x\n", 3, *(volatile u32 *)(MP0_DBG_CTRL), *(volatile u32 *)(MP0_DBG_FLAG)); mt_reg_sync_writel(8, MP1_DBG_CTRL); pr_emerg("CPU%u, MP1_DBG_CTRL: 0x%08x, MP1_DBG_FLAG: 0x%08x\n", 4, *(volatile u32 *)(MP1_DBG_CTRL), *(volatile u32 *)(MP1_DBG_FLAG)); mt_reg_sync_writel(9, MP1_DBG_CTRL); pr_emerg("CPU%u, MP1_DBG_CTRL: 0x%08x, MP1_DBG_FLAG: 0x%08x\n", 5, *(volatile u32 *)(MP1_DBG_CTRL), *(volatile u32 *)(MP1_DBG_FLAG)); mt_reg_sync_writel(10, MP1_DBG_CTRL); pr_emerg("CPU%u, MP1_DBG_CTRL: 0x%08x, MP1_DBG_FLAG: 0x%08x\n", 6, *(volatile u32 *)(MP1_DBG_CTRL), *(volatile u32 *)(MP1_DBG_FLAG)); mt_reg_sync_writel(11, MP1_DBG_CTRL); pr_emerg("CPU%u, MP1_DBG_CTRL: 0x%08x, MP1_DBG_FLAG: 0x%08x\n", 7, *(volatile u32 *)(MP1_DBG_CTRL), *(volatile u32 *)(MP1_DBG_FLAG)); */ return 0; }
void mtk_hotplug_mechanism_thermal_protect(int limited_cpus) { int i; HOTPLUG_INFO("mtk_hotplug_mechanism_thermal_protect: %d\n", limited_cpus); if ((limited_cpus < 1 ) || (limited_cpus > g_max_cpus)) return; mutex_lock(&g_mtk_hotplug_mechanism_lock); g_limited_cpus = limited_cpus; if (g_limited_cpus == 1) { disable_hotplug_policy(true, g_limited_cpus); } else { disable_hotplug_policy(false, g_limited_cpus); } for (i = g_limited_cpus; i < g_max_cpus; ++i) cpu_down(i); mutex_unlock(&g_mtk_hotplug_mechanism_lock); }
static void mt_hotplug_mechanism_early_suspend(struct early_suspend *h) { HOTPLUG_INFO("mt_hotplug_mechanism_early_suspend"); if (g_enable) { int i = 0; mutex_lock(&hp_onoff_mutex); hp_disable_cpu_hp(1); for (i = (num_possible_cpus() - 1); i > 0; i--) { if (cpu_online(i)) cpu_down(i); } mutex_unlock(&hp_onoff_mutex); } g_cur_state = STATE_ENTER_EARLY_SUSPEND; return; }
static int mt_hotplug_mechanism_write_test1(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { int len = 0, test1 = 0; char desc[32]; len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1); if (copy_from_user(desc, buffer, len)) { return 0; } desc[len] = '\0'; if (sscanf(desc, "%d", &test1) == 1) { g_test1 = test1; switch (g_test1) { case 0: spm_mtcmos_ctrl_dbg0(STA_POWER_ON); break; case 1: spm_mtcmos_ctrl_dbg0(STA_POWER_DOWN); break; case 2: //spm_mtcmos_ctrl_dbg1(STA_POWER_ON); pr_emerg("SPM_CA7_CPU0_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU0_PWR_CON)); pr_emerg("SPM_CA7_CPU1_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU1_PWR_CON)); pr_emerg("SPM_CA7_CPU2_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU2_PWR_CON)); pr_emerg("SPM_CA7_CPU3_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU3_PWR_CON)); pr_emerg("SPM_CA7_DBG_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_DBG_PWR_CON)); pr_emerg("SPM_CA7_CPUTOP_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPUTOP_PWR_CON)); pr_emerg("SPM_CA7_CPU0_L1_PDN: 0x%08x\n", REG_READ(SPM_CA7_CPU0_L1_PDN)); pr_emerg("SPM_CA7_CPU1_L1_PDN: 0x%08x\n", REG_READ(SPM_CA7_CPU1_L1_PDN)); pr_emerg("SPM_CA7_CPU2_L1_PDN: 0x%08x\n", REG_READ(SPM_CA7_CPU2_L1_PDN)); pr_emerg("SPM_CA7_CPU3_L1_PDN: 0x%08x\n", REG_READ(SPM_CA7_CPU3_L1_PDN)); pr_emerg("SPM_CA7_CPUTOP_L2_PDN: 0x%08x\n", REG_READ(SPM_CA7_CPUTOP_L2_PDN)); pr_emerg("SPM_CA15_CPU0_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU0_PWR_CON)); pr_emerg("SPM_CA15_CPU1_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU1_PWR_CON)); pr_emerg("SPM_CA15_CPU2_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU2_PWR_CON)); pr_emerg("SPM_CA15_CPU3_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU3_PWR_CON)); pr_emerg("SPM_CA15_CPUTOP_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPUTOP_PWR_CON)); pr_emerg("SPM_CA15_L1_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_L1_PWR_CON)); pr_emerg("SPM_CA15_L2_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_L2_PWR_CON)); break; case 3: //spm_mtcmos_ctrl_dbg1(STA_POWER_DOWN); break; } return count; } else { HOTPLUG_INFO("mt_hotplug_mechanism_write_test1, bad argument\n"); } return -EINVAL; }
/******************************* * kernel module exit function ********************************/ static void __exit mt_hotplug_mechanism_exit(void) { HOTPLUG_INFO("mt_hotplug_mechanism_exit"); #ifdef CONFIG_HAS_EARLYSUSPEND cancel_delayed_work_sync(&hotplug_delayed_work); wake_lock_destroy(&hotplug_wake_lock); #endif //#ifdef CONFIG_HAS_EARLYSUSPEND }
/* * platform_cpu_disable: * @cpu: * Return error code. */ int platform_cpu_disable(unsigned int cpu) { /* * we don't allow CPU 0 to be shutdown (it is still too special * e.g. clock tick interrupts) */ HOTPLUG_INFO("platform_cpu_disable, cpu: %d\n", cpu); return cpu == 0 ? -EPERM : 0; }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; static int is_first_boot = 1; printk(KERN_CRIT "Boot slave CPU\n"); /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); HOTPLUG_INFO("boot_secondary, cpu: %d\n", cpu); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ pen_release = cpu; __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); if (is_first_boot) { mt65xx_reg_sync_writel(SLAVE_MAGIC_NUM, SLAVE_MAGIC_REG); is_first_boot = 0; } else { mt65xx_reg_sync_writel(virt_to_phys(mt_secondary_startup), BOOTROM_BOOT_ADDR); } power_on_cpu1(); smp_cross_call(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
static void mtk_hotplug_mechanism_late_resume(struct early_suspend *h) { HOTPLUG_INFO("mtk_hotplug_mechanism_late_resume"); if (g_enable) cpu_opp_mask("SCREEN_OFF", NULL, false); g_cur_state = STATE_ENTER_LATE_RESUME; return; }
static void mtk_hotplug_mechanism_early_suspend(struct early_suspend *h) { int mask[11] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; HOTPLUG_INFO("mtk_hotplug_mechanism_early_suspend"); if (g_enable) cpu_opp_mask("SCREEN_OFF", mask, true); g_cur_state = STATE_ENTER_EARLY_SUSPEND; return; }
/************************************************************** * mt hotplug mechanism control interface for procfs test0 ***************************************************************/ static int mt_hotplug_mechanism_read_test0(char *buf, char **start, off_t off, int count, int *eof, void *data) { char *p = buf; p += sprintf(p, "%d\n", g_test0); *eof = 1; HOTPLUG_INFO("mt_hotplug_mechanism_read_test0, hotplug_cpu_count: %d\n", atomic_read(&hotplug_cpu_count)); on_each_cpu((smp_call_func_t)dump_stack, NULL, 1); return p - buf; }
static void mt_hotplug_mechanism_late_resume(struct power_suspend *h) { HOTPLUG_INFO("mt_hotplug_mechanism_late_resume"); if (g_enable) { hp_disable_cpu_hp(0); } g_cur_state = STATE_ENTER_LATE_RESUME; return; }
static int mt_hotplug_mechanism_write_memory_debug(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { int len = 0; char desc[32]; char cmd1[16]; int cmd2, cmd3; len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1); if (copy_from_user(desc, buffer, len)) { return 0; } desc[len] = '\0'; if (sscanf(desc, "%s %x %x", cmd1, &cmd2, &cmd3) == 3) { if (strcmp(cmd1, "w") == 0) { HOTPLUG_INFO("write [0x%08x] to 0x%08x\n", cmd2, cmd3); REG_WRITE(cmd2, cmd3); } return count; } else if (sscanf(desc, "%s %x", cmd1, &cmd2) == 2) { if (strcmp(cmd1, "r") == 0) { HOTPLUG_INFO("read [0x%08x] as 0x%08x\n", cmd2, REG_READ(cmd2)); g_memory_debug = cmd2; } return count; } else { HOTPLUG_INFO("mt_hotplug_mechanism_write_memory_debug, bad argument\n"); } return -EINVAL; }
/******************************* * kernel module init function ********************************/ static int __init mt_hotplug_mechanism_init(void) { struct proc_dir_entry *entry = NULL; struct proc_dir_entry *mt_hotplug_dir = NULL; HOTPLUG_INFO("mt_hotplug_mechanism_init"); mt_hotplug_dir = proc_mkdir("mt_hotplug", NULL); if (!mt_hotplug_dir) { HOTPLUG_INFO("mkdir /proc/mt_hotplug failed"); } else { entry = create_proc_entry("test0", S_IRUGO | S_IWUSR, mt_hotplug_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test0; entry->write_proc = mt_hotplug_mechanism_write_test0; } entry = create_proc_entry("test1", S_IRUGO | S_IWUSR, mt_hotplug_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test1; entry->write_proc = mt_hotplug_mechanism_write_test1; } } #ifdef CONFIG_HAS_EARLYSUSPEND mt_hotplug_mechanism_early_suspend_handler.suspend = mt_hotplug_mechanism_early_suspend; mt_hotplug_mechanism_early_suspend_handler.resume = mt_hotplug_mechanism_late_resume; register_early_suspend(&mt_hotplug_mechanism_early_suspend_handler); INIT_DELAYED_WORK_DEFERRABLE(&hotplug_delayed_work, hotplug_delayed_work_handler); wake_lock_init(&hotplug_wake_lock, WAKE_LOCK_SUSPEND, "hotplug"); #endif //#ifdef CONFIG_HAS_EARLYSUSPEND return 0; }
/* * mt_cpu_kill: * @cpu: * Return TBD. */ int mt_cpu_kill(unsigned int cpu) { HOTPLUG_INFO("mt_cpu_kill, cpu: %d\n", cpu); #ifdef CONFIG_HOTPLUG_WITH_POWER_CTRL switch(cpu) { case 1: spm_mtcmos_ctrl_cpu1(STA_POWER_DOWN, 1); break; case 2: spm_mtcmos_ctrl_cpu2(STA_POWER_DOWN, 1); break; case 3: spm_mtcmos_ctrl_cpu3(STA_POWER_DOWN, 1); break; case 4: spm_mtcmos_ctrl_cpu4(STA_POWER_DOWN, 1); break; case 5: spm_mtcmos_ctrl_cpu5(STA_POWER_DOWN, 1); break; case 6: spm_mtcmos_ctrl_cpu6(STA_POWER_DOWN, 1); break; case 7: spm_mtcmos_ctrl_cpu7(STA_POWER_DOWN, 1); break; default: break; } #endif atomic_dec(&hotplug_cpu_count); #if 0 pr_emerg("SPM_CA7_CPU0_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU0_PWR_CON)); pr_emerg("SPM_CA7_CPU1_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU1_PWR_CON)); pr_emerg("SPM_CA7_CPU2_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU2_PWR_CON)); pr_emerg("SPM_CA7_CPU3_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPU3_PWR_CON)); pr_emerg("SPM_CA7_DBG_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_DBG_PWR_CON)); pr_emerg("SPM_CA7_CPUTOP_PWR_CON: 0x%08x\n", REG_READ(SPM_CA7_CPUTOP_PWR_CON)); pr_emerg("SPM_CA15_CPU0_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU0_PWR_CON)); pr_emerg("SPM_CA15_CPU1_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU1_PWR_CON)); pr_emerg("SPM_CA15_CPU2_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU2_PWR_CON)); pr_emerg("SPM_CA15_CPU3_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPU3_PWR_CON)); pr_emerg("SPM_CA15_CPUTOP_PWR_CON: 0x%08x\n", REG_READ(SPM_CA15_CPUTOP_PWR_CON)); #endif return 1; }
static int mt_hotplug_mechanism_write_test0(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { int len = 0, test0 = 0; char desc[32]; char cmd1[16]; int cmd2; len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1); if (copy_from_user(desc, buffer, len)) { return 0; } desc[len] = '\0'; if (sscanf(desc, "%s %d", cmd1, &cmd2) == 2) { if (strcmp(cmd1, "wakeup_debug") == 0) { extern int wakeup_debug; wakeup_debug = cmd2; HOTPLUG_INFO("wakeup_debug: %d\n", wakeup_debug); } return count; } else if (sscanf(desc, "%d", &test0) == 1) { g_test0 = test0; return count; } else { HOTPLUG_INFO("mt_hotplug_mechanism_write_test0, bad argument\n"); } return -EINVAL; }
/******************************* * kernel module init function ********************************/ static int __init mt_hotplug_mechanism_init(void) { struct proc_dir_entry *entry = NULL; struct proc_dir_entry *mt_hotplug_test_dir = NULL; HOTPLUG_INFO("mt_hotplug_mechanism_init"); mt_hotplug_test_dir = proc_mkdir("mt_hotplug_test", NULL); if (!mt_hotplug_test_dir) { HOTPLUG_INFO("mkdir /proc/mt_hotplug_test failed"); } else { entry = create_proc_entry("test0", S_IRUGO | S_IWUSR, mt_hotplug_test_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test0; entry->write_proc = mt_hotplug_mechanism_write_test0; } entry = create_proc_entry("test1", S_IRUGO | S_IWUSR, mt_hotplug_test_dir); if (entry) { entry->read_proc = mt_hotplug_mechanism_read_test1; entry->write_proc = mt_hotplug_mechanism_write_test1; } } #ifdef CONFIG_POWERSUSPEND mt_hotplug_mechanism_power_suspend_handler.suspend = mt_hotplug_mechanism_power_suspend; mt_hotplug_mechanism_power_suspend_handler.resume = mt_hotplug_mechanism_late_resume; register_power_suspend(&mt_hotplug_mechanism_power_suspend_handler); #endif //#ifdef CONFIG_POWERSUSPEND return 0; }
/* * platform_cpu_kill: * @cpu: * Return TBD. */ int platform_cpu_kill(unsigned int cpu) { HOTPLUG_INFO("platform_cpu_kill, cpu: %d\n", cpu); #ifdef CONFIG_HOTPLUG_WITH_POWER_CTRL if (1 == cpu) { spm_mtcmos_ctrl_cpu1(STA_POWER_DOWN, 1); } #endif atomic_dec(&hotplug_cpu_count); return 1; }
/* * static function */ static inline void cpu_enter_lowpower(unsigned int cpu) { HOTPLUG_INFO("cpu_enter_lowpower\n"); /* Cluster off */ if ((cpu == 3 && cpu_online(2) == 0) || (cpu == 2 && cpu_online(3) == 0)) { /* Clear the SCTLR C bit to prevent further data cache allocation */ __disable_dcache(); isb(); dsb(); /* Clean and invalidate all data from the L1, L2 data cache */ inner_dcache_flush_all(); /* flush_cache_all(); */ /* Switch the processor from SMP mode to AMP mode by clearing the ACTLR SMP bit */ __switch_to_amp(); isb(); dsb(); /* disable CA15 CCI */ spm_write(CA15_CCI400_DVM_EN, spm_read(CA15_CCI400_DVM_EN) & ~0x3); /* wait cci change pending */ while (spm_read(CCI400_STATUS) & 0x1) ; /* Ensure the ACP master does not send further requests to the individual processor. Assert AINACTS to idle the ACP slave interface after all responses are received. */ /* mt65xx_reg_sync_writel( *CA15_MISC_DBG | 0x11, CA15_MISC_DBG); */ spm_write(CA15_MISC_DBG, spm_read(CA15_MISC_DBG) | 0x11); } else { /* Clear the SCTLR C bit to prevent further data cache allocation */ __disable_dcache(); isb(); dsb(); /* Clean and invalidate all data from the L1 data cache */ inner_dcache_flush_L1(); /* Just flush the cache. */ /* flush_cache_all(); */ /* Execute a CLREX instruction */ __asm__ __volatile__("clrex"); /* Switch the processor from SMP mode to AMP mode by clearing the ACTLR SMP bit */ __switch_to_amp(); } }
static void hotplug_delayed_work_handler(struct work_struct *work) { int i = 0; HOTPLUG_INFO("hotplug_delayed_work_handler\n"); if (g_cur_state == STATE_ENTER_EARLY_SUSPEND) { for (i = (num_possible_cpus() - 1); i > 0; i--) { if (cpu_online(i)) cpu_down(i); } wake_unlock(&hotplug_wake_lock); } }
/******************************* * resume callback function ********************************/ static int mt_hotplug_mechanism_resume(struct platform_device *pdev) { HOTPLUG_INFO("mt_hotplug_mechanism_resume\n"); if (!g_enable) return 0; if (!g_enable_dynamic_cpu_hotplug_at_suspend) { #ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG hp_set_dynamic_cpu_hotplug_enable(g_prev_dynamic_cpu_hotplug_enable); #endif //#ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG } return 0; }
/******************************* * suspend callback function ********************************/ static int mt_hotplug_mechanism_suspend(struct platform_device *pdev, pm_message_t state) { HOTPLUG_INFO("mt_hotplug_mechanism_suspend\n"); if (!g_enable) return 0; if (!g_enable_dynamic_cpu_hotplug_at_suspend) { #ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG g_prev_dynamic_cpu_hotplug_enable = hp_get_dynamic_cpu_hotplug_enable(); hp_set_dynamic_cpu_hotplug_enable(0); #endif //#ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG } return 0; }
static void mt_hotplug_mechanism_late_resume(struct early_suspend *h) { HOTPLUG_INFO("mt_hotplug_mechanism_late_resume"); if (g_enable) { wake_unlock(&hotplug_wake_lock); cancel_delayed_work_sync(&hotplug_delayed_work); #ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG hp_disable_cpu_hp(0); #endif } g_cur_state = STATE_ENTER_LATE_RESUME; return; }