Skip to content

Commit b3d09a0

Browse files
Carlos Leijatmlind
authored andcommitted
ARM: OMAP4: PM: update ROM return address for OSWR and OFF
We need to add a dummy smc call to the cpuidle wakeup path to force the ROM code to save the return address after MMU is enabled again. This is needed to prevent random hangs on secure devices like droid4. Otherwise the system will eventually hang when entering deeper SoC idle states with the core and mpu domains in open-switch retention (OSWR). The hang happens as the ROM code tries to use the earlier physical return address set by omap-headsmp.S with MMU off while waking up CPU1 again. The hangs started happening in theory already with commit caf8c87 ("ARM: OMAP2+: Allow core oswr for omap4"), but in practise the issue went unnoticed as various drivers were often blocking any deeper idle states with hardware autoidle features. This patch is based on an earlier TI Linux kernel tree commit 92f0b30 ("OMAP4: PM: update ROM return address for OSWR and OFF") written by Carlos Leija <[email protected]>, Praneeth Bajjuri <[email protected]>, and Bryan Buckley <[email protected]>. A later version of the patch was updated to use CPU_PM notifiers by Tero Kristo <[email protected]>. Signed-off-by: Carlos Leija <[email protected]> Signed-off-by: Praneeth Bajjuri <[email protected]> Signed-off-by: Bryan Buckley <[email protected]> Signed-off-by: Tero Kristo <[email protected]> Fixes: caf8c87 ("ARM: OMAP2+: Allow core oswr for omap4") Reported-by: Carl Philipp Klemm <[email protected]> Reported-by: Merlijn Wajer <[email protected]> Cc: Ivan Jelincic <[email protected]> Cc: Pavel Machek <[email protected]> Cc: Sebastian Reichel <[email protected]> Cc: Tero Kristo <[email protected]> [[email protected]: updated to apply, updated description] Signed-off-by: Tony Lindgren <[email protected]>
1 parent 30916fa commit b3d09a0

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

arch/arm/mach-omap2/omap-secure.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
#include <linux/arm-smccc.h>
12+
#include <linux/cpu_pm.h>
1213
#include <linux/kernel.h>
1314
#include <linux/init.h>
1415
#include <linux/io.h>
@@ -20,6 +21,7 @@
2021

2122
#include "common.h"
2223
#include "omap-secure.h"
24+
#include "soc.h"
2325

2426
static phys_addr_t omap_secure_memblock_base;
2527

@@ -213,3 +215,40 @@ void __init omap_secure_init(void)
213215
{
214216
omap_optee_init_check();
215217
}
218+
219+
/*
220+
* Dummy dispatcher call after core OSWR and MPU off. Updates the ROM return
221+
* address after MMU has been re-enabled after CPU1 has been woken up again.
222+
* Otherwise the ROM code will attempt to use the earlier physical return
223+
* address that got set with MMU off when waking up CPU1. Only used on secure
224+
* devices.
225+
*/
226+
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
227+
{
228+
switch (cmd) {
229+
case CPU_CLUSTER_PM_EXIT:
230+
omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
231+
FLAG_START_CRITICAL,
232+
0, 0, 0, 0, 0);
233+
break;
234+
default:
235+
break;
236+
}
237+
238+
return NOTIFY_OK;
239+
}
240+
241+
static struct notifier_block secure_notifier_block = {
242+
.notifier_call = cpu_notifier,
243+
};
244+
245+
static int __init secure_pm_init(void)
246+
{
247+
if (omap_type() == OMAP2_DEVICE_TYPE_GP || !soc_is_omap44xx())
248+
return 0;
249+
250+
cpu_pm_register_notifier(&secure_notifier_block);
251+
252+
return 0;
253+
}
254+
omap_arch_initcall(secure_pm_init);

arch/arm/mach-omap2/omap-secure.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107
5151

5252
/* Secure PPA(Primary Protected Application) APIs */
53+
#define OMAP4_PPA_SERVICE_0 0x21
5354
#define OMAP4_PPA_L2_POR_INDEX 0x23
5455
#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
5556

0 commit comments

Comments
 (0)