/* * arch/arm/mach-s5pv210/cpuidle.c * * Copyright (c) Samsung Electronics Co. Ltd * * CPU idle driver for S5PV210 * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define S5PC110_MAX_STATES 1 static void s5p_enter_idle(void) { unsigned long tmp; tmp = __raw_readl(S5P_IDLE_CFG); tmp &= ~((3<<30)|(3<<28)|(1<<0)); tmp |= ((2<<30)|(2<<28)); __raw_writel(tmp, S5P_IDLE_CFG); tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; __raw_writel(tmp, S5P_PWR_CFG); cpu_do_idle(); } /* Actual code that puts the SoC in different idle states */ static int s5p_enter_idle_normal(struct cpuidle_device *dev, struct cpuidle_state *state) { struct timeval before, after; int idle_time; local_irq_disable(); do_gettimeofday(&before); s5p_enter_idle(); do_gettimeofday(&after); local_irq_enable(); idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + (after.tv_usec - before.tv_usec); return idle_time; } static DEFINE_PER_CPU(struct cpuidle_device, s5p_cpuidle_device); static struct cpuidle_driver s5p_idle_driver = { .name = "s5p_idle", .owner = THIS_MODULE, }; /* Initialize CPU idle by registering the idle states */ static int s5p_init_cpuidle(void) { struct cpuidle_device *device; cpuidle_register_driver(&s5p_idle_driver); device = &per_cpu(s5p_cpuidle_device, smp_processor_id()); device->state_count = 1; /* Wait for interrupt state */ device->states[0].enter = s5p_enter_idle_normal; device->states[0].exit_latency = 1; /* uS */ device->states[0].target_residency = 10000; device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; strcpy(device->states[0].name, "IDLE"); strcpy(device->states[0].desc, "ARM clock gating - WFI"); if (cpuidle_register_device(device)) { printk(KERN_ERR "s5p_init_cpuidle: Failed registering\n"); return -EIO; } return 0; } device_initcall(s5p_init_cpuidle);