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
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commitd31a13afc518d2e23e880b938e727d2451ebaaf4 (patch)
treeb328d2476d5558d9ce38776fc5bf9c17bd95097a /arch/arm/mach-imx
parent66e110c3a47a03890ab6bed3d2c348e1926d484c (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 b38a54e2b280..17cde76138b4 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -225,6 +225,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;
}