diff mbox

[v3,4/5] ARM: tegra: set CPU reset handler with firmware op

Message ID 1376360992-1508-5-git-send-email-acourbot@nvidia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alexandre Courbot Aug. 13, 2013, 2:29 a.m. UTC
Use a firmware operation to set the CPU reset handler and only resort to
doing it ourselves if there is none defined.

This supports the booting of secondary CPUs on devices using a TrustZone
secure monitor.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 arch/arm/mach-tegra/reset.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Comments

Stephen Warren Aug. 14, 2013, 9:40 p.m. UTC | #1
On 08/12/2013 08:29 PM, Alexandre Courbot wrote:
> Use a firmware operation to set the CPU reset handler and only resort to
> doing it ourselves if there is none defined.
> 
> This supports the booting of secondary CPUs on devices using a TrustZone
> secure monitor.

> diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c

> +	err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
> +	switch (err) {
> +	case -ENOSYS:
> +		tegra_cpu_reset_handler_set(reset_address);
> +		/* pass-through */
> +	case 0:
> +		is_enabled = true;
> +		break;
> +	default:
> +		pr_crit("Cannot set CPU reset handler: %d\n", err);
> +		BUG();
> +	}

Instead of trying and failing, does it make sense to register
tegra_cpu_reset_handler_set() as the set_cpu_boot_addr firmware op when
there is no firmware present? That would simplify all call-sites of any
firmware op.
Alexandre Courbot Aug. 18, 2013, 8:37 a.m. UTC | #2
On Thu, Aug 15, 2013 at 6:40 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 08/12/2013 08:29 PM, Alexandre Courbot wrote:
>> Use a firmware operation to set the CPU reset handler and only resort to
>> doing it ourselves if there is none defined.
>>
>> This supports the booting of secondary CPUs on devices using a TrustZone
>> secure monitor.
>
>> diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
>
>> +     err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
>> +     switch (err) {
>> +     case -ENOSYS:
>> +             tegra_cpu_reset_handler_set(reset_address);
>> +             /* pass-through */
>> +     case 0:
>> +             is_enabled = true;
>> +             break;
>> +     default:
>> +             pr_crit("Cannot set CPU reset handler: %d\n", err);
>> +             BUG();
>> +     }
>
> Instead of trying and failing, does it make sense to register
> tegra_cpu_reset_handler_set() as the set_cpu_boot_addr firmware op when
> there is no firmware present? That would simplify all call-sites of any
> firmware op.

We discussed that point in v2 already IIRC (that is some time ago).
The reason I did it this way is because I wanted to follow the way
Tomasz was using his interface with Exynos - it seemed appropriate
that all users of an interface use it the same way. But if you prefer
to use a "non-firmware" firmware_ops for Tegra, I have absolutely
nothing against this.

Thanks,
Alex.
diff mbox

Patch

diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 6964117..fc9cf03 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -21,6 +21,7 @@ 
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/firmware.h>
 
 #include "iomap.h"
 #include "irammap.h"
@@ -65,6 +66,7 @@  static void __init tegra_cpu_reset_handler_enable(void)
 	void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
 	const u32 reset_address = TEGRA_IRAM_RESET_BASE +
 						tegra_cpu_reset_handler_offset;
+	int err;
 
 	BUG_ON(is_enabled);
 	BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
@@ -72,9 +74,18 @@  static void __init tegra_cpu_reset_handler_enable(void)
 	memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
 			tegra_cpu_reset_handler_size);
 
-	tegra_cpu_reset_handler_set(reset_address);
-
-	is_enabled = true;
+	err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
+	switch (err) {
+	case -ENOSYS:
+		tegra_cpu_reset_handler_set(reset_address);
+		/* pass-through */
+	case 0:
+		is_enabled = true;
+		break;
+	default:
+		pr_crit("Cannot set CPU reset handler: %d\n", err);
+		BUG();
+	}
 }
 
 void __init tegra_cpu_reset_handler_init(void)