MLK-14241-5: ARM: imx: pm-rpmsg: add heartbeat_off support in bootargs
authorRobin Gong <yibin.gong@nxp.com>
Thu, 23 Feb 2017 10:07:56 +0000 (18:07 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:10:47 +0000 (15:10 -0500)
If bootargs with 'heartbeat_off' setting, will remove heartbeat feature
in kernel and M4 will not reset A7 even A7 hang. It's useful for debug
in A7 if you want to connect debugger, otherwise M4 will reset A7 core
if A7 core halt more than 30s.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
arch/arm/mach-imx/pm-rpmsg.c

index 9708b0c..9407929 100644 (file)
@@ -34,6 +34,7 @@
 enum pm_rpmsg_cmd {
        PM_RPMSG_MODE,
        PM_RPMSG_HEART_BEAT,
+       PM_RPMSG_HEART_BEAT_OFF,
 };
 
 enum pm_rpmsg_power_mode {
@@ -62,6 +63,8 @@ static struct pm_rpmsg_info pm_rpmsg;
 
 static struct delayed_work heart_beat_work;
 
+static bool heartbeat_off;
+
 struct pm_rpmsg_data {
        struct imx_rpmsg_head header;
        u8 data;
@@ -162,6 +165,20 @@ void pm_reboot_notify_m4(void)
 
 }
 
+void  pm_heartbeat_off_notify_m4(bool enter)
+{
+       struct pm_rpmsg_data msg;
+
+       msg.header.cate = IMX_RMPSG_LIFECYCLE;
+       msg.header.major = IMX_RMPSG_MAJOR;
+       msg.header.minor = IMX_RMPSG_MINOR;
+       msg.header.type = PM_RPMSG_TYPE;
+       msg.header.cmd = PM_RPMSG_HEART_BEAT_OFF;
+       msg.data = enter ? 0 : 1;
+
+       pm_send_message(&msg, &pm_rpmsg, true);
+}
+
 static void pm_heart_beat_work_handler(struct work_struct *work)
 {
        struct pm_rpmsg_data msg;
@@ -169,19 +186,24 @@ static void pm_heart_beat_work_handler(struct work_struct *work)
        /* Notify M4 side A7 in RUN mode at boot time */
        if (pm_rpmsg.first_flag) {
                pm_vlls_notify_m4(false);
+
+               pm_heartbeat_off_notify_m4(heartbeat_off);
+
                pm_rpmsg.first_flag = false;
        }
 
-       msg.header.cate = IMX_RMPSG_LIFECYCLE;
-       msg.header.major = IMX_RMPSG_MAJOR;
-       msg.header.minor = IMX_RMPSG_MINOR;
-       msg.header.type = HEATBEAT_RPMSG_TYPE;
-       msg.header.cmd = PM_RPMSG_HEART_BEAT;
-       msg.data = 0;
-       pm_send_message(&msg, &pm_rpmsg, false);
-
-       schedule_delayed_work(&heart_beat_work,
-               msecs_to_jiffies(30000));
+       if (!heartbeat_off) {
+               msg.header.cate = IMX_RMPSG_LIFECYCLE;
+               msg.header.major = IMX_RMPSG_MAJOR;
+               msg.header.minor = IMX_RMPSG_MINOR;
+               msg.header.type = HEATBEAT_RPMSG_TYPE;
+               msg.header.cmd = PM_RPMSG_HEART_BEAT;
+               msg.data = 0;
+               pm_send_message(&msg, &pm_rpmsg, false);
+
+               schedule_delayed_work(&heart_beat_work,
+                       msecs_to_jiffies(30000));
+       }
 }
 
 static int pm_restart_handler(struct notifier_block *this, unsigned long mode,
@@ -306,6 +328,14 @@ static struct platform_driver pm_heartbeat_driver = {
        .probe = pm_heartbeat_probe,
 };
 
+static int __init setup_heartbeat(char *str)
+{
+       heartbeat_off = true;
+
+       return 1;
+};
+__setup("heartbeat_off", setup_heartbeat);
+
 module_platform_driver(pm_heartbeat_driver);
 
 MODULE_DESCRIPTION("Freescale PM rpmsg driver");