Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pm-cpuidle'

* pm-cpuidle: (51 commits)
cpuidle: add maintainer entry
ARM: s3c64xx: cpuidle: use init/exit common routine
SH: cpuidle: use init/exit common routine
cpuidle: fix comment format
ARM: imx: cpuidle: use init/exit common routine
ARM: davinci: cpuidle: use init/exit common routine
ARM: kirkwood: cpuidle: use init/exit common routine
ARM: calxeda: cpuidle: use init/exit common routine
ARM: tegra: cpuidle: use init/exit common routine for tegra3
ARM: tegra: cpuidle: use init/exit common routine for tegra2
ARM: OMAP4: cpuidle: use init/exit common routine
ARM: shmobile: cpuidle: use init/exit common routine
ARM: tegra: cpuidle: use init/exit common routine
ARM: OMAP3: cpuidle: use init/exit common routine
ARM: at91: cpuidle: use init/exit common routine
ARM: ux500: cpuidle: use init/exit common routine
cpuidle: make a single register function for all
ARM: ux500: cpuidle: replace for_each_online_cpu by for_each_possible_cpu
cpuidle: remove en_core_tk_irqen flag
ARM: OMAP3: remove cpuidle_wrap_enter
...

+362 -757
+6
Documentation/cpuidle/driver.txt
··· 15 15 cpuidle driver initializes the cpuidle_device structure for each CPU device 16 16 and registers with cpuidle using cpuidle_register_device. 17 17 18 + If all the idle states are the same, the wrapper function cpuidle_register 19 + could be used instead. 20 + 18 21 It can also support the dynamic changes (like battery <-> AC), by using 19 22 cpuidle_pause_and_lock, cpuidle_disable_device and cpuidle_enable_device, 20 23 cpuidle_resume_and_unlock. 21 24 22 25 Interfaces: 26 + extern int cpuidle_register(struct cpuidle_driver *drv, 27 + const struct cpumask *const coupled_cpus); 28 + extern int cpuidle_unregister(struct cpuidle_driver *drv); 23 29 extern int cpuidle_register_driver(struct cpuidle_driver *drv); 24 30 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 25 31 extern int cpuidle_register_device(struct cpuidle_device *dev);
+9
MAINTAINERS
··· 2206 2206 F: drivers/cpufreq/ 2207 2207 F: include/linux/cpufreq.h 2208 2208 2209 + CPUIDLE DRIVERS 2210 + M: Rafael J. Wysocki <rjw@sisk.pl> 2211 + M: Daniel Lezcano <daniel.lezcano@linaro.org> 2212 + L: linux-pm@vger.kernel.org 2213 + S: Maintained 2214 + T: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 2215 + F: drivers/cpuidle/* 2216 + F: include/linux/cpuidle.h 2217 + 2209 2218 CPUID/MSR DRIVER 2210 2219 M: "H. Peter Anvin" <hpa@zytor.com> 2211 2220 S: Maintained
-1
arch/arm/configs/kirkwood_defconfig
··· 56 56 CONFIG_ZBOOT_ROM_TEXT=0x0 57 57 CONFIG_ZBOOT_ROM_BSS=0x0 58 58 CONFIG_CPU_IDLE=y 59 - CONFIG_CPU_IDLE_KIRKWOOD=y 60 59 CONFIG_NET=y 61 60 CONFIG_PACKET=y 62 61 CONFIG_UNIX=y
+2 -16
arch/arm/mach-at91/cpuidle.c
··· 27 27 28 28 #define AT91_MAX_STATES 2 29 29 30 - static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); 31 - 32 30 /* Actual code that puts the SoC in different idle states */ 33 31 static int at91_enter_idle(struct cpuidle_device *dev, 34 32 struct cpuidle_driver *drv, ··· 45 47 static struct cpuidle_driver at91_idle_driver = { 46 48 .name = "at91_idle", 47 49 .owner = THIS_MODULE, 48 - .en_core_tk_irqen = 1, 49 50 .states[0] = ARM_CPUIDLE_WFI_STATE, 50 51 .states[1] = { 51 52 .enter = at91_enter_idle, ··· 58 61 }; 59 62 60 63 /* Initialize CPU idle by registering the idle states */ 61 - static int at91_init_cpuidle(void) 64 + static int __init at91_init_cpuidle(void) 62 65 { 63 - struct cpuidle_device *device; 64 - 65 - device = &per_cpu(at91_cpuidle_device, smp_processor_id()); 66 - device->state_count = AT91_MAX_STATES; 67 - 68 - cpuidle_register_driver(&at91_idle_driver); 69 - 70 - if (cpuidle_register_device(device)) { 71 - printk(KERN_ERR "at91_init_cpuidle: Failed registering\n"); 72 - return -EIO; 73 - } 74 - return 0; 66 + return cpuidle_register(&at91_idle_driver, NULL); 75 67 } 76 68 77 69 device_initcall(at91_init_cpuidle);
+3 -26
arch/arm/mach-davinci/cpuidle.c
··· 25 25 26 26 #define DAVINCI_CPUIDLE_MAX_STATES 2 27 27 28 - static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); 29 28 static void __iomem *ddr2_reg_base; 30 29 static bool ddr2_pdown; 31 30 ··· 49 50 50 51 /* Actual code that puts the SoC in different idle states */ 51 52 static int davinci_enter_idle(struct cpuidle_device *dev, 52 - struct cpuidle_driver *drv, 53 - int index) 53 + struct cpuidle_driver *drv, int index) 54 54 { 55 55 davinci_save_ddr_power(1, ddr2_pdown); 56 - 57 - index = cpuidle_wrap_enter(dev, drv, index, 58 - arm_cpuidle_simple_enter); 59 - 56 + cpu_do_idle(); 60 57 davinci_save_ddr_power(0, ddr2_pdown); 61 58 62 59 return index; ··· 61 66 static struct cpuidle_driver davinci_idle_driver = { 62 67 .name = "cpuidle-davinci", 63 68 .owner = THIS_MODULE, 64 - .en_core_tk_irqen = 1, 65 69 .states[0] = ARM_CPUIDLE_WFI_STATE, 66 70 .states[1] = { 67 71 .enter = davinci_enter_idle, ··· 75 81 76 82 static int __init davinci_cpuidle_probe(struct platform_device *pdev) 77 83 { 78 - int ret; 79 - struct cpuidle_device *device; 80 84 struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; 81 - 82 - device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); 83 85 84 86 if (!pdata) { 85 87 dev_err(&pdev->dev, "cannot get platform data\n"); ··· 86 96 87 97 ddr2_pdown = pdata->ddr2_pdown; 88 98 89 - ret = cpuidle_register_driver(&davinci_idle_driver); 90 - if (ret) { 91 - dev_err(&pdev->dev, "failed to register driver\n"); 92 - return ret; 93 - } 94 - 95 - ret = cpuidle_register_device(device); 96 - if (ret) { 97 - dev_err(&pdev->dev, "failed to register device\n"); 98 - cpuidle_unregister_driver(&davinci_idle_driver); 99 - return ret; 100 - } 101 - 102 - return 0; 99 + return cpuidle_register(&davinci_idle_driver, NULL); 103 100 } 104 101 105 102 static struct platform_driver davinci_cpuidle_driver = {
-1
arch/arm/mach-exynos/cpuidle.c
··· 58 58 static struct cpuidle_driver exynos4_idle_driver = { 59 59 .name = "exynos4_idle", 60 60 .owner = THIS_MODULE, 61 - .en_core_tk_irqen = 1, 62 61 }; 63 62 64 63 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
+1 -1
arch/arm/mach-imx/Makefile
··· 30 30 obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 31 31 32 32 ifeq ($(CONFIG_CPU_IDLE),y) 33 - obj-y += cpuidle.o 33 + obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o 34 34 obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o 35 35 endif 36 36
+37
arch/arm/mach-imx/cpuidle-imx5.c
··· 1 + /* 2 + * Copyright (C) 2012 Freescale Semiconductor, Inc. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/cpuidle.h> 10 + #include <linux/module.h> 11 + #include <asm/system_misc.h> 12 + 13 + static int imx5_cpuidle_enter(struct cpuidle_device *dev, 14 + struct cpuidle_driver *drv, int index) 15 + { 16 + arm_pm_idle(); 17 + return index; 18 + } 19 + 20 + static struct cpuidle_driver imx5_cpuidle_driver = { 21 + .name = "imx5_cpuidle", 22 + .owner = THIS_MODULE, 23 + .states[0] = { 24 + .enter = imx5_cpuidle_enter, 25 + .exit_latency = 2, 26 + .target_residency = 1, 27 + .flags = CPUIDLE_FLAG_TIME_VALID, 28 + .name = "IMX5 SRPG", 29 + .desc = "CPU state retained,powered off", 30 + }, 31 + .state_count = 1, 32 + }; 33 + 34 + int __init imx5_cpuidle_init(void) 35 + { 36 + return cpuidle_register(&imx5_cpuidle_driver, NULL); 37 + }
+3 -23
arch/arm/mach-imx/cpuidle-imx6q.c
··· 6 6 * published by the Free Software Foundation. 7 7 */ 8 8 9 - #include <linux/clockchips.h> 10 9 #include <linux/cpuidle.h> 11 10 #include <linux/module.h> 12 11 #include <asm/cpuidle.h> ··· 20 21 static int imx6q_enter_wait(struct cpuidle_device *dev, 21 22 struct cpuidle_driver *drv, int index) 22 23 { 23 - int cpu = dev->cpu; 24 - 25 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); 26 - 27 24 if (atomic_inc_return(&master) == num_online_cpus()) { 28 25 /* 29 26 * With this lock, we prevent other cpu to exit and enter ··· 38 43 cpu_do_idle(); 39 44 done: 40 45 atomic_dec(&master); 41 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); 42 46 43 47 return index; 44 - } 45 - 46 - /* 47 - * For each cpu, setup the broadcast timer because local timer 48 - * stops for the states other than WFI. 49 - */ 50 - static void imx6q_setup_broadcast_timer(void *arg) 51 - { 52 - int cpu = smp_processor_id(); 53 - 54 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); 55 48 } 56 49 57 50 static struct cpuidle_driver imx6q_cpuidle_driver = { 58 51 .name = "imx6q_cpuidle", 59 52 .owner = THIS_MODULE, 60 - .en_core_tk_irqen = 1, 61 53 .states = { 62 54 /* WFI */ 63 55 ARM_CPUIDLE_WFI_STATE, ··· 52 70 { 53 71 .exit_latency = 50, 54 72 .target_residency = 75, 55 - .flags = CPUIDLE_FLAG_TIME_VALID, 73 + .flags = CPUIDLE_FLAG_TIME_VALID | 74 + CPUIDLE_FLAG_TIMER_STOP, 56 75 .enter = imx6q_enter_wait, 57 76 .name = "WAIT", 58 77 .desc = "Clock off", ··· 71 88 /* Set chicken bit to get a reliable WAIT mode support */ 72 89 imx6q_set_chicken_bit(); 73 90 74 - /* Configure the broadcast timer on each cpu */ 75 - on_each_cpu(imx6q_setup_broadcast_timer, NULL, 1); 76 - 77 - return imx_cpuidle_init(&imx6q_cpuidle_driver); 91 + return cpuidle_register(&imx6q_cpuidle_driver, NULL); 78 92 }
-80
arch/arm/mach-imx/cpuidle.c
··· 1 - /* 2 - * Copyright 2012 Freescale Semiconductor, Inc. 3 - * Copyright 2012 Linaro Ltd. 4 - * 5 - * The code contained herein is licensed under the GNU General Public 6 - * License. You may obtain a copy of the GNU General Public License 7 - * Version 2 or later at the following locations: 8 - * 9 - * http://www.opensource.org/licenses/gpl-license.html 10 - * http://www.gnu.org/copyleft/gpl.html 11 - */ 12 - 13 - #include <linux/cpuidle.h> 14 - #include <linux/err.h> 15 - #include <linux/hrtimer.h> 16 - #include <linux/io.h> 17 - #include <linux/kernel.h> 18 - #include <linux/slab.h> 19 - 20 - static struct cpuidle_device __percpu * imx_cpuidle_devices; 21 - 22 - static void __init imx_cpuidle_devices_uninit(void) 23 - { 24 - int cpu_id; 25 - struct cpuidle_device *dev; 26 - 27 - for_each_possible_cpu(cpu_id) { 28 - dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); 29 - cpuidle_unregister_device(dev); 30 - } 31 - 32 - free_percpu(imx_cpuidle_devices); 33 - } 34 - 35 - int __init imx_cpuidle_init(struct cpuidle_driver *drv) 36 - { 37 - struct cpuidle_device *dev; 38 - int cpu_id, ret; 39 - 40 - if (drv->state_count > CPUIDLE_STATE_MAX) { 41 - pr_err("%s: state_count exceeds maximum\n", __func__); 42 - return -EINVAL; 43 - } 44 - 45 - ret = cpuidle_register_driver(drv); 46 - if (ret) { 47 - pr_err("%s: Failed to register cpuidle driver with error: %d\n", 48 - __func__, ret); 49 - return ret; 50 - } 51 - 52 - imx_cpuidle_devices = alloc_percpu(struct cpuidle_device); 53 - if (imx_cpuidle_devices == NULL) { 54 - ret = -ENOMEM; 55 - goto unregister_drv; 56 - } 57 - 58 - /* initialize state data for each cpuidle_device */ 59 - for_each_possible_cpu(cpu_id) { 60 - dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); 61 - dev->cpu = cpu_id; 62 - dev->state_count = drv->state_count; 63 - 64 - ret = cpuidle_register_device(dev); 65 - if (ret) { 66 - pr_err("%s: Failed to register cpu %u, error: %d\n", 67 - __func__, cpu_id, ret); 68 - goto uninit; 69 - } 70 - } 71 - 72 - return 0; 73 - 74 - uninit: 75 - imx_cpuidle_devices_uninit(); 76 - 77 - unregister_drv: 78 - cpuidle_unregister_driver(drv); 79 - return ret; 80 - }
+4 -6
arch/arm/mach-imx/cpuidle.h
··· 10 10 * http://www.gnu.org/copyleft/gpl.html 11 11 */ 12 12 13 - #include <linux/cpuidle.h> 14 - 15 13 #ifdef CONFIG_CPU_IDLE 16 - extern int imx_cpuidle_init(struct cpuidle_driver *drv); 14 + extern int imx5_cpuidle_init(void); 17 15 extern int imx6q_cpuidle_init(void); 18 16 #else 19 - static inline int imx_cpuidle_init(struct cpuidle_driver *drv) 17 + static inline int imx5_cpuidle_init(void) 20 18 { 21 - return -ENODEV; 19 + return 0; 22 20 } 23 21 static inline int imx6q_cpuidle_init(void) 24 22 { 25 - return -ENODEV; 23 + return 0; 26 24 } 27 25 #endif
+1 -29
arch/arm/mach-imx/pm-imx5.c
··· 149 149 imx5_cpu_do_idle(); 150 150 } 151 151 152 - static int imx5_cpuidle_enter(struct cpuidle_device *dev, 153 - struct cpuidle_driver *drv, int idx) 154 - { 155 - int ret; 156 - 157 - ret = imx5_cpu_do_idle(); 158 - if (ret < 0) 159 - return ret; 160 - 161 - return idx; 162 - } 163 - 164 - static struct cpuidle_driver imx5_cpuidle_driver = { 165 - .name = "imx5_cpuidle", 166 - .owner = THIS_MODULE, 167 - .en_core_tk_irqen = 1, 168 - .states[0] = { 169 - .enter = imx5_cpuidle_enter, 170 - .exit_latency = 2, 171 - .target_residency = 1, 172 - .flags = CPUIDLE_FLAG_TIME_VALID, 173 - .name = "IMX5 SRPG", 174 - .desc = "CPU state retained,powered off", 175 - }, 176 - .state_count = 1, 177 - }; 178 - 179 152 static int __init imx5_pm_common_init(void) 180 153 { 181 154 int ret; ··· 166 193 /* Set the registers to the default cpu idle state. */ 167 194 mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); 168 195 169 - imx_cpuidle_init(&imx5_cpuidle_driver); 170 - return 0; 196 + return imx5_cpuidle_init(); 171 197 } 172 198 173 199 void __init imx51_pm_init(void)
-5
arch/arm/mach-omap2/common.h
··· 249 249 extern int omap4_finish_suspend(unsigned long cpu_state); 250 250 extern void omap4_cpu_resume(void); 251 251 extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); 252 - extern u32 omap4_mpuss_read_prev_context_state(void); 253 252 #else 254 253 static inline int omap4_enter_lowpower(unsigned int cpu, 255 254 unsigned int power_state) ··· 276 277 static inline void omap4_cpu_resume(void) 277 278 {} 278 279 279 - static inline u32 omap4_mpuss_read_prev_context_state(void) 280 - { 281 - return 0; 282 - } 283 280 #endif 284 281 285 282 struct omap_sdrc_params;
+13 -39
arch/arm/mach-omap2/cpuidle34xx.c
··· 26 26 #include <linux/cpuidle.h> 27 27 #include <linux/export.h> 28 28 #include <linux/cpu_pm.h> 29 + #include <asm/cpuidle.h> 29 30 30 31 #include "powerdomain.h" 31 32 #include "clockdomain.h" ··· 100 99 }, 101 100 }; 102 101 103 - /* Private functions */ 104 - 105 - static int __omap3_enter_idle(struct cpuidle_device *dev, 106 - struct cpuidle_driver *drv, 107 - int index) 102 + /** 103 + * omap3_enter_idle - Programs OMAP3 to enter the specified state 104 + * @dev: cpuidle device 105 + * @drv: cpuidle driver 106 + * @index: the index of state to be entered 107 + */ 108 + static int omap3_enter_idle(struct cpuidle_device *dev, 109 + struct cpuidle_driver *drv, 110 + int index) 108 111 { 109 112 struct omap3_idle_statedata *cx = &omap3_idle_data[index]; 110 113 ··· 151 146 local_fiq_enable(); 152 147 153 148 return index; 154 - } 155 - 156 - /** 157 - * omap3_enter_idle - Programs OMAP3 to enter the specified state 158 - * @dev: cpuidle device 159 - * @drv: cpuidle driver 160 - * @index: the index of state to be entered 161 - * 162 - * Called from the CPUidle framework to program the device to the 163 - * specified target state selected by the governor. 164 - */ 165 - static inline int omap3_enter_idle(struct cpuidle_device *dev, 166 - struct cpuidle_driver *drv, 167 - int index) 168 - { 169 - return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle); 170 149 } 171 150 172 151 /** ··· 260 271 return ret; 261 272 } 262 273 263 - static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 264 - 265 274 static struct cpuidle_driver omap3_idle_driver = { 266 - .name = "omap3_idle", 267 - .owner = THIS_MODULE, 275 + .name = "omap3_idle", 276 + .owner = THIS_MODULE, 268 277 .states = { 269 278 { 270 279 .enter = omap3_enter_idle_bm, ··· 335 348 */ 336 349 int __init omap3_idle_init(void) 337 350 { 338 - struct cpuidle_device *dev; 339 - 340 351 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 341 352 core_pd = pwrdm_lookup("core_pwrdm"); 342 353 per_pd = pwrdm_lookup("per_pwrdm"); ··· 343 358 if (!mpu_pd || !core_pd || !per_pd || !cam_pd) 344 359 return -ENODEV; 345 360 346 - cpuidle_register_driver(&omap3_idle_driver); 347 - 348 - dev = &per_cpu(omap3_idle_dev, smp_processor_id()); 349 - dev->cpu = 0; 350 - 351 - if (cpuidle_register_device(dev)) { 352 - printk(KERN_ERR "%s: CPUidle register device failed\n", 353 - __func__); 354 - return -EIO; 355 - } 356 - 357 - return 0; 361 + return cpuidle_register(&omap3_idle_driver, NULL); 358 362 }
+25 -59
arch/arm/mach-omap2/cpuidle44xx.c
··· 1 1 /* 2 - * OMAP4 CPU idle Routines 2 + * OMAP4+ CPU idle Routines 3 3 * 4 - * Copyright (C) 2011 Texas Instruments, Inc. 4 + * Copyright (C) 2011-2013 Texas Instruments, Inc. 5 5 * Santosh Shilimkar <santosh.shilimkar@ti.com> 6 6 * Rajendra Nayak <rnayak@ti.com> 7 7 * ··· 14 14 #include <linux/cpuidle.h> 15 15 #include <linux/cpu_pm.h> 16 16 #include <linux/export.h> 17 - #include <linux/clockchips.h> 18 17 18 + #include <asm/cpuidle.h> 19 19 #include <asm/proc-fns.h> 20 20 21 21 #include "common.h" ··· 24 24 #include "clockdomain.h" 25 25 26 26 /* Machine specific information */ 27 - struct omap4_idle_statedata { 27 + struct idle_statedata { 28 28 u32 cpu_state; 29 29 u32 mpu_logic_state; 30 30 u32 mpu_state; 31 31 }; 32 32 33 - static struct omap4_idle_statedata omap4_idle_data[] = { 33 + static struct idle_statedata omap4_idle_data[] = { 34 34 { 35 35 .cpu_state = PWRDM_POWER_ON, 36 36 .mpu_state = PWRDM_POWER_ON, ··· 53 53 54 54 static atomic_t abort_barrier; 55 55 static bool cpu_done[NR_CPUS]; 56 + static struct idle_statedata *state_ptr = &omap4_idle_data[0]; 56 57 57 58 /* Private functions */ 58 59 59 60 /** 60 - * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions 61 + * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions 61 62 * @dev: cpuidle device 62 63 * @drv: cpuidle driver 63 64 * @index: the index of state to be entered ··· 67 66 * specified low power state selected by the governor. 68 67 * Returns the amount of time spent in the low power state. 69 68 */ 70 - static int omap4_enter_idle_simple(struct cpuidle_device *dev, 69 + static int omap_enter_idle_simple(struct cpuidle_device *dev, 71 70 struct cpuidle_driver *drv, 72 71 int index) 73 72 { ··· 78 77 return index; 79 78 } 80 79 81 - static int omap4_enter_idle_coupled(struct cpuidle_device *dev, 80 + static int omap_enter_idle_coupled(struct cpuidle_device *dev, 82 81 struct cpuidle_driver *drv, 83 82 int index) 84 83 { 85 - struct omap4_idle_statedata *cx = &omap4_idle_data[index]; 86 - int cpu_id = smp_processor_id(); 84 + struct idle_statedata *cx = state_ptr + index; 87 85 88 86 local_fiq_disable(); 89 87 ··· 108 108 109 109 } 110 110 } 111 - 112 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); 113 111 114 112 /* 115 113 * Call idle CPU PM enter notifier chain so that ··· 147 149 * Call idle CPU cluster PM exit notifier chain 148 150 * to restore GIC and wakeupgen context. 149 151 */ 150 - if (omap4_mpuss_read_prev_context_state()) 152 + if ((cx->mpu_state == PWRDM_POWER_RET) && 153 + (cx->mpu_logic_state == PWRDM_POWER_OFF)) 151 154 cpu_cluster_pm_exit(); 152 - 153 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); 154 155 155 156 fail: 156 157 cpuidle_coupled_parallel_barrier(dev, &abort_barrier); ··· 160 163 return index; 161 164 } 162 165 163 - /* 164 - * For each cpu, setup the broadcast timer because local timers 165 - * stops for the states above C1. 166 - */ 167 - static void omap_setup_broadcast_timer(void *arg) 168 - { 169 - int cpu = smp_processor_id(); 170 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); 171 - } 172 - 173 - static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); 174 - 175 166 static struct cpuidle_driver omap4_idle_driver = { 176 167 .name = "omap4_idle", 177 168 .owner = THIS_MODULE, 178 - .en_core_tk_irqen = 1, 179 169 .states = { 180 170 { 181 171 /* C1 - CPU0 ON + CPU1 ON + MPU ON */ 182 172 .exit_latency = 2 + 2, 183 173 .target_residency = 5, 184 174 .flags = CPUIDLE_FLAG_TIME_VALID, 185 - .enter = omap4_enter_idle_simple, 175 + .enter = omap_enter_idle_simple, 186 176 .name = "C1", 187 - .desc = "MPUSS ON" 177 + .desc = "CPUx ON, MPUSS ON" 188 178 }, 189 179 { 190 180 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ 191 181 .exit_latency = 328 + 440, 192 182 .target_residency = 960, 193 - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, 194 - .enter = omap4_enter_idle_coupled, 183 + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | 184 + CPUIDLE_FLAG_TIMER_STOP, 185 + .enter = omap_enter_idle_coupled, 195 186 .name = "C2", 196 - .desc = "MPUSS CSWR", 187 + .desc = "CPUx OFF, MPUSS CSWR", 197 188 }, 198 189 { 199 190 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ 200 191 .exit_latency = 460 + 518, 201 192 .target_residency = 1100, 202 - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, 203 - .enter = omap4_enter_idle_coupled, 193 + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | 194 + CPUIDLE_FLAG_TIMER_STOP, 195 + .enter = omap_enter_idle_coupled, 204 196 .name = "C3", 205 - .desc = "MPUSS OSWR", 197 + .desc = "CPUx OFF, MPUSS OSWR", 206 198 }, 207 199 }, 208 200 .state_count = ARRAY_SIZE(omap4_idle_data), ··· 201 215 /* Public functions */ 202 216 203 217 /** 204 - * omap4_idle_init - Init routine for OMAP4 idle 218 + * omap4_idle_init - Init routine for OMAP4+ idle 205 219 * 206 - * Registers the OMAP4 specific cpuidle driver to the cpuidle 220 + * Registers the OMAP4+ specific cpuidle driver to the cpuidle 207 221 * framework with the valid set of states. 208 222 */ 209 223 int __init omap4_idle_init(void) 210 224 { 211 - struct cpuidle_device *dev; 212 - unsigned int cpu_id = 0; 213 - 214 225 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 215 226 cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); 216 227 cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); ··· 219 236 if (!cpu_clkdm[0] || !cpu_clkdm[1]) 220 237 return -ENODEV; 221 238 222 - /* Configure the broadcast timer on each cpu */ 223 - on_each_cpu(omap_setup_broadcast_timer, NULL, 1); 224 - 225 - for_each_cpu(cpu_id, cpu_online_mask) { 226 - dev = &per_cpu(omap4_idle_dev, cpu_id); 227 - dev->cpu = cpu_id; 228 - #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 229 - dev->coupled_cpus = *cpu_online_mask; 230 - #endif 231 - cpuidle_register_driver(&omap4_idle_driver); 232 - 233 - if (cpuidle_register_device(dev)) { 234 - pr_err("%s: CPUidle register failed\n", __func__); 235 - return -EIO; 236 - } 237 - } 238 - 239 - return 0; 239 + return cpuidle_register(&omap4_idle_driver, cpu_online_mask); 240 240 }
-14
arch/arm/mach-omap2/omap-mpuss-lowpower.c
··· 139 139 } 140 140 } 141 141 142 - /** 143 - * omap4_mpuss_read_prev_context_state: 144 - * Function returns the MPUSS previous context state 145 - */ 146 - u32 omap4_mpuss_read_prev_context_state(void) 147 - { 148 - u32 reg; 149 - 150 - reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, 151 - OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); 152 - reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; 153 - return reg; 154 - } 155 - 156 142 /* 157 143 * Store the CPU cluster state for L2X0 low power operations. 158 144 */
+1 -14
arch/arm/mach-s3c64xx/cpuidle.c
··· 40 40 return index; 41 41 } 42 42 43 - static DEFINE_PER_CPU(struct cpuidle_device, s3c64xx_cpuidle_device); 44 - 45 43 static struct cpuidle_driver s3c64xx_cpuidle_driver = { 46 44 .name = "s3c64xx_cpuidle", 47 45 .owner = THIS_MODULE, 48 - .en_core_tk_irqen = 1, 49 46 .states = { 50 47 { 51 48 .enter = s3c64xx_enter_idle, ··· 58 61 59 62 static int __init s3c64xx_init_cpuidle(void) 60 63 { 61 - int ret; 62 - 63 - cpuidle_register_driver(&s3c64xx_cpuidle_driver); 64 - 65 - ret = cpuidle_register_device(&s3c64xx_cpuidle_device); 66 - if (ret) { 67 - pr_err("Failed to register cpuidle device: %d\n", ret); 68 - return ret; 69 - } 70 - 71 - return 0; 64 + return cpuidle_register(&s3c64xx_cpuidle_driver, NULL); 72 65 } 73 66 device_initcall(s3c64xx_init_cpuidle);
+3 -20
arch/arm/mach-shmobile/cpuidle.c
··· 16 16 #include <asm/cpuidle.h> 17 17 #include <asm/io.h> 18 18 19 - int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv, 20 - int index) 21 - { 22 - cpu_do_idle(); 23 - return 0; 24 - } 25 - 26 - static struct cpuidle_device shmobile_cpuidle_dev; 27 19 static struct cpuidle_driver shmobile_cpuidle_default_driver = { 28 20 .name = "shmobile_cpuidle", 29 21 .owner = THIS_MODULE, 30 - .en_core_tk_irqen = 1, 31 22 .states[0] = ARM_CPUIDLE_WFI_STATE, 32 - .states[0].enter = shmobile_enter_wfi, 33 23 .safe_state_index = 0, /* C1 */ 34 24 .state_count = 1, 35 25 }; 36 26 37 27 static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver; 38 28 39 - void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv) 29 + void __init shmobile_cpuidle_set_driver(struct cpuidle_driver *drv) 40 30 { 41 31 cpuidle_drv = drv; 42 32 } 43 33 44 - int shmobile_cpuidle_init(void) 34 + int __init shmobile_cpuidle_init(void) 45 35 { 46 - struct cpuidle_device *dev = &shmobile_cpuidle_dev; 47 - 48 - cpuidle_register_driver(cpuidle_drv); 49 - 50 - dev->state_count = cpuidle_drv->state_count; 51 - cpuidle_register_device(dev); 52 - 53 - return 0; 36 + return cpuidle_register(cpuidle_drv, NULL); 54 37 }
-3
arch/arm/mach-shmobile/include/mach/common.h
··· 13 13 extern void shmobile_handle_irq_intc(struct pt_regs *); 14 14 extern struct platform_suspend_ops shmobile_suspend_ops; 15 15 struct cpuidle_driver; 16 - struct cpuidle_device; 17 - extern int shmobile_enter_wfi(struct cpuidle_device *dev, 18 - struct cpuidle_driver *drv, int index); 19 16 extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv); 20 17 21 18 extern void sh7372_init_irq(void);
+2 -4
arch/arm/mach-shmobile/pm-sh7372.c
··· 410 410 static struct cpuidle_driver sh7372_cpuidle_driver = { 411 411 .name = "sh7372_cpuidle", 412 412 .owner = THIS_MODULE, 413 - .en_core_tk_irqen = 1, 414 413 .state_count = 5, 415 414 .safe_state_index = 0, /* C1 */ 416 415 .states[0] = ARM_CPUIDLE_WFI_STATE, 417 - .states[0].enter = shmobile_enter_wfi, 418 416 .states[1] = { 419 417 .name = "C2", 420 418 .desc = "Core Standby Mode", ··· 448 450 }, 449 451 }; 450 452 451 - static void sh7372_cpuidle_init(void) 453 + static void __init sh7372_cpuidle_init(void) 452 454 { 453 455 shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver); 454 456 } 455 457 #else 456 - static void sh7372_cpuidle_init(void) {} 458 + static void __init sh7372_cpuidle_init(void) {} 457 459 #endif 458 460 459 461 #ifdef CONFIG_SUSPEND
+1 -27
arch/arm/mach-tegra/cpuidle-tegra114.c
··· 23 23 static struct cpuidle_driver tegra_idle_driver = { 24 24 .name = "tegra_idle", 25 25 .owner = THIS_MODULE, 26 - .en_core_tk_irqen = 1, 27 26 .state_count = 1, 28 27 .states = { 29 28 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), 30 29 }, 31 30 }; 32 31 33 - static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); 34 - 35 32 int __init tegra114_cpuidle_init(void) 36 33 { 37 - int ret; 38 - unsigned int cpu; 39 - struct cpuidle_device *dev; 40 - struct cpuidle_driver *drv = &tegra_idle_driver; 41 - 42 - ret = cpuidle_register_driver(&tegra_idle_driver); 43 - if (ret) { 44 - pr_err("CPUidle driver registration failed\n"); 45 - return ret; 46 - } 47 - 48 - for_each_possible_cpu(cpu) { 49 - dev = &per_cpu(tegra_idle_device, cpu); 50 - dev->cpu = cpu; 51 - 52 - dev->state_count = drv->state_count; 53 - ret = cpuidle_register_device(dev); 54 - if (ret) { 55 - pr_err("CPU%u: CPUidle device registration failed\n", 56 - cpu); 57 - return ret; 58 - } 59 - } 60 - return 0; 34 + return cpuidle_register(&tegra_idle_driver, NULL); 61 35 }
+21 -51
arch/arm/mach-tegra/cpuidle-tegra20.c
··· 43 43 static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, 44 44 struct cpuidle_driver *drv, 45 45 int index); 46 + #define TEGRA20_MAX_STATES 2 47 + #else 48 + #define TEGRA20_MAX_STATES 1 46 49 #endif 47 - 48 - static struct cpuidle_state tegra_idle_states[] = { 49 - [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), 50 - #ifdef CONFIG_PM_SLEEP 51 - [1] = { 52 - .enter = tegra20_idle_lp2_coupled, 53 - .exit_latency = 5000, 54 - .target_residency = 10000, 55 - .power_usage = 0, 56 - .flags = CPUIDLE_FLAG_TIME_VALID | 57 - CPUIDLE_FLAG_COUPLED, 58 - .name = "powered-down", 59 - .desc = "CPU power gated", 60 - }, 61 - #endif 62 - }; 63 50 64 51 static struct cpuidle_driver tegra_idle_driver = { 65 52 .name = "tegra_idle", 66 53 .owner = THIS_MODULE, 67 - .en_core_tk_irqen = 1, 54 + .states = { 55 + ARM_CPUIDLE_WFI_STATE_PWR(600), 56 + #ifdef CONFIG_PM_SLEEP 57 + { 58 + .enter = tegra20_idle_lp2_coupled, 59 + .exit_latency = 5000, 60 + .target_residency = 10000, 61 + .power_usage = 0, 62 + .flags = CPUIDLE_FLAG_TIME_VALID | 63 + CPUIDLE_FLAG_COUPLED, 64 + .name = "powered-down", 65 + .desc = "CPU power gated", 66 + }, 67 + #endif 68 + }, 69 + .state_count = TEGRA20_MAX_STATES, 70 + .safe_state_index = 0, 68 71 }; 69 - 70 - static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); 71 72 72 73 #ifdef CONFIG_PM_SLEEP 73 74 #ifdef CONFIG_SMP ··· 218 217 219 218 int __init tegra20_cpuidle_init(void) 220 219 { 221 - int ret; 222 - unsigned int cpu; 223 - struct cpuidle_device *dev; 224 - struct cpuidle_driver *drv = &tegra_idle_driver; 225 - 226 220 #ifdef CONFIG_PM_SLEEP 227 221 tegra_tear_down_cpu = tegra20_tear_down_cpu; 228 222 #endif 229 - 230 - drv->state_count = ARRAY_SIZE(tegra_idle_states); 231 - memcpy(drv->states, tegra_idle_states, 232 - drv->state_count * sizeof(drv->states[0])); 233 - 234 - ret = cpuidle_register_driver(&tegra_idle_driver); 235 - if (ret) { 236 - pr_err("CPUidle driver registration failed\n"); 237 - return ret; 238 - } 239 - 240 - for_each_possible_cpu(cpu) { 241 - dev = &per_cpu(tegra_idle_device, cpu); 242 - dev->cpu = cpu; 243 - #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 244 - dev->coupled_cpus = *cpu_possible_mask; 245 - #endif 246 - 247 - dev->state_count = drv->state_count; 248 - ret = cpuidle_register_device(dev); 249 - if (ret) { 250 - pr_err("CPU%u: CPUidle device registration failed\n", 251 - cpu); 252 - return ret; 253 - } 254 - } 255 - return 0; 223 + return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); 256 224 }
+1 -28
arch/arm/mach-tegra/cpuidle-tegra30.c
··· 43 43 static struct cpuidle_driver tegra_idle_driver = { 44 44 .name = "tegra_idle", 45 45 .owner = THIS_MODULE, 46 - .en_core_tk_irqen = 1, 47 46 #ifdef CONFIG_PM_SLEEP 48 47 .state_count = 2, 49 48 #else ··· 63 64 #endif 64 65 }, 65 66 }; 66 - 67 - static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); 68 67 69 68 #ifdef CONFIG_PM_SLEEP 70 69 static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev, ··· 154 157 155 158 int __init tegra30_cpuidle_init(void) 156 159 { 157 - int ret; 158 - unsigned int cpu; 159 - struct cpuidle_device *dev; 160 - struct cpuidle_driver *drv = &tegra_idle_driver; 161 - 162 160 #ifdef CONFIG_PM_SLEEP 163 161 tegra_tear_down_cpu = tegra30_tear_down_cpu; 164 162 #endif 165 - 166 - ret = cpuidle_register_driver(&tegra_idle_driver); 167 - if (ret) { 168 - pr_err("CPUidle driver registration failed\n"); 169 - return ret; 170 - } 171 - 172 - for_each_possible_cpu(cpu) { 173 - dev = &per_cpu(tegra_idle_device, cpu); 174 - dev->cpu = cpu; 175 - 176 - dev->state_count = drv->state_count; 177 - ret = cpuidle_register_device(dev); 178 - if (ret) { 179 - pr_err("CPU%u: CPUidle device registration failed\n", 180 - cpu); 181 - return ret; 182 - } 183 - } 184 - return 0; 163 + return cpuidle_register(&tegra_idle_driver, NULL); 185 164 }
+3 -55
arch/arm/mach-ux500/cpuidle.c
··· 11 11 12 12 #include <linux/module.h> 13 13 #include <linux/cpuidle.h> 14 - #include <linux/clockchips.h> 15 14 #include <linux/spinlock.h> 16 15 #include <linux/atomic.h> 17 16 #include <linux/smp.h> ··· 21 22 22 23 static atomic_t master = ATOMIC_INIT(0); 23 24 static DEFINE_SPINLOCK(master_lock); 24 - static DEFINE_PER_CPU(struct cpuidle_device, ux500_cpuidle_device); 25 25 26 26 static inline int ux500_enter_idle(struct cpuidle_device *dev, 27 27 struct cpuidle_driver *drv, int index) 28 28 { 29 29 int this_cpu = smp_processor_id(); 30 30 bool recouple = false; 31 - 32 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu); 33 31 34 32 if (atomic_inc_return(&master) == num_online_cpus()) { 35 33 ··· 87 91 spin_unlock(&master_lock); 88 92 } 89 93 90 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu); 91 - 92 94 return index; 93 95 } 94 96 95 97 static struct cpuidle_driver ux500_idle_driver = { 96 98 .name = "ux500_idle", 97 99 .owner = THIS_MODULE, 98 - .en_core_tk_irqen = 1, 99 100 .states = { 100 101 ARM_CPUIDLE_WFI_STATE, 101 102 { 102 103 .enter = ux500_enter_idle, 103 104 .exit_latency = 70, 104 105 .target_residency = 260, 105 - .flags = CPUIDLE_FLAG_TIME_VALID, 106 + .flags = CPUIDLE_FLAG_TIME_VALID | 107 + CPUIDLE_FLAG_TIMER_STOP, 106 108 .name = "ApIdle", 107 109 .desc = "ARM Retention", 108 110 }, ··· 109 115 .state_count = 2, 110 116 }; 111 117 112 - /* 113 - * For each cpu, setup the broadcast timer because we will 114 - * need to migrate the timers for the states >= ApIdle. 115 - */ 116 - static void ux500_setup_broadcast_timer(void *arg) 117 - { 118 - int cpu = smp_processor_id(); 119 - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); 120 - } 121 - 122 118 int __init ux500_idle_init(void) 123 119 { 124 - int ret, cpu; 125 - struct cpuidle_device *device; 126 - 127 120 /* Configure wake up reasons */ 128 121 prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | 129 122 PRCMU_WAKEUP(ABB)); 130 123 131 - /* 132 - * Configure the timer broadcast for each cpu, that must 133 - * be done from the cpu context, so we use a smp cross 134 - * call with 'on_each_cpu'. 135 - */ 136 - on_each_cpu(ux500_setup_broadcast_timer, NULL, 1); 137 - 138 - ret = cpuidle_register_driver(&ux500_idle_driver); 139 - if (ret) { 140 - printk(KERN_ERR "failed to register ux500 idle driver\n"); 141 - return ret; 142 - } 143 - 144 - for_each_online_cpu(cpu) { 145 - device = &per_cpu(ux500_cpuidle_device, cpu); 146 - device->cpu = cpu; 147 - ret = cpuidle_register_device(device); 148 - if (ret) { 149 - printk(KERN_ERR "Failed to register cpuidle " 150 - "device for cpu%d\n", cpu); 151 - goto out_unregister; 152 - } 153 - } 154 - out: 155 - return ret; 156 - 157 - out_unregister: 158 - for_each_online_cpu(cpu) { 159 - device = &per_cpu(ux500_cpuidle_device, cpu); 160 - cpuidle_unregister_device(device); 161 - } 162 - 163 - cpuidle_unregister_driver(&ux500_idle_driver); 164 - goto out; 124 + return cpuidle_register(&ux500_idle_driver, NULL); 165 125 } 166 126 167 127 device_initcall(ux500_idle_init);
+14 -20
arch/powerpc/platforms/pseries/processor_idle.c
··· 23 23 #include "pseries.h" 24 24 25 25 struct cpuidle_driver pseries_idle_driver = { 26 - .name = "pseries_idle", 27 - .owner = THIS_MODULE, 26 + .name = "pseries_idle", 27 + .owner = THIS_MODULE, 28 28 }; 29 29 30 30 #define MAX_IDLE_STATE_COUNT 2 ··· 33 33 static struct cpuidle_device __percpu *pseries_cpuidle_devices; 34 34 static struct cpuidle_state *cpuidle_state_table; 35 35 36 - static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) 36 + static inline void idle_loop_prolog(unsigned long *in_purr) 37 37 { 38 - 39 - *kt_before = ktime_get(); 40 38 *in_purr = mfspr(SPRN_PURR); 41 39 /* 42 40 * Indicate to the HV that we are idle. Now would be ··· 43 45 get_lppaca()->idle = 1; 44 46 } 45 47 46 - static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) 48 + static inline void idle_loop_epilog(unsigned long in_purr) 47 49 { 48 50 get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; 49 51 get_lppaca()->idle = 0; 50 - 51 - return ktime_to_us(ktime_sub(ktime_get(), kt_before)); 52 52 } 53 53 54 54 static int snooze_loop(struct cpuidle_device *dev, ··· 54 58 int index) 55 59 { 56 60 unsigned long in_purr; 57 - ktime_t kt_before; 58 61 int cpu = dev->cpu; 59 62 60 - idle_loop_prolog(&in_purr, &kt_before); 63 + idle_loop_prolog(&in_purr); 61 64 local_irq_enable(); 62 65 set_thread_flag(TIF_POLLING_NRFLAG); 63 66 ··· 70 75 clear_thread_flag(TIF_POLLING_NRFLAG); 71 76 smp_mb(); 72 77 73 - dev->last_residency = 74 - (int)idle_loop_epilog(in_purr, kt_before); 78 + idle_loop_epilog(in_purr); 79 + 75 80 return index; 76 81 } 77 82 ··· 97 102 int index) 98 103 { 99 104 unsigned long in_purr; 100 - ktime_t kt_before; 101 105 102 - idle_loop_prolog(&in_purr, &kt_before); 106 + idle_loop_prolog(&in_purr); 103 107 get_lppaca()->donate_dedicated_cpu = 1; 104 108 105 109 ppc64_runlatch_off(); ··· 106 112 check_and_cede_processor(); 107 113 108 114 get_lppaca()->donate_dedicated_cpu = 0; 109 - dev->last_residency = 110 - (int)idle_loop_epilog(in_purr, kt_before); 115 + 116 + idle_loop_epilog(in_purr); 117 + 111 118 return index; 112 119 } 113 120 ··· 117 122 int index) 118 123 { 119 124 unsigned long in_purr; 120 - ktime_t kt_before; 121 125 122 - idle_loop_prolog(&in_purr, &kt_before); 126 + idle_loop_prolog(&in_purr); 123 127 124 128 /* 125 129 * Yield the processor to the hypervisor. We return if ··· 129 135 */ 130 136 check_and_cede_processor(); 131 137 132 - dev->last_residency = 133 - (int)idle_loop_epilog(in_purr, kt_before); 138 + idle_loop_epilog(in_purr); 139 + 134 140 return index; 135 141 } 136 142
+2 -2
arch/sh/include/asm/suspend.h
··· 14 14 void sh_mobile_call_standby(unsigned long mode); 15 15 16 16 #ifdef CONFIG_CPU_IDLE 17 - void sh_mobile_setup_cpuidle(void); 17 + int sh_mobile_setup_cpuidle(void); 18 18 #else 19 - static inline void sh_mobile_setup_cpuidle(void) {} 19 + static inline int sh_mobile_setup_cpuidle(void) { return 0; } 20 20 #endif 21 21 22 22 /* notifier chains for pre/post sleep hooks */
+42 -59
arch/sh/kernel/cpu/shmobile/cpuidle.c
··· 51 51 return k; 52 52 } 53 53 54 - static struct cpuidle_device cpuidle_dev; 55 54 static struct cpuidle_driver cpuidle_driver = { 56 - .name = "sh_idle", 57 - .owner = THIS_MODULE, 58 - .en_core_tk_irqen = 1, 55 + .name = "sh_idle", 56 + .owner = THIS_MODULE, 57 + .states = { 58 + { 59 + .exit_latency = 1, 60 + .target_residency = 1 * 2, 61 + .power_usage = 3, 62 + .flags = CPUIDLE_FLAG_TIME_VALID, 63 + .enter = cpuidle_sleep_enter, 64 + .name = "C1", 65 + .desc = "SuperH Sleep Mode", 66 + }, 67 + { 68 + .exit_latency = 100, 69 + .target_residency = 1 * 2, 70 + .power_usage = 1, 71 + .flags = CPUIDLE_FLAG_TIME_VALID, 72 + .enter = cpuidle_sleep_enter, 73 + .name = "C2", 74 + .desc = "SuperH Sleep Mode [SF]", 75 + .disabled = true, 76 + }, 77 + { 78 + .exit_latency = 2300, 79 + .target_residency = 1 * 2, 80 + .power_usage = 1, 81 + .flags = CPUIDLE_FLAG_TIME_VALID, 82 + .enter = cpuidle_sleep_enter, 83 + .name = "C3", 84 + .desc = "SuperH Mobile Standby Mode [SF]", 85 + .disabled = true, 86 + }, 87 + }, 88 + .safe_state_index = 0, 89 + .state_count = 3, 59 90 }; 60 91 61 - void sh_mobile_setup_cpuidle(void) 92 + int __init sh_mobile_setup_cpuidle(void) 62 93 { 63 - struct cpuidle_device *dev = &cpuidle_dev; 64 - struct cpuidle_driver *drv = &cpuidle_driver; 65 - struct cpuidle_state *state; 66 - int i; 94 + int ret; 67 95 96 + if (sh_mobile_sleep_supported & SUSP_SH_SF) 97 + cpuidle_driver.states[1].disabled = false; 68 98 69 - for (i = 0; i < CPUIDLE_STATE_MAX; i++) { 70 - drv->states[i].name[0] = '\0'; 71 - drv->states[i].desc[0] = '\0'; 72 - } 99 + if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) 100 + cpuidle_driver.states[2].disabled = false; 73 101 74 - i = CPUIDLE_DRIVER_STATE_START; 75 - 76 - state = &drv->states[i++]; 77 - snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); 78 - strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN); 79 - state->exit_latency = 1; 80 - state->target_residency = 1 * 2; 81 - state->power_usage = 3; 82 - state->flags = 0; 83 - state->flags |= CPUIDLE_FLAG_TIME_VALID; 84 - state->enter = cpuidle_sleep_enter; 85 - 86 - drv->safe_state_index = i-1; 87 - 88 - if (sh_mobile_sleep_supported & SUSP_SH_SF) { 89 - state = &drv->states[i++]; 90 - snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 91 - strncpy(state->desc, "SuperH Sleep Mode [SF]", 92 - CPUIDLE_DESC_LEN); 93 - state->exit_latency = 100; 94 - state->target_residency = 1 * 2; 95 - state->power_usage = 1; 96 - state->flags = 0; 97 - state->flags |= CPUIDLE_FLAG_TIME_VALID; 98 - state->enter = cpuidle_sleep_enter; 99 - } 100 - 101 - if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { 102 - state = &drv->states[i++]; 103 - snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); 104 - strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", 105 - CPUIDLE_DESC_LEN); 106 - state->exit_latency = 2300; 107 - state->target_residency = 1 * 2; 108 - state->power_usage = 1; 109 - state->flags = 0; 110 - state->flags |= CPUIDLE_FLAG_TIME_VALID; 111 - state->enter = cpuidle_sleep_enter; 112 - } 113 - 114 - drv->state_count = i; 115 - dev->state_count = i; 116 - 117 - cpuidle_register_driver(&cpuidle_driver); 118 - 119 - cpuidle_register_device(dev); 102 + return cpuidle_register(&cpuidle_driver); 120 103 }
+1 -2
arch/sh/kernel/cpu/shmobile/pm.c
··· 150 150 static int __init sh_pm_init(void) 151 151 { 152 152 suspend_set_ops(&sh_pm_ops); 153 - sh_mobile_setup_cpuidle(); 154 - return 0; 153 + return sh_mobile_setup_cpuidle(); 155 154 } 156 155 157 156 late_initcall(sh_pm_init);
-1
arch/x86/kernel/apm_32.c
··· 373 373 static struct cpuidle_driver apm_idle_driver = { 374 374 .name = "apm_idle", 375 375 .owner = THIS_MODULE, 376 - .en_core_tk_irqen = 1, 377 376 .states = { 378 377 { /* entry 0 is for polling */ }, 379 378 { /* entry 1 is for APM idle */
-1
drivers/acpi/processor_idle.c
··· 918 918 struct cpuidle_driver acpi_idle_driver = { 919 919 .name = "acpi_idle", 920 920 .owner = THIS_MODULE, 921 - .en_core_tk_irqen = 1, 922 921 }; 923 922 924 923 /**
-6
drivers/cpuidle/Kconfig
··· 39 39 help 40 40 Select this to enable cpuidle on Calxeda processors. 41 41 42 - config CPU_IDLE_KIRKWOOD 43 - bool "CPU Idle Driver for Kirkwood processors" 44 - depends on ARCH_KIRKWOOD 45 - help 46 - Select this to enable cpuidle on Kirkwood processors. 47 - 48 42 endif
+1 -1
drivers/cpuidle/Makefile
··· 6 6 obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o 7 7 8 8 obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o 9 - obj-$(CONFIG_CPU_IDLE_KIRKWOOD) += cpuidle-kirkwood.o 9 + obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
+4 -53
drivers/cpuidle/cpuidle-calxeda.c
··· 1 1 /* 2 2 * Copyright 2012 Calxeda, Inc. 3 3 * 4 - * Based on arch/arm/plat-mxc/cpuidle.c: 4 + * Based on arch/arm/plat-mxc/cpuidle.c: #v3.7 5 5 * Copyright 2012 Freescale Semiconductor, Inc. 6 6 * Copyright 2012 Linaro Ltd. 7 7 * ··· 16 16 * 17 17 * You should have received a copy of the GNU General Public License along with 18 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 + * 20 + * Maintainer: Rob Herring <rob.herring@calxeda.com> 19 21 */ 20 22 21 23 #include <linux/cpuidle.h> ··· 36 34 37 35 extern void highbank_set_cpu_jump(int cpu, void *jump_addr); 38 36 extern void *scu_base_addr; 39 - 40 - static struct cpuidle_device __percpu *calxeda_idle_cpuidle_devices; 41 37 42 38 static inline unsigned int get_auxcr(void) 43 39 { ··· 85 85 return index; 86 86 } 87 87 88 - static void calxeda_idle_cpuidle_devices_uninit(void) 89 - { 90 - int i; 91 - struct cpuidle_device *dev; 92 - 93 - for_each_possible_cpu(i) { 94 - dev = per_cpu_ptr(calxeda_idle_cpuidle_devices, i); 95 - cpuidle_unregister_device(dev); 96 - } 97 - 98 - free_percpu(calxeda_idle_cpuidle_devices); 99 - } 100 - 101 88 static struct cpuidle_driver calxeda_idle_driver = { 102 89 .name = "calxeda_idle", 103 - .en_core_tk_irqen = 1, 104 90 .states = { 105 91 ARM_CPUIDLE_WFI_STATE, 106 92 { ··· 104 118 105 119 static int __init calxeda_cpuidle_init(void) 106 120 { 107 - int cpu_id; 108 - int ret; 109 - struct cpuidle_device *dev; 110 - struct cpuidle_driver *drv = &calxeda_idle_driver; 111 - 112 121 if (!of_machine_is_compatible("calxeda,highbank")) 113 122 return -ENODEV; 114 123 115 - ret = cpuidle_register_driver(drv); 116 - if (ret) 117 - return ret; 118 - 119 - calxeda_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 120 - if (calxeda_idle_cpuidle_devices == NULL) { 121 - ret = -ENOMEM; 122 - goto unregister_drv; 123 - } 124 - 125 - /* initialize state data for each cpuidle_device */ 126 - for_each_possible_cpu(cpu_id) { 127 - dev = per_cpu_ptr(calxeda_idle_cpuidle_devices, cpu_id); 128 - dev->cpu = cpu_id; 129 - dev->state_count = drv->state_count; 130 - 131 - ret = cpuidle_register_device(dev); 132 - if (ret) { 133 - pr_err("Failed to register cpu %u, error: %d\n", 134 - cpu_id, ret); 135 - goto uninit; 136 - } 137 - } 138 - 139 - return 0; 140 - 141 - uninit: 142 - calxeda_idle_cpuidle_devices_uninit(); 143 - unregister_drv: 144 - cpuidle_unregister_driver(drv); 145 - return ret; 124 + return cpuidle_register(&calxeda_idle_driver, NULL); 146 125 } 147 126 module_init(calxeda_cpuidle_init);
+8 -21
drivers/cpuidle/cpuidle-kirkwood.c
··· 1 1 /* 2 - * arch/arm/mach-kirkwood/cpuidle.c 3 - * 4 2 * CPU idle Marvell Kirkwood SoCs 5 3 * 6 4 * This file is licensed under the terms of the GNU General Public ··· 9 11 * to implement two idle states - 10 12 * #1 wait-for-interrupt 11 13 * #2 wait-for-interrupt and DDR self refresh 14 + * 15 + * Maintainer: Jason Cooper <jason@lakedaemon.net> 16 + * Maintainer: Andrew Lunn <andrew@lunn.ch> 12 17 */ 13 18 14 19 #include <linux/kernel.h> ··· 42 41 static struct cpuidle_driver kirkwood_idle_driver = { 43 42 .name = "kirkwood_idle", 44 43 .owner = THIS_MODULE, 45 - .en_core_tk_irqen = 1, 46 44 .states[0] = ARM_CPUIDLE_WFI_STATE, 47 45 .states[1] = { 48 46 .enter = kirkwood_enter_idle, ··· 53 53 }, 54 54 .state_count = KIRKWOOD_MAX_STATES, 55 55 }; 56 - static struct cpuidle_device *device; 57 - 58 - static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); 59 56 60 57 /* Initialize CPU idle by registering the idle states */ 61 58 static int kirkwood_cpuidle_probe(struct platform_device *pdev) ··· 63 66 if (res == NULL) 64 67 return -EINVAL; 65 68 66 - ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res); 67 - if (!ddr_operation_base) 68 - return -EADDRNOTAVAIL; 69 + ddr_operation_base = devm_ioremap_resource(&pdev->dev, res); 70 + if (IS_ERR(ddr_operation_base)) 71 + return PTR_ERR(ddr_operation_base); 69 72 70 - device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); 71 - device->state_count = KIRKWOOD_MAX_STATES; 72 - 73 - cpuidle_register_driver(&kirkwood_idle_driver); 74 - if (cpuidle_register_device(device)) { 75 - pr_err("kirkwood_init_cpuidle: Failed registering\n"); 76 - return -EIO; 77 - } 78 - return 0; 73 + return cpuidle_register(&kirkwood_idle_driver, NULL); 79 74 } 80 75 81 76 int kirkwood_cpuidle_remove(struct platform_device *pdev) 82 77 { 83 - cpuidle_unregister_device(device); 84 - cpuidle_unregister_driver(&kirkwood_idle_driver); 85 - 78 + cpuidle_unregister(&kirkwood_idle_driver); 86 79 return 0; 87 80 } 88 81
+99 -54
drivers/cpuidle/cpuidle.c
··· 8 8 * This code is licenced under the GPL. 9 9 */ 10 10 11 + #include <linux/clockchips.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/mutex.h> 13 14 #include <linux/sched.h> ··· 24 23 #include "cpuidle.h" 25 24 26 25 DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 26 + DEFINE_PER_CPU(struct cpuidle_device, cpuidle_dev); 27 27 28 28 DEFINE_MUTEX(cpuidle_lock); 29 29 LIST_HEAD(cpuidle_detected_devices); ··· 43 41 } 44 42 45 43 static int __cpuidle_register_device(struct cpuidle_device *dev); 46 - 47 - static inline int cpuidle_enter(struct cpuidle_device *dev, 48 - struct cpuidle_driver *drv, int index) 49 - { 50 - struct cpuidle_state *target_state = &drv->states[index]; 51 - return target_state->enter(dev, drv, index); 52 - } 53 - 54 - static inline int cpuidle_enter_tk(struct cpuidle_device *dev, 55 - struct cpuidle_driver *drv, int index) 56 - { 57 - return cpuidle_wrap_enter(dev, drv, index, cpuidle_enter); 58 - } 59 - 60 - typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev, 61 - struct cpuidle_driver *drv, int index); 62 - 63 - static cpuidle_enter_t cpuidle_enter_ops; 64 44 65 45 /** 66 46 * cpuidle_play_dead - cpu off-lining ··· 73 89 * @next_state: index into drv->states of the state to enter 74 90 */ 75 91 int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, 76 - int next_state) 92 + int index) 77 93 { 78 94 int entered_state; 79 95 80 - entered_state = cpuidle_enter_ops(dev, drv, next_state); 96 + struct cpuidle_state *target_state = &drv->states[index]; 97 + ktime_t time_start, time_end; 98 + s64 diff; 99 + 100 + time_start = ktime_get(); 101 + 102 + entered_state = target_state->enter(dev, drv, index); 103 + 104 + time_end = ktime_get(); 105 + 106 + local_irq_enable(); 107 + 108 + diff = ktime_to_us(ktime_sub(time_end, time_start)); 109 + if (diff > INT_MAX) 110 + diff = INT_MAX; 111 + 112 + dev->last_residency = (int) diff; 81 113 82 114 if (entered_state >= 0) { 83 115 /* Update cpuidle counters */ ··· 146 146 147 147 trace_cpu_idle_rcuidle(next_state, dev->cpu); 148 148 149 + if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) 150 + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, 151 + &dev->cpu); 152 + 149 153 if (cpuidle_state_is_coupled(dev, drv, next_state)) 150 154 entered_state = cpuidle_enter_state_coupled(dev, drv, 151 155 next_state); 152 156 else 153 157 entered_state = cpuidle_enter_state(dev, drv, next_state); 158 + 159 + if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) 160 + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, 161 + &dev->cpu); 154 162 155 163 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); 156 164 ··· 228 220 mutex_lock(&cpuidle_lock); 229 221 cpuidle_install_idle_handler(); 230 222 mutex_unlock(&cpuidle_lock); 231 - } 232 - 233 - /** 234 - * cpuidle_wrap_enter - performs timekeeping and irqen around enter function 235 - * @dev: pointer to a valid cpuidle_device object 236 - * @drv: pointer to a valid cpuidle_driver object 237 - * @index: index of the target cpuidle state. 238 - */ 239 - int cpuidle_wrap_enter(struct cpuidle_device *dev, 240 - struct cpuidle_driver *drv, int index, 241 - int (*enter)(struct cpuidle_device *dev, 242 - struct cpuidle_driver *drv, int index)) 243 - { 244 - ktime_t time_start, time_end; 245 - s64 diff; 246 - 247 - time_start = ktime_get(); 248 - 249 - index = enter(dev, drv, index); 250 - 251 - time_end = ktime_get(); 252 - 253 - local_irq_enable(); 254 - 255 - diff = ktime_to_us(ktime_sub(time_end, time_start)); 256 - if (diff > INT_MAX) 257 - diff = INT_MAX; 258 - 259 - dev->last_residency = (int) diff; 260 - 261 - return index; 262 223 } 263 224 264 225 #ifdef CONFIG_ARCH_HAS_CPU_RELAX ··· 300 323 if (ret) 301 324 return ret; 302 325 } 303 - 304 - cpuidle_enter_ops = drv->en_core_tk_irqen ? 305 - cpuidle_enter_tk : cpuidle_enter; 306 326 307 327 poll_idle_init(drv); 308 328 ··· 453 479 } 454 480 455 481 EXPORT_SYMBOL_GPL(cpuidle_unregister_device); 482 + 483 + /** 484 + * cpuidle_unregister: unregister a driver and the devices. This function 485 + * can be used only if the driver has been previously registered through 486 + * the cpuidle_register function. 487 + * 488 + * @drv: a valid pointer to a struct cpuidle_driver 489 + */ 490 + void cpuidle_unregister(struct cpuidle_driver *drv) 491 + { 492 + int cpu; 493 + struct cpuidle_device *device; 494 + 495 + for_each_possible_cpu(cpu) { 496 + device = &per_cpu(cpuidle_dev, cpu); 497 + cpuidle_unregister_device(device); 498 + } 499 + 500 + cpuidle_unregister_driver(drv); 501 + } 502 + EXPORT_SYMBOL_GPL(cpuidle_unregister); 503 + 504 + /** 505 + * cpuidle_register: registers the driver and the cpu devices with the 506 + * coupled_cpus passed as parameter. This function is used for all common 507 + * initialization pattern there are in the arch specific drivers. The 508 + * devices is globally defined in this file. 509 + * 510 + * @drv : a valid pointer to a struct cpuidle_driver 511 + * @coupled_cpus: a cpumask for the coupled states 512 + * 513 + * Returns 0 on success, < 0 otherwise 514 + */ 515 + int cpuidle_register(struct cpuidle_driver *drv, 516 + const struct cpumask *const coupled_cpus) 517 + { 518 + int ret, cpu; 519 + struct cpuidle_device *device; 520 + 521 + ret = cpuidle_register_driver(drv); 522 + if (ret) { 523 + pr_err("failed to register cpuidle driver\n"); 524 + return ret; 525 + } 526 + 527 + for_each_possible_cpu(cpu) { 528 + device = &per_cpu(cpuidle_dev, cpu); 529 + device->cpu = cpu; 530 + 531 + #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 532 + /* 533 + * On multiplatform for ARM, the coupled idle states could 534 + * enabled in the kernel even if the cpuidle driver does not 535 + * use it. Note, coupled_cpus is a struct copy. 536 + */ 537 + if (coupled_cpus) 538 + device->coupled_cpus = *coupled_cpus; 539 + #endif 540 + ret = cpuidle_register_device(device); 541 + if (!ret) 542 + continue; 543 + 544 + pr_err("Failed to register cpuidle device for cpu%d\n", cpu); 545 + 546 + cpuidle_unregister(drv); 547 + break; 548 + } 549 + 550 + return ret; 551 + } 552 + EXPORT_SYMBOL_GPL(cpuidle_register); 456 553 457 554 #ifdef CONFIG_SMP 458 555
+29 -2
drivers/cpuidle/driver.c
··· 11 11 #include <linux/mutex.h> 12 12 #include <linux/module.h> 13 13 #include <linux/cpuidle.h> 14 + #include <linux/cpumask.h> 15 + #include <linux/clockchips.h> 14 16 15 17 #include "cpuidle.h" 16 18 ··· 21 19 static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu); 22 20 static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu); 23 21 24 - static void __cpuidle_driver_init(struct cpuidle_driver *drv) 22 + static void cpuidle_setup_broadcast_timer(void *arg) 25 23 { 24 + int cpu = smp_processor_id(); 25 + clockevents_notify((long)(arg), &cpu); 26 + } 27 + 28 + static void __cpuidle_driver_init(struct cpuidle_driver *drv, int cpu) 29 + { 30 + int i; 31 + 26 32 drv->refcnt = 0; 33 + 34 + for (i = drv->state_count - 1; i >= 0 ; i--) { 35 + 36 + if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP)) 37 + continue; 38 + 39 + drv->bctimer = 1; 40 + on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer, 41 + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); 42 + break; 43 + } 27 44 } 28 45 29 46 static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu) ··· 56 35 if (__cpuidle_get_cpu_driver(cpu)) 57 36 return -EBUSY; 58 37 59 - __cpuidle_driver_init(drv); 38 + __cpuidle_driver_init(drv, cpu); 60 39 61 40 __cpuidle_set_cpu_driver(drv, cpu); 62 41 ··· 70 49 71 50 if (!WARN_ON(drv->refcnt > 0)) 72 51 __cpuidle_set_cpu_driver(NULL, cpu); 52 + 53 + if (drv->bctimer) { 54 + drv->bctimer = 0; 55 + on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer, 56 + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1); 57 + } 73 58 } 74 59 75 60 #ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
-4
drivers/idle/intel_idle.c
··· 71 71 static struct cpuidle_driver intel_idle_driver = { 72 72 .name = "intel_idle", 73 73 .owner = THIS_MODULE, 74 - .en_core_tk_irqen = 1, 75 74 }; 76 75 /* intel_idle.max_cstate=0 disables driver */ 77 76 static int max_cstate = CPUIDLE_STATE_MAX - 1; ··· 338 339 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 339 340 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); 340 341 341 - stop_critical_timings(); 342 342 if (!need_resched()) { 343 343 344 344 __monitor((void *)&current_thread_info()->flags, 0, 0); ··· 345 347 if (!need_resched()) 346 348 __mwait(eax, ecx); 347 349 } 348 - 349 - start_critical_timings(); 350 350 351 351 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 352 352 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+16 -16
include/linux/clockchips.h
··· 8 8 #ifndef _LINUX_CLOCKCHIPS_H 9 9 #define _LINUX_CLOCKCHIPS_H 10 10 11 + /* Clock event notification values */ 12 + enum clock_event_nofitiers { 13 + CLOCK_EVT_NOTIFY_ADD, 14 + CLOCK_EVT_NOTIFY_BROADCAST_ON, 15 + CLOCK_EVT_NOTIFY_BROADCAST_OFF, 16 + CLOCK_EVT_NOTIFY_BROADCAST_FORCE, 17 + CLOCK_EVT_NOTIFY_BROADCAST_ENTER, 18 + CLOCK_EVT_NOTIFY_BROADCAST_EXIT, 19 + CLOCK_EVT_NOTIFY_SUSPEND, 20 + CLOCK_EVT_NOTIFY_RESUME, 21 + CLOCK_EVT_NOTIFY_CPU_DYING, 22 + CLOCK_EVT_NOTIFY_CPU_DEAD, 23 + }; 24 + 11 25 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD 12 26 13 27 #include <linux/clocksource.h> ··· 38 24 CLOCK_EVT_MODE_PERIODIC, 39 25 CLOCK_EVT_MODE_ONESHOT, 40 26 CLOCK_EVT_MODE_RESUME, 41 - }; 42 - 43 - /* Clock event notification values */ 44 - enum clock_event_nofitiers { 45 - CLOCK_EVT_NOTIFY_ADD, 46 - CLOCK_EVT_NOTIFY_BROADCAST_ON, 47 - CLOCK_EVT_NOTIFY_BROADCAST_OFF, 48 - CLOCK_EVT_NOTIFY_BROADCAST_FORCE, 49 - CLOCK_EVT_NOTIFY_BROADCAST_ENTER, 50 - CLOCK_EVT_NOTIFY_BROADCAST_EXIT, 51 - CLOCK_EVT_NOTIFY_SUSPEND, 52 - CLOCK_EVT_NOTIFY_RESUME, 53 - CLOCK_EVT_NOTIFY_CPU_DYING, 54 - CLOCK_EVT_NOTIFY_CPU_DEAD, 55 27 }; 56 28 57 29 /* ··· 173 173 #ifdef CONFIG_GENERIC_CLOCKEVENTS 174 174 extern void clockevents_notify(unsigned long reason, void *arg); 175 175 #else 176 - # define clockevents_notify(reason, arg) do { } while (0) 176 + static inline void clockevents_notify(unsigned long reason, void *arg) {} 177 177 #endif 178 178 179 179 #else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */ ··· 181 181 static inline void clockevents_suspend(void) {} 182 182 static inline void clockevents_resume(void) {} 183 183 184 - #define clockevents_notify(reason, arg) do { } while (0) 184 + static inline void clockevents_notify(unsigned long reason, void *arg) {} 185 185 186 186 #endif 187 187
+10 -13
include/linux/cpuidle.h
··· 57 57 /* Idle State Flags */ 58 58 #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ 59 59 #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ 60 + #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */ 60 61 61 62 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) 62 63 ··· 105 104 struct module *owner; 106 105 int refcnt; 107 106 108 - /* set to 1 to use the core cpuidle time keeping (for all states). */ 109 - unsigned int en_core_tk_irqen:1; 107 + /* used by the cpuidle framework to setup the broadcast timer */ 108 + unsigned int bctimer:1; 110 109 /* states array must be ordered in decreasing power consumption */ 111 110 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 112 111 int state_count; ··· 123 122 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 124 123 extern int cpuidle_register_device(struct cpuidle_device *dev); 125 124 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 126 - 125 + extern int cpuidle_register(struct cpuidle_driver *drv, 126 + const struct cpumask *const coupled_cpus); 127 + extern void cpuidle_unregister(struct cpuidle_driver *drv); 127 128 extern void cpuidle_pause_and_lock(void); 128 129 extern void cpuidle_resume_and_unlock(void); 129 130 extern void cpuidle_pause(void); 130 131 extern void cpuidle_resume(void); 131 132 extern int cpuidle_enable_device(struct cpuidle_device *dev); 132 133 extern void cpuidle_disable_device(struct cpuidle_device *dev); 133 - extern int cpuidle_wrap_enter(struct cpuidle_device *dev, 134 - struct cpuidle_driver *drv, int index, 135 - int (*enter)(struct cpuidle_device *dev, 136 - struct cpuidle_driver *drv, int index)); 137 134 extern int cpuidle_play_dead(void); 138 135 139 136 extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); ··· 150 151 static inline int cpuidle_register_device(struct cpuidle_device *dev) 151 152 {return -ENODEV; } 152 153 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 153 - 154 + static inline int cpuidle_register(struct cpuidle_driver *drv, 155 + const struct cpumask *const coupled_cpus) 156 + {return -ENODEV; } 157 + static inline void cpuidle_unregister(struct cpuidle_driver *drv) { } 154 158 static inline void cpuidle_pause_and_lock(void) { } 155 159 static inline void cpuidle_resume_and_unlock(void) { } 156 160 static inline void cpuidle_pause(void) { } ··· 161 159 static inline int cpuidle_enable_device(struct cpuidle_device *dev) 162 160 {return -ENODEV; } 163 161 static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 164 - static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, 165 - struct cpuidle_driver *drv, int index, 166 - int (*enter)(struct cpuidle_device *dev, 167 - struct cpuidle_driver *drv, int index)) 168 - { return -ENODEV; } 169 162 static inline int cpuidle_play_dead(void) {return -ENODEV; } 170 163 #endif 171 164