msm-poweroff: Store restart reason

After cold reset is introduced, the phone is cold reset instead of
warm reset, such as panic. In this case, the power up reason saved
in shared memory will be lost. Consequently, the power up reason on
next boot up time will be normal boot instead of correct ones. To
resolve this issue, we can use the two spared pmic registers which
are power lost safe to save the restart reason for these cases.

Motorola definition of AP panic bit set in extra info pmic reg
conflicts with QC definition of Warm reboot bit set in extra info reg
move Mot bit to available position to avoid conflict

Force a cold reboot for the command "adb reboot bootloader"
to avoid the warm boot when user tries to continue boot from boot menu.

For early kernel panic before PMIC is initialized, the function
qpnp_pon_store_extra_reset_info will fail. Need to set IMEM flag
for fail safe in this case.

For post-panic, post-wdt, post-pmicwdt reboot, we do cold reset.
And set the PMIC register accordingly, to nofity BL the special
reboot behavior.

Configure panic as warm restart, so that we have chance to get panic logs.

According to SR 01277290, 0x88D and 0x88E are spare registers for PMIC
where we could store oem specific reset information

Ported from: https://gerrit.mot.com/1446282

Change-Id: I6704c801435c6586dbe64259c214dcdc926b07cf
Signed-off-by: zhaoxp3 <zhaoxp3@motorola.com>
Reviewed-on: https://gerrit.mot.com/1499584
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Wang Wang <wangwang1@lenovo.com>
Submit-Approved: Jira Key
This commit is contained in:
zhaoxp3 authored and Gilberto Gambugge committed 2023-06-01 00:47:04 -03:00
1 parent 510a378881
commit d177ede646
3 files changed
+91 -1

No files matched your search

+46
View File
@@ -86,6 +86,8 @@
#define QPNP_PON_S3_DBC_CTL(pon) ((pon)->base + 0x75)
#define QPNP_PON_SMPL_CTL(pon) ((pon)->base + 0x7F)
#define QPNP_PON_TRIGGER_EN(pon) ((pon)->base + 0x80)
#define QPNP_PON_PERPH_RB_SPARE(pon) ((pon)->base + 0x8C)
#define QPNP_PON_DVDD_RB_SPARE(pon) ((pon)->base + 0x8D)
#define QPNP_PON_XVDD_RB_SPARE(pon) ((pon)->base + 0x8E)
#define QPNP_PON_SOFT_RB_SPARE(pon) ((pon)->base + 0x8F)
#define QPNP_PON_SEC_ACCESS(pon) ((pon)->base + 0xD0)
@@ -383,6 +385,50 @@ int qpnp_pon_set_restart_reason(enum pon_restart_reason reason)
}
EXPORT_SYMBOL(qpnp_pon_set_restart_reason);
/**
* qpnp_pon_store_extra_reset_info - Store extra reset info in PMIC register.
*
* Returns = 0 if PMIC feature is not available or store restart reason
* successfully.
* Returns > 0 for errors
*
* This function is used to store extra reset info in PMIC spare register
* which can be preserved during reset.
*/
int qpnp_pon_store_extra_reset_info(u16 mask, u16 val)
{
int rc = 0;
struct qpnp_pon *pon = sys_reset_dev;
if (!pon)
return 0;
if (mask & 0xFF) {
rc = qpnp_pon_masked_write(pon, QPNP_PON_DVDD_RB_SPARE(pon),
(mask & 0xFF), (val & 0xFF));
if (rc) {
dev_err(pon->dev,
"Failed to store extra reset info to 0x%x\n",
QPNP_PON_DVDD_RB_SPARE(pon));
return rc;
}
}
if (mask & 0xFF00) {
rc = qpnp_pon_masked_write(pon, QPNP_PON_XVDD_RB_SPARE(pon),
((mask >> 8) & 0xFF), ((val >> 8) & 0xFF));
if (rc) {
dev_err(pon->dev,
"Failed to store extra reset info to 0x%x\n",
QPNP_PON_XVDD_RB_SPARE(pon));
return rc;
}
}
return rc;
}
EXPORT_SYMBOL(qpnp_pon_store_extra_reset_info);
/*
* qpnp_pon_check_hard_reset_stored() - Checks if the PMIC need to
* store hard reset reason.
+33 -1
View File
@@ -490,7 +490,7 @@ static void msm_restart_prepare(const char *cmd)
pr_info("Forcing a warm reset of the system\n");
/* Hard reset the PMIC unless memory contents must be maintained. */
if (force_warm_reboot || need_warm_reset)
if (force_warm_reboot || in_panic)
qpnp_pon_system_pwr_off(PON_POWER_OFF_WARM_RESET);
else
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
@@ -500,6 +500,14 @@ static void msm_restart_prepare(const char *cmd)
qpnp_pon_set_restart_reason(
PON_RESTART_REASON_BOOTLOADER);
__raw_writel(0x77665500, restart_reason);
/* set reboot_bl flag in PMIC for cold reset */
qpnp_pon_store_extra_reset_info(RESET_EXTRA_REBOOT_BL_REASON,
RESET_EXTRA_REBOOT_BL_REASON);
/*
* force cold reboot here to avoid unexpected
* warm boot from bootloader.
*/
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
} else if (!strncmp(cmd, "recovery", 8)) {
qpnp_pon_set_restart_reason(
PON_RESTART_REASON_RECOVERY);
@@ -530,9 +538,33 @@ static void msm_restart_prepare(const char *cmd)
restart_reason);
} else if (!strncmp(cmd, "edl", 3)) {
enable_emergency_dload_mode();
} else if (!strncmp(cmd, "post-wdt", 8)) {
/* set flag in PMIC to nofity BL post watchdog reboot */
qpnp_pon_store_extra_reset_info(RESET_EXTRA_POST_REBOOT_MASK,
RESET_EXTRA_POST_WDT_REASON);
/* force cold reboot */
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
} else if (!strncmp(cmd, "post-pmicwdt", 12)) {
/* set flag in PMIC to nofity BL post pmic watchdog reboot */
qpnp_pon_store_extra_reset_info(RESET_EXTRA_POST_REBOOT_MASK,
RESET_EXTRA_POST_PMICWDT_REASON);
/* force cold reboot */
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
} else if (!strncmp(cmd, "post-panic", 10)) {
/* set flag in PMIC to nofity BL post panic reboot */
qpnp_pon_store_extra_reset_info(RESET_EXTRA_POST_REBOOT_MASK,
RESET_EXTRA_POST_PANIC_REASON);
/* force cold reboot */
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
} else {
__raw_writel(0x77665501, restart_reason);
}
} else if (in_panic == 1) {
__raw_writel(0x77665505, restart_reason);
qpnp_pon_store_extra_reset_info(RESET_EXTRA_PANIC_REASON,
RESET_EXTRA_PANIC_REASON);
} else {
__raw_writel(0x77665501, restart_reason);
}
flush_cache_all();
+12
View File
@@ -56,6 +56,13 @@ enum pon_restart_reason {
PON_RESTART_REASON_KEYS_CLEAR = 0x06,
};
#define RESET_EXTRA_POST_PANIC_REASON (BIT(4) | BIT(5))
#define RESET_EXTRA_POST_PMICWDT_REASON BIT(5)
#define RESET_EXTRA_POST_WDT_REASON BIT(4)
#define RESET_EXTRA_POST_REBOOT_MASK (BIT(4) | BIT(5) | BIT(6))
#define RESET_EXTRA_PANIC_REASON BIT(3)
#define RESET_EXTRA_REBOOT_BL_REASON BIT(2)
#ifdef CONFIG_INPUT_QPNP_POWER_ON
int qpnp_pon_system_pwr_off(enum pon_power_off_type type);
int qpnp_pon_is_warm_reset(void);
@@ -64,6 +71,7 @@ int qpnp_pon_wd_config(bool enable);
int qpnp_pon_set_restart_reason(enum pon_restart_reason reason);
bool qpnp_pon_check_hard_reset_stored(void);
int qpnp_pon_modem_pwr_off(enum pon_power_off_type type);
int qpnp_pon_store_extra_reset_info(u16 mask, u16 val);
#else
@@ -103,6 +111,10 @@ static inline int qpnp_pon_modem_pwr_off(enum pon_power_off_type type)
return -ENODEV;
}
static inline int qpnp_pon_store_extra_reset_info(u16 mask, u16 val)
{
return -ENODEV;
}
#endif
#endif