diff options
author | Lina Iyer <lina.iyer@linaro.org> | 2014-12-02 10:39:15 -0700 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2015-01-13 17:56:52 +0300 |
commit | 7a81b453785f46e447f8c9b091eb0db1f9341774 (patch) | |
tree | 0223ef5fdd645e7b0bb69761e178880563d9865f /drivers/cpuidle | |
parent | b2dc35363c82fdd88a0f8081d0350c670683f48a (diff) |
qcom: cpuidle: Add cpuidle driver for QCOM cpus
Add cpuidle driver interface to allow cpus to go into idle states. Use
the cpuidle DT interface, common across ARM architectures, to provide
the idle state information to the cpuidle framework.
Supported modes at this time are Standby and Standalone Power Collapse.
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/Kconfig.arm | 7 | ||||
-rw-r--r-- | drivers/cpuidle/Makefile | 1 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-qcom.c | 99 |
3 files changed, 107 insertions, 0 deletions
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 8c16ab20fb15..e98993c872a2 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm @@ -63,3 +63,10 @@ config ARM_MVEBU_V7_CPUIDLE depends on ARCH_MVEBU help Select this to enable cpuidle on Armada 370, 38x and XP processors. + +config ARM_QCOM_CPUIDLE + bool "CPU Idle drivers for Qualcomm processors" + depends on ARCH_QCOM + select DT_IDLE_STATES + help + Select this to enable cpuidle for QCOM processors diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 4d177b916f75..6c222d536005 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o +obj-$(CONFIG_ARM_QCOM_CPUIDLE) += cpuidle-qcom.o ############################################################################### # MIPS drivers diff --git a/drivers/cpuidle/cpuidle-qcom.c b/drivers/cpuidle/cpuidle-qcom.c new file mode 100644 index 000000000000..aa6a6c9a3590 --- /dev/null +++ b/drivers/cpuidle/cpuidle-qcom.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Linaro Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/cpuidle.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <soc/qcom/pm.h> +#include "dt_idle_states.h" + +static struct qcom_cpu_pm_ops *lpm_ops; + +static int qcom_cpu_stby(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int ret; + + ret = lpm_ops->standby(NULL); + if (ret) + return ret; + + return index; +} + +static int qcom_cpu_spc(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int ret; + + ret = lpm_ops->spc(NULL); + if (ret) + return ret; + + return index; +} + +static struct cpuidle_driver qcom_cpuidle_driver = { + .name = "qcom_cpuidle", +}; + +static const struct of_device_id qcom_idle_state_match[] = { + { .compatible = "qcom,idle-state-stby", .data = qcom_cpu_stby }, + { .compatible = "qcom,idle-state-spc", .data = qcom_cpu_spc }, + { }, +}; + +static int qcom_cpuidle_probe(struct platform_device *pdev) +{ + struct cpuidle_driver *drv = &qcom_cpuidle_driver; + int ret; + + lpm_ops = pdev->dev.platform_data; + + /* Probe for other states, including standby */ + ret = dt_init_idle_driver(drv, qcom_idle_state_match, 0); + if (ret < 0) + return ret; + + /* + * We will not register for cpu's cpuidle device here, + * they will be registered as and when their power controllers + * are ready. + */ + return cpuidle_register_driver(drv); +} + +static struct platform_driver qcom_cpuidle = { + .probe = qcom_cpuidle_probe, + .driver = { + .name = "qcom_cpuidle", + }, +}; + +/* + * Register the driver early so the we have a successul registration + * when the device shows up. + * This way the cpuidle driver could be registered before the cpuidle + * devices are registered. + */ +static int __init qcom_cpuidle_driver_init(void) +{ + return platform_driver_register(&qcom_cpuidle); +} +core_initcall(qcom_cpuidle_driver_init); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CPUIDLE driver for QCOM SoC"); +MODULE_ALIAS("platform:qcom-cpuidle"); |