summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2018-05-15 01:23:16 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:31:45 +0800
commitf8a89618b31d9a7aa9e84a4fcbda224a5837bc19 (patch)
tree9edeb9ae87625f9d6e1f1bf709279b215a8790fe /arch/arm/mach-imx
parentadf42a741ba8f6954dca4e2d1620ceea1d193d30 (diff)
MLK-18308-2: ARM: imx: imx7ulp: add poweroff feature
On i.mx7ULP, poweroff kernel by sending rpmsg message to M4, and M4 poweroff CA7. Then M4 can power on CA7 again by type 'V' command in its console or press POWERON key once M4 support POWERON. Note: CA7 should enter VLLS mode firstly before poweroff by M4. Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/common.h1
-rw-r--r--arch/arm/mach-imx/pm-imx7ulp.c9
-rw-r--r--arch/arm/mach-imx/pm-rpmsg.c16
3 files changed, 22 insertions, 4 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index ab12c6c8dd10..02529cda7cb1 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -229,6 +229,7 @@ void imx6ull_pm_init(void);
void imx7d_pm_init(void);
void imx7ulp_pm_init(void);
void imx7ulp_enable_nmi(void);
+void imx7ulp_poweroff(void);
void imx6q_pm_set_ccm_base(void __iomem *base);
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-imx/pm-imx7ulp.c b/arch/arm/mach-imx/pm-imx7ulp.c
index b4789a305742..777d3ca98eeb 100644
--- a/arch/arm/mach-imx/pm-imx7ulp.c
+++ b/arch/arm/mach-imx/pm-imx7ulp.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
- * Copyright 2017 NXP
+ * Copyright 2017-2018 NXP
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -516,6 +516,13 @@ static int imx7ulp_pm_enter(suspend_state_t state)
return 0;
}
+/* Put CA7 into VLLS mode before M4 power off CA7 */
+void imx7ulp_poweroff(void)
+{
+ imx7ulp_set_lpm(VLLS);
+ cpu_suspend(0, imx7ulp_suspend_finish);
+}
+
static int imx7ulp_pm_valid(suspend_state_t state)
{
return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
diff --git a/arch/arm/mach-imx/pm-rpmsg.c b/arch/arm/mach-imx/pm-rpmsg.c
index 3bfd6f9eadac..e760379cdf85 100644
--- a/arch/arm/mach-imx/pm-rpmsg.c
+++ b/arch/arm/mach-imx/pm-rpmsg.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 NXP
+ * Copyright 2017-2018 NXP
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include <linux/rpmsg.h>
#include <linux/uaccess.h>
#include <linux/virtio.h>
+#include "common.h"
#define RPMSG_TIMEOUT 1000
@@ -145,9 +146,10 @@ void pm_shutdown_notify_m4(void)
msg.header.type = PM_RPMSG_TYPE;
msg.header.cmd = PM_RPMSG_MODE;
msg.data = PM_RPMSG_SHUTDOWN;
+ /* No ACK from M4 */
+ pm_send_message(&msg, &pm_rpmsg, false);
- pm_send_message(&msg, &pm_rpmsg, true);
-
+ imx7ulp_poweroff();
}
void pm_reboot_notify_m4(void)
@@ -206,6 +208,12 @@ static void pm_heart_beat_work_handler(struct work_struct *work)
}
}
+static void pm_poweroff_rpmsg(void)
+{
+ pm_shutdown_notify_m4();
+ pr_emerg("Unable to poweroff system\n");
+}
+
static int pm_restart_handler(struct notifier_block *this, unsigned long mode,
void *cmd)
{
@@ -238,6 +246,8 @@ static int pm_rpmsg_probe(struct rpmsg_device *rpdev)
if (ret)
dev_err(&rpdev->dev, "cannot register restart handler\n");
+ pm_power_off = pm_poweroff_rpmsg;
+
return 0;
}