diff options
Diffstat (limited to 'arch/arm/mach-imx/cpuidle.c')
| -rw-r--r-- | arch/arm/mach-imx/cpuidle.c | 80 | 
1 files changed, 80 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/cpuidle.c b/arch/arm/mach-imx/cpuidle.c new file mode 100644 index 00000000000..d4cb511a44a --- /dev/null +++ b/arch/arm/mach-imx/cpuidle.c @@ -0,0 +1,80 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/cpuidle.h> +#include <linux/err.h> +#include <linux/hrtimer.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/slab.h> + +static struct cpuidle_device __percpu * imx_cpuidle_devices; + +static void __init imx_cpuidle_devices_uninit(void) +{ +	int cpu_id; +	struct cpuidle_device *dev; + +	for_each_possible_cpu(cpu_id) { +		dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); +		cpuidle_unregister_device(dev); +	} + +	free_percpu(imx_cpuidle_devices); +} + +int __init imx_cpuidle_init(struct cpuidle_driver *drv) +{ +	struct cpuidle_device *dev; +	int cpu_id, ret; + +	if (drv->state_count > CPUIDLE_STATE_MAX) { +		pr_err("%s: state_count exceeds maximum\n", __func__); +		return -EINVAL; +	} + +	ret = cpuidle_register_driver(drv); +	if (ret) { +		pr_err("%s: Failed to register cpuidle driver with error: %d\n", +			 __func__, ret); +		return ret; +	} + +	imx_cpuidle_devices = alloc_percpu(struct cpuidle_device); +	if (imx_cpuidle_devices == NULL) { +		ret = -ENOMEM; +		goto unregister_drv; +	} + +	/* initialize state data for each cpuidle_device */ +	for_each_possible_cpu(cpu_id) { +		dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); +		dev->cpu = cpu_id; +		dev->state_count = drv->state_count; + +		ret = cpuidle_register_device(dev); +		if (ret) { +			pr_err("%s: Failed to register cpu %u, error: %d\n", +				__func__, cpu_id, ret); +			goto uninit; +		} +	} + +	return 0; + +uninit: +	imx_cpuidle_devices_uninit(); + +unregister_drv: +	cpuidle_unregister_driver(drv); +	return ret; +}  |