diff options
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/Kconfig.arm | 14 | ||||
-rw-r--r-- | drivers/cpuidle/Makefile | 2 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-armada-370-xp.c | 93 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-big_little.c | 12 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-mvebu-v7.c | 150 |
5 files changed, 169 insertions, 102 deletions
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index a186dec8e5df..38cff69ffe06 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm @@ -1,15 +1,9 @@ # # ARM CPU Idle drivers # -config ARM_ARMADA_370_XP_CPUIDLE - bool "CPU Idle Driver for Armada 370/XP family processors" - depends on ARCH_MVEBU - help - Select this to enable cpuidle on Armada 370/XP processors. - config ARM_BIG_LITTLE_CPUIDLE bool "Support for ARM big.LITTLE processors" - depends on ARCH_VEXPRESS_TC2_PM + depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS depends on MCPM select ARM_CPU_SUSPEND select CPU_IDLE_MULTIPLE_DRIVERS @@ -62,3 +56,9 @@ config ARM_EXYNOS_CPUIDLE depends on ARCH_EXYNOS help Select this to enable cpuidle for Exynos processors + +config ARM_MVEBU_V7_CPUIDLE + bool "CPU Idle Driver for mvebu v7 family processors" + depends on ARCH_MVEBU + help + Select this to enable cpuidle on Armada 370, 38x and XP processors. diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index d8bb1ff72561..11edb31c55e9 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o ################################################################################## # ARM SoC drivers -obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o +obj-$(CONFIG_ARM_MVEBU_V7_CPUIDLE) += cpuidle-mvebu-v7.o obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o obj-$(CONFIG_ARM_CLPS711X_CPUIDLE) += cpuidle-clps711x.o obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c deleted file mode 100644 index a5fba0287bfb..000000000000 --- a/drivers/cpuidle/cpuidle-armada-370-xp.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Marvell Armada 370 and Armada XP SoC cpuidle driver - * - * Copyright (C) 2014 Marvell - * - * Nadav Haklai <nadavh@marvell.com> - * Gregory CLEMENT <gregory.clement@free-electrons.com> - * - * 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. - * - * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com> - */ - -#include <linux/cpu_pm.h> -#include <linux/cpuidle.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/suspend.h> -#include <linux/platform_device.h> -#include <asm/cpuidle.h> - -#define ARMADA_370_XP_MAX_STATES 3 -#define ARMADA_370_XP_FLAG_DEEP_IDLE 0x10000 - -static int (*armada_370_xp_cpu_suspend)(int); - -static int armada_370_xp_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - int ret; - bool deepidle = false; - cpu_pm_enter(); - - if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE) - deepidle = true; - - ret = armada_370_xp_cpu_suspend(deepidle); - if (ret) - return ret; - - cpu_pm_exit(); - - return index; -} - -static struct cpuidle_driver armada_370_xp_idle_driver = { - .name = "armada_370_xp_idle", - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = armada_370_xp_enter_idle, - .exit_latency = 10, - .power_usage = 50, - .target_residency = 100, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "Idle", - .desc = "CPU power down", - }, - .states[2] = { - .enter = armada_370_xp_enter_idle, - .exit_latency = 100, - .power_usage = 5, - .target_residency = 1000, - .flags = CPUIDLE_FLAG_TIME_VALID | - ARMADA_370_XP_FLAG_DEEP_IDLE, - .name = "Deep idle", - .desc = "CPU and L2 Fabric power down", - }, - .state_count = ARMADA_370_XP_MAX_STATES, -}; - -static int armada_370_xp_cpuidle_probe(struct platform_device *pdev) -{ - - armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data); - return cpuidle_register(&armada_370_xp_idle_driver, NULL); -} - -static struct platform_driver armada_370_xp_cpuidle_plat_driver = { - .driver = { - .name = "cpuidle-armada-370-xp", - .owner = THIS_MODULE, - }, - .probe = armada_370_xp_cpuidle_probe, -}; - -module_platform_driver(armada_370_xp_cpuidle_plat_driver); - -MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>"); -MODULE_DESCRIPTION("Armada 370/XP cpu idle driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index b45fc6249041..344d79fa3407 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c @@ -163,14 +163,24 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id) return 0; } +static const struct of_device_id compatible_machine_match[] = { + { .compatible = "arm,vexpress,v2p-ca15_a7" }, + { .compatible = "samsung,exynos5420" }, + {}, +}; + static int __init bl_idle_init(void) { int ret; + struct device_node *root = of_find_node_by_path("/"); + + if (!root) + return -ENODEV; /* * Initialize the driver just for a compliant set of machines */ - if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7")) + if (!of_match_node(compatible_machine_match, root)) return -ENODEV; /* * For now the differentiation between little and big cores diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c new file mode 100644 index 000000000000..45371bb16214 --- /dev/null +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c @@ -0,0 +1,150 @@ +/* + * Marvell Armada 370, 38x and XP SoC cpuidle driver + * + * Copyright (C) 2014 Marvell + * + * Nadav Haklai <nadavh@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * 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. + * + * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com> + */ + +#include <linux/cpu_pm.h> +#include <linux/cpuidle.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/suspend.h> +#include <linux/platform_device.h> +#include <asm/cpuidle.h> + +#define MVEBU_V7_FLAG_DEEP_IDLE 0x10000 + +static int (*mvebu_v7_cpu_suspend)(int); + +static int mvebu_v7_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int ret; + bool deepidle = false; + cpu_pm_enter(); + + if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE) + deepidle = true; + + ret = mvebu_v7_cpu_suspend(deepidle); + if (ret) + return ret; + + cpu_pm_exit(); + + return index; +} + +static struct cpuidle_driver armadaxp_idle_driver = { + .name = "armada_xp_idle", + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = mvebu_v7_enter_idle, + .exit_latency = 10, + .power_usage = 50, + .target_residency = 100, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "MV CPU IDLE", + .desc = "CPU power down", + }, + .states[2] = { + .enter = mvebu_v7_enter_idle, + .exit_latency = 100, + .power_usage = 5, + .target_residency = 1000, + .flags = CPUIDLE_FLAG_TIME_VALID | + MVEBU_V7_FLAG_DEEP_IDLE, + .name = "MV CPU DEEP IDLE", + .desc = "CPU and L2 Fabric power down", + }, + .state_count = 3, +}; + +static struct cpuidle_driver armada370_idle_driver = { + .name = "armada_370_idle", + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = mvebu_v7_enter_idle, + .exit_latency = 100, + .power_usage = 5, + .target_residency = 1000, + .flags = (CPUIDLE_FLAG_TIME_VALID | + MVEBU_V7_FLAG_DEEP_IDLE), + .name = "Deep Idle", + .desc = "CPU and L2 Fabric power down", + }, + .state_count = 2, +}; + +static struct cpuidle_driver armada38x_idle_driver = { + .name = "armada_38x_idle", + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = mvebu_v7_enter_idle, + .exit_latency = 10, + .power_usage = 5, + .target_residency = 100, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "Idle", + .desc = "CPU and SCU power down", + }, + .state_count = 2, +}; + +static int mvebu_v7_cpuidle_probe(struct platform_device *pdev) +{ + mvebu_v7_cpu_suspend = pdev->dev.platform_data; + + if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-xp")) + return cpuidle_register(&armadaxp_idle_driver, NULL); + else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-370")) + return cpuidle_register(&armada370_idle_driver, NULL); + else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-38x")) + return cpuidle_register(&armada38x_idle_driver, NULL); + else + return -EINVAL; +} + +static struct platform_driver armadaxp_cpuidle_plat_driver = { + .driver = { + .name = "cpuidle-armada-xp", + .owner = THIS_MODULE, + }, + .probe = mvebu_v7_cpuidle_probe, +}; + +module_platform_driver(armadaxp_cpuidle_plat_driver); + +static struct platform_driver armada370_cpuidle_plat_driver = { + .driver = { + .name = "cpuidle-armada-370", + .owner = THIS_MODULE, + }, + .probe = mvebu_v7_cpuidle_probe, +}; + +module_platform_driver(armada370_cpuidle_plat_driver); + +static struct platform_driver armada38x_cpuidle_plat_driver = { + .driver = { + .name = "cpuidle-armada-38x", + .owner = THIS_MODULE, + }, + .probe = mvebu_v7_cpuidle_probe, +}; + +module_platform_driver(armada38x_cpuidle_plat_driver); + +MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>"); +MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver"); +MODULE_LICENSE("GPL"); |