diff options
-rw-r--r-- | arch/arm/firmware/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/firmware/trusted_foundations.c | 20 | ||||
-rw-r--r-- | arch/arm/include/asm/firmware.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/trusted_foundations.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle-tegra114.c | 7 |
5 files changed, 40 insertions, 7 deletions
diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig index bb00ccf00d66..ad396af68e47 100644 --- a/arch/arm/firmware/Kconfig +++ b/arch/arm/firmware/Kconfig | |||
@@ -11,6 +11,7 @@ menu "Firmware options" | |||
11 | config TRUSTED_FOUNDATIONS | 11 | config TRUSTED_FOUNDATIONS |
12 | bool "Trusted Foundations secure monitor support" | 12 | bool "Trusted Foundations secure monitor support" |
13 | depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS | 13 | depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS |
14 | default y | ||
14 | help | 15 | help |
15 | Some devices (including most Tegra-based consumer devices on the | 16 | Some devices (including most Tegra-based consumer devices on the |
16 | market) are booted with the Trusted Foundations secure monitor | 17 | market) are booted with the Trusted Foundations secure monitor |
@@ -20,7 +21,7 @@ config TRUSTED_FOUNDATIONS | |||
20 | This option allows the kernel to invoke the secure monitor whenever | 21 | This option allows the kernel to invoke the secure monitor whenever |
21 | required on devices using Trusted Foundations. See | 22 | required on devices using Trusted Foundations. See |
22 | arch/arm/include/asm/trusted_foundations.h or the | 23 | arch/arm/include/asm/trusted_foundations.h or the |
23 | tl,trusted-foundations device tree binding documentation for details | 24 | tlm,trusted-foundations device tree binding documentation for details |
24 | on how to use it. | 25 | on how to use it. |
25 | 26 | ||
26 | Say n if you don't know what this is about. | 27 | Say n if you don't know what this is about. |
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c index ef1e3d8f4af0..3fb1b5a1dce9 100644 --- a/arch/arm/firmware/trusted_foundations.c +++ b/arch/arm/firmware/trusted_foundations.c | |||
@@ -22,6 +22,15 @@ | |||
22 | 22 | ||
23 | #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200 | 23 | #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200 |
24 | 24 | ||
25 | #define TF_CPU_PM 0xfffffffc | ||
26 | #define TF_CPU_PM_S3 0xffffffe3 | ||
27 | #define TF_CPU_PM_S2 0xffffffe6 | ||
28 | #define TF_CPU_PM_S2_NO_MC_CLK 0xffffffe5 | ||
29 | #define TF_CPU_PM_S1 0xffffffe4 | ||
30 | #define TF_CPU_PM_S1_NOFLUSH_L2 0xffffffe7 | ||
31 | |||
32 | static unsigned long cpu_boot_addr; | ||
33 | |||
25 | static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) | 34 | static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) |
26 | { | 35 | { |
27 | asm volatile( | 36 | asm volatile( |
@@ -41,13 +50,22 @@ static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) | |||
41 | 50 | ||
42 | static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr) | 51 | static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr) |
43 | { | 52 | { |
44 | tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0); | 53 | cpu_boot_addr = boot_addr; |
54 | tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, cpu_boot_addr, 0); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int tf_prepare_idle(void) | ||
60 | { | ||
61 | tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr); | ||
45 | 62 | ||
46 | return 0; | 63 | return 0; |
47 | } | 64 | } |
48 | 65 | ||
49 | static const struct firmware_ops trusted_foundations_ops = { | 66 | static const struct firmware_ops trusted_foundations_ops = { |
50 | .set_cpu_boot_addr = tf_set_cpu_boot_addr, | 67 | .set_cpu_boot_addr = tf_set_cpu_boot_addr, |
68 | .prepare_idle = tf_prepare_idle, | ||
51 | }; | 69 | }; |
52 | 70 | ||
53 | void register_trusted_foundations(struct trusted_foundations_platform_data *pd) | 71 | void register_trusted_foundations(struct trusted_foundations_platform_data *pd) |
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h index 15631300c238..2c9f10df7568 100644 --- a/arch/arm/include/asm/firmware.h +++ b/arch/arm/include/asm/firmware.h | |||
@@ -22,6 +22,10 @@ | |||
22 | */ | 22 | */ |
23 | struct firmware_ops { | 23 | struct firmware_ops { |
24 | /* | 24 | /* |
25 | * Inform the firmware we intend to enter CPU idle mode | ||
26 | */ | ||
27 | int (*prepare_idle)(void); | ||
28 | /* | ||
25 | * Enters CPU idle mode | 29 | * Enters CPU idle mode |
26 | */ | 30 | */ |
27 | int (*do_idle)(void); | 31 | int (*do_idle)(void); |
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h index 3bd36e2c5f2e..b5f7705abcb0 100644 --- a/arch/arm/include/asm/trusted_foundations.h +++ b/arch/arm/include/asm/trusted_foundations.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/printk.h> | 30 | #include <linux/printk.h> |
31 | #include <linux/bug.h> | 31 | #include <linux/bug.h> |
32 | #include <linux/of.h> | 32 | #include <linux/of.h> |
33 | #include <linux/cpu.h> | ||
34 | #include <linux/smp.h> | ||
33 | 35 | ||
34 | struct trusted_foundations_platform_data { | 36 | struct trusted_foundations_platform_data { |
35 | unsigned int version_major; | 37 | unsigned int version_major; |
@@ -47,10 +49,13 @@ static inline void register_trusted_foundations( | |||
47 | struct trusted_foundations_platform_data *pd) | 49 | struct trusted_foundations_platform_data *pd) |
48 | { | 50 | { |
49 | /* | 51 | /* |
50 | * If we try to register TF, this means the system needs it to continue. | 52 | * If the system requires TF and we cannot provide it, continue booting |
51 | * Its absence if thus a fatal error. | 53 | * but disable features that cannot be provided. |
52 | */ | 54 | */ |
53 | panic("No support for Trusted Foundations, stopping...\n"); | 55 | pr_err("No support for Trusted Foundations, continuing in degraded mode.\n"); |
56 | pr_err("Secondary processors as well as CPU PM will be disabled.\n"); | ||
57 | setup_max_cpus = 0; | ||
58 | cpu_idle_poll_ctrl(true); | ||
54 | } | 59 | } |
55 | 60 | ||
56 | static inline void of_register_trusted_foundations(void) | 61 | static inline void of_register_trusted_foundations(void) |
@@ -59,7 +64,7 @@ static inline void of_register_trusted_foundations(void) | |||
59 | * If we find the target should enable TF but does not support it, | 64 | * If we find the target should enable TF but does not support it, |
60 | * fail as the system won't be able to do much anyway | 65 | * fail as the system won't be able to do much anyway |
61 | */ | 66 | */ |
62 | if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations")) | 67 | if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations")) |
63 | register_trusted_foundations(NULL); | 68 | register_trusted_foundations(NULL); |
64 | } | 69 | } |
65 | #endif /* CONFIG_TRUSTED_FOUNDATIONS */ | 70 | #endif /* CONFIG_TRUSTED_FOUNDATIONS */ |
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index e0b87300243d..b5fb7c110c64 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/cpuidle.h> | 19 | #include <linux/cpuidle.h> |
20 | #include <linux/cpu_pm.h> | 20 | #include <linux/cpu_pm.h> |
21 | #include <linux/clockchips.h> | 21 | #include <linux/clockchips.h> |
22 | #include <asm/firmware.h> | ||
22 | 23 | ||
23 | #include <asm/cpuidle.h> | 24 | #include <asm/cpuidle.h> |
24 | #include <asm/suspend.h> | 25 | #include <asm/suspend.h> |
@@ -45,7 +46,11 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, | |||
45 | 46 | ||
46 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); | 47 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); |
47 | 48 | ||
48 | cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); | 49 | call_firmware_op(prepare_idle); |
50 | |||
51 | /* Do suspend by ourselves if the firmware does not implement it */ | ||
52 | if (call_firmware_op(do_idle) == -ENOSYS) | ||
53 | cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); | ||
49 | 54 | ||
50 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); | 55 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); |
51 | 56 | ||