diff options
author | Joseph Lo <josephl@nvidia.com> | 2012-10-31 05:41:15 -0400 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2012-11-15 17:09:20 -0500 |
commit | 0b25e25bef0e03c0465c3eb1119b32cb906db689 (patch) | |
tree | 1a36d929038a7f4e4c0fccc3b4ad8e126d787be3 | |
parent | 641b4ef8f1fea88803cc1ff3f34d93ba6bcd8106 (diff) |
ARM: tegra: cpuidle: separate cpuidle driver for different chips
The different Tegra chips may have different CPU idle states and data.
Individual CPU idle driver make it more easy to maintain.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle-tegra20.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle-tegra30.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle.c | 47 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle.h | 32 |
5 files changed, 184 insertions, 34 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index dcd4726ebbae..488159eaa429 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -15,9 +15,16 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o | |||
15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o | 15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o |
16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o | 16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o |
17 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o | 17 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o |
18 | ifeq ($(CONFIG_CPU_IDLE),y) | ||
19 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o | ||
20 | endif | ||
18 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o | 21 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o |
19 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o | 22 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o |
20 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o | 23 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o |
24 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o | ||
25 | ifeq ($(CONFIG_CPU_IDLE),y) | ||
26 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o | ||
27 | endif | ||
21 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 28 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
22 | obj-$(CONFIG_SMP) += reset.o | 29 | obj-$(CONFIG_SMP) += reset.o |
23 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 30 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c new file mode 100644 index 000000000000..d32e8b0dbd4f --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle-tegra20.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * CPU idle driver for Tegra CPUs | ||
3 | * | ||
4 | * Copyright (c) 2010-2012, NVIDIA Corporation. | ||
5 | * Copyright (c) 2011 Google, Inc. | ||
6 | * Author: Colin Cross <ccross@android.com> | ||
7 | * Gary King <gking@nvidia.com> | ||
8 | * | ||
9 | * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/cpuidle.h> | ||
25 | |||
26 | #include <asm/cpuidle.h> | ||
27 | |||
28 | static struct cpuidle_driver tegra_idle_driver = { | ||
29 | .name = "tegra_idle", | ||
30 | .owner = THIS_MODULE, | ||
31 | .en_core_tk_irqen = 1, | ||
32 | .state_count = 1, | ||
33 | .states = { | ||
34 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); | ||
39 | |||
40 | int __init tegra20_cpuidle_init(void) | ||
41 | { | ||
42 | int ret; | ||
43 | unsigned int cpu; | ||
44 | struct cpuidle_device *dev; | ||
45 | struct cpuidle_driver *drv = &tegra_idle_driver; | ||
46 | |||
47 | ret = cpuidle_register_driver(&tegra_idle_driver); | ||
48 | if (ret) { | ||
49 | pr_err("CPUidle driver registration failed\n"); | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | for_each_possible_cpu(cpu) { | ||
54 | dev = &per_cpu(tegra_idle_device, cpu); | ||
55 | dev->cpu = cpu; | ||
56 | |||
57 | dev->state_count = drv->state_count; | ||
58 | ret = cpuidle_register_device(dev); | ||
59 | if (ret) { | ||
60 | pr_err("CPU%u: CPUidle device registration failed\n", | ||
61 | cpu); | ||
62 | return ret; | ||
63 | } | ||
64 | } | ||
65 | return 0; | ||
66 | } | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c new file mode 100644 index 000000000000..37e75512f697 --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * CPU idle driver for Tegra CPUs | ||
3 | * | ||
4 | * Copyright (c) 2010-2012, NVIDIA Corporation. | ||
5 | * Copyright (c) 2011 Google, Inc. | ||
6 | * Author: Colin Cross <ccross@android.com> | ||
7 | * Gary King <gking@nvidia.com> | ||
8 | * | ||
9 | * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/cpuidle.h> | ||
25 | |||
26 | #include <asm/cpuidle.h> | ||
27 | |||
28 | static struct cpuidle_driver tegra_idle_driver = { | ||
29 | .name = "tegra_idle", | ||
30 | .owner = THIS_MODULE, | ||
31 | .en_core_tk_irqen = 1, | ||
32 | .state_count = 1, | ||
33 | .states = { | ||
34 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); | ||
39 | |||
40 | int __init tegra30_cpuidle_init(void) | ||
41 | { | ||
42 | int ret; | ||
43 | unsigned int cpu; | ||
44 | struct cpuidle_device *dev; | ||
45 | struct cpuidle_driver *drv = &tegra_idle_driver; | ||
46 | |||
47 | ret = cpuidle_register_driver(&tegra_idle_driver); | ||
48 | if (ret) { | ||
49 | pr_err("CPUidle driver registration failed\n"); | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | for_each_possible_cpu(cpu) { | ||
54 | dev = &per_cpu(tegra_idle_device, cpu); | ||
55 | dev->cpu = cpu; | ||
56 | |||
57 | dev->state_count = drv->state_count; | ||
58 | ret = cpuidle_register_device(dev); | ||
59 | if (ret) { | ||
60 | pr_err("CPU%u: CPUidle device registration failed\n", | ||
61 | cpu); | ||
62 | return ret; | ||
63 | } | ||
64 | } | ||
65 | return 0; | ||
66 | } | ||
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index 4e0b07c7963c..d0651397aec7 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c | |||
@@ -23,47 +23,26 @@ | |||
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/cpuidle.h> | ||
27 | 26 | ||
28 | #include <asm/cpuidle.h> | 27 | #include "fuse.h" |
29 | 28 | #include "cpuidle.h" | |
30 | struct cpuidle_driver tegra_idle_driver = { | ||
31 | .name = "tegra_idle", | ||
32 | .owner = THIS_MODULE, | ||
33 | .en_core_tk_irqen = 1, | ||
34 | .state_count = 1, | ||
35 | .states = { | ||
36 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
37 | }, | ||
38 | }; | ||
39 | |||
40 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); | ||
41 | 29 | ||
42 | static int __init tegra_cpuidle_init(void) | 30 | static int __init tegra_cpuidle_init(void) |
43 | { | 31 | { |
44 | int ret; | 32 | int ret; |
45 | unsigned int cpu; | ||
46 | struct cpuidle_device *dev; | ||
47 | struct cpuidle_driver *drv = &tegra_idle_driver; | ||
48 | 33 | ||
49 | ret = cpuidle_register_driver(&tegra_idle_driver); | 34 | switch (tegra_chip_id) { |
50 | if (ret) { | 35 | case TEGRA20: |
51 | pr_err("CPUidle driver registration failed\n"); | 36 | ret = tegra20_cpuidle_init(); |
52 | return ret; | 37 | break; |
38 | case TEGRA30: | ||
39 | ret = tegra30_cpuidle_init(); | ||
40 | break; | ||
41 | default: | ||
42 | ret = -ENODEV; | ||
43 | break; | ||
53 | } | 44 | } |
54 | 45 | ||
55 | for_each_possible_cpu(cpu) { | 46 | return ret; |
56 | dev = &per_cpu(tegra_idle_device, cpu); | ||
57 | dev->cpu = cpu; | ||
58 | |||
59 | dev->state_count = drv->state_count; | ||
60 | ret = cpuidle_register_device(dev); | ||
61 | if (ret) { | ||
62 | pr_err("CPU%u: CPUidle device registration failed\n", | ||
63 | cpu); | ||
64 | return ret; | ||
65 | } | ||
66 | } | ||
67 | return 0; | ||
68 | } | 47 | } |
69 | device_initcall(tegra_cpuidle_init); | 48 | device_initcall(tegra_cpuidle_init); |
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h new file mode 100644 index 000000000000..496204d34e55 --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __MACH_TEGRA_CPUIDLE_H | ||
18 | #define __MACH_TEGRA_CPUIDLE_H | ||
19 | |||
20 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
21 | int tegra20_cpuidle_init(void); | ||
22 | #else | ||
23 | static inline int tegra20_cpuidle_init(void) { return -ENODEV; } | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
27 | int tegra30_cpuidle_init(void); | ||
28 | #else | ||
29 | static inline int tegra30_cpuidle_init(void) { return -ENODEV; } | ||
30 | #endif | ||
31 | |||
32 | #endif | ||