power: reset: Import xiaomi changes
[ItsVixano: Skip `qcom_dload_restart` func changes, due to commit
52c3eb6f12
]
Change-Id: I7b70bf2dcace33a063fb060b6108287765afc147
This commit is contained in:
parent
9ef32b7651
commit
8fa6995f56
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2021 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@ -60,8 +61,8 @@ static struct nvmem_cell *nvmem_cell;
|
||||
static int download_mode = 1;
|
||||
static struct kobject dload_kobj;
|
||||
|
||||
static int in_panic;
|
||||
static int dload_type = SCM_DLOAD_FULLDUMP;
|
||||
static int in_panic = 0;
|
||||
static int dload_type = SCM_DLOAD_BOTHDUMPS;
|
||||
static void *dload_mode_addr;
|
||||
static bool dload_mode_enabled;
|
||||
static void *emergency_dload_mode_addr;
|
||||
@ -431,7 +432,10 @@ static void msm_restart_prepare(const char *cmd)
|
||||
else
|
||||
qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
|
||||
|
||||
if (cmd != NULL) {
|
||||
if (in_panic) {
|
||||
reason = PON_RESTART_REASON_PANIC;
|
||||
}
|
||||
else if (cmd != NULL) {
|
||||
if (!strncmp(cmd, "bootloader", 10)) {
|
||||
reason = PON_RESTART_REASON_BOOTLOADER;
|
||||
__raw_writel(0x77665500, restart_reason);
|
||||
@ -461,15 +465,19 @@ static void msm_restart_prepare(const char *cmd)
|
||||
} else if (!strncmp(cmd, "edl", 3)) {
|
||||
enable_emergency_dload_mode();
|
||||
} else {
|
||||
reason = PON_RESTART_REASON_NORMAL;
|
||||
__raw_writel(0x77665501, restart_reason);
|
||||
}
|
||||
|
||||
if (reason && nvmem_cell)
|
||||
nvmem_cell_write(nvmem_cell, &reason, sizeof(reason));
|
||||
else
|
||||
qpnp_pon_set_restart_reason(
|
||||
(enum pon_restart_reason)reason);
|
||||
} else {
|
||||
reason = PON_RESTART_REASON_NORMAL;
|
||||
__raw_writel(0x77665501, restart_reason);
|
||||
}
|
||||
if (reason && nvmem_cell)
|
||||
nvmem_cell_write(nvmem_cell, &reason, sizeof(reason));
|
||||
else
|
||||
qpnp_pon_set_restart_reason(
|
||||
(enum pon_restart_reason)reason);
|
||||
|
||||
/*outer_flush_all is not supported by 64bit kernel*/
|
||||
#ifndef CONFIG_ARM64
|
||||
|
@ -38,7 +38,7 @@ struct qcom_dload {
|
||||
static bool enable_dump =
|
||||
IS_ENABLED(CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_DEFAULT);
|
||||
static enum qcom_download_mode current_download_mode = QCOM_DOWNLOAD_NODUMP;
|
||||
static enum qcom_download_mode dump_mode = QCOM_DOWNLOAD_FULLDUMP;
|
||||
static enum qcom_download_mode dump_mode = QCOM_DOWNLOAD_BOTHDUMP;
|
||||
static bool early_pcie_init_enable;
|
||||
|
||||
static int set_download_mode(enum qcom_download_mode mode)
|
||||
@ -328,6 +328,26 @@ static void check_pci_edl(struct device_node *np)
|
||||
iounmap(mem);
|
||||
}
|
||||
|
||||
#define DISPLAY_CONFIG_OFFSET_PROP "qcom,msm-imem-display_config_offset"
|
||||
/*
|
||||
** set display config imem first 4 bytes to 0xdead4ead, because imem context
|
||||
** will not lost when warm reset. if panic, xbl ramdump will display orange
|
||||
** screen, and framebuffer addr is determined by these four bytes in
|
||||
** MDP_GetDisplayBootConfig function. so set these four bytes to a invalid
|
||||
** value and let the framebuffer of orange screen use
|
||||
** RAMDUMP_FRAME_BUFFER_ADDRESS(0xE1000000)
|
||||
**/
|
||||
static void clear_display_config(void)
|
||||
{
|
||||
void *display_config_imem_addr = map_prop_mem(DISPLAY_CONFIG_OFFSET_PROP);
|
||||
|
||||
if (display_config_imem_addr) {
|
||||
__raw_writel(0xdead4ead, display_config_imem_addr);
|
||||
iounmap(display_config_imem_addr);
|
||||
pr_err("%s clear display config\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static int qcom_dload_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_dload *poweroff;
|
||||
@ -358,6 +378,7 @@ static int qcom_dload_probe(struct platform_device *pdev)
|
||||
poweroff->dload_dest_addr = map_prop_mem("qcom,msm-imem-dload-type");
|
||||
store_kaslr_offset();
|
||||
check_pci_edl(pdev->dev.of_node);
|
||||
clear_display_config();
|
||||
|
||||
msm_enable_dump_mode(enable_dump);
|
||||
if (!enable_dump)
|
||||
|
@ -17,6 +17,8 @@
|
||||
struct qcom_reboot_reason {
|
||||
struct device *dev;
|
||||
struct notifier_block reboot_nb;
|
||||
struct notifier_block panic_nb;
|
||||
struct notifier_block restart_nb;
|
||||
struct nvmem_cell *nvmem_cell;
|
||||
};
|
||||
|
||||
@ -32,9 +34,19 @@ static struct poweroff_reason reasons[] = {
|
||||
{ "dm-verity device corrupted", 0x04 },
|
||||
{ "dm-verity enforcing", 0x05 },
|
||||
{ "keys clear", 0x06 },
|
||||
{ "panic", 0x21 },
|
||||
{ NULL, 0x20 },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct poweroff_reason restart_reasons[] = {
|
||||
{ "lp_kthread", 0x28 },
|
||||
{ NULL, 0x00 }, //end loop flag, not reset reason
|
||||
};
|
||||
|
||||
#define RESTART_REASON_PANIC 6
|
||||
#define RESTART_REASON_NORMAL 7
|
||||
|
||||
static int qcom_reboot_reason_reboot(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
@ -43,20 +55,67 @@ static int qcom_reboot_reason_reboot(struct notifier_block *this,
|
||||
struct qcom_reboot_reason, reboot_nb);
|
||||
struct poweroff_reason *reason;
|
||||
|
||||
if (!cmd)
|
||||
if (!cmd) {
|
||||
nvmem_cell_write(reboot->nvmem_cell,
|
||||
&reasons[RESTART_REASON_NORMAL].pon_reason,
|
||||
sizeof(reasons[RESTART_REASON_NORMAL].pon_reason));
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
for (reason = reasons; reason->cmd; reason++) {
|
||||
if (!strcmp(cmd, reason->cmd)) {
|
||||
nvmem_cell_write(reboot->nvmem_cell,
|
||||
&reason->pon_reason,
|
||||
sizeof(reason->pon_reason));
|
||||
break;
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
}
|
||||
nvmem_cell_write(reboot->nvmem_cell,
|
||||
&reason->pon_reason,
|
||||
sizeof(reason->pon_reason));
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function only used in restart chain for limited reset reasons
|
||||
* eg: long press power key kthread, because it cannot trigger
|
||||
* reboot chain to set reset reason
|
||||
*/
|
||||
static int qcom_restart_reason_reboot(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
char *cmd = ptr;
|
||||
struct qcom_reboot_reason *reboot = container_of(this,
|
||||
struct qcom_reboot_reason, restart_nb);
|
||||
struct poweroff_reason *reason;
|
||||
|
||||
if (!cmd) {
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
for (reason = restart_reasons; reason->cmd; reason++) {
|
||||
if (!strcmp(cmd, reason->cmd)) {
|
||||
nvmem_cell_write(reboot->nvmem_cell,
|
||||
&reason->pon_reason,
|
||||
sizeof(reason->pon_reason));
|
||||
pr_info("restart reason: %s\n", cmd);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
||||
static int panic_prep_restart(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct qcom_reboot_reason *reboot = container_of(this,
|
||||
struct qcom_reboot_reason, panic_nb);
|
||||
nvmem_cell_write(reboot->nvmem_cell,
|
||||
&reasons[RESTART_REASON_PANIC].pon_reason,
|
||||
sizeof(reasons[RESTART_REASON_PANIC].pon_reason));
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int qcom_reboot_reason_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_reboot_reason *reboot;
|
||||
@ -78,6 +137,15 @@ static int qcom_reboot_reason_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, reboot);
|
||||
|
||||
reboot->panic_nb.notifier_call = panic_prep_restart;
|
||||
reboot->panic_nb.priority = INT_MAX;
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &reboot->panic_nb);
|
||||
|
||||
/*register restart chain for set restart reason*/
|
||||
reboot->restart_nb.notifier_call = qcom_restart_reason_reboot;
|
||||
reboot->restart_nb.priority = 200;
|
||||
register_restart_handler(&reboot->restart_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -85,8 +153,9 @@ static int qcom_reboot_reason_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_reboot_reason *reboot = platform_get_drvdata(pdev);
|
||||
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list, &reboot->panic_nb);
|
||||
unregister_reboot_notifier(&reboot->reboot_nb);
|
||||
|
||||
unregister_restart_handler(&reboot->restart_nb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2015, 2017-2019, The Linux Foundation.
|
||||
* Copyright (C) 2021 XiaoMi, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
@ -55,6 +56,8 @@ enum pon_restart_reason {
|
||||
PON_RESTART_REASON_DMVERITY_CORRUPTED = 0x04,
|
||||
PON_RESTART_REASON_DMVERITY_ENFORCE = 0x05,
|
||||
PON_RESTART_REASON_KEYS_CLEAR = 0x06,
|
||||
PON_RESTART_REASON_NORMAL = 0x20,
|
||||
PON_RESTART_REASON_PANIC = 0x21,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT_QPNP_POWER_ON)
|
||||
@ -106,4 +109,9 @@ static inline int qpnp_pon_modem_pwr_off(enum pon_power_off_type type)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_BLOCK2MTD
|
||||
extern struct Scsi_Host *g_shost;
|
||||
extern void machine_restart(char *cmd);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user