firmware: qcom_scm: Add SCM call to perform warm reboot

An SCM call can be made instead of using PSCI SYS_RESET2. Use this SCM
call instead as PSCI driver does not have support to do vendor reset
types.

Change-Id: I07ccdcb408df0ef8a6a6c09f744ccff6345f0dea
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
Elliot Berman 2020-03-11 12:37:11 -07:00
commit 147254f01d
3 changed files with 35 additions and 0 deletions

View file

@ -1919,6 +1919,19 @@ int __qcom_scm_tsens_reinit(struct device *dev, int *tsens_ret)
return ret;
}
int __qcom_scm_reboot(struct device *dev)
{
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_OEM_POWER,
.cmd = QCOM_SCM_OEM_POWER_REBOOT,
.owner = ARM_SMCCC_OWNER_OEM,
};
desc.arginfo = QCOM_SCM_ARGS(0);
return qcom_scm_call_atomic(dev, &desc);
}
int __qcom_scm_ice_restore_cfg(struct device *dev)
{
struct qcom_scm_desc desc = {

View file

@ -13,6 +13,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/reboot.h>
#include <linux/clk.h>
#include <linux/reset-controller.h>
#include <soc/qcom/qseecom_scm.h>
@ -30,6 +31,7 @@ struct qcom_scm {
struct clk *iface_clk;
struct clk *bus_clk;
struct reset_controller_dev reset;
struct notifier_block restart_nb;
u64 dload_mode_addr;
};
@ -992,6 +994,17 @@ bool qcom_scm_is_available(void)
}
EXPORT_SYMBOL(qcom_scm_is_available);
static int qcom_scm_do_restart(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct qcom_scm *scm = container_of(this, struct qcom_scm, restart_nb);
if (reboot_mode == REBOOT_WARM)
__qcom_scm_reboot(scm->dev);
return NOTIFY_OK;
}
static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
{
struct device_node *tcsr;
@ -1085,6 +1098,10 @@ static int qcom_scm_probe(struct platform_device *pdev)
if (ret)
return ret;
scm->restart_nb.notifier_call = qcom_scm_do_restart;
scm->restart_nb.priority = 130;
register_restart_handler(&scm->restart_nb);
__scm = scm;
__scm->dev = &pdev->dev;

View file

@ -235,6 +235,11 @@ extern int __qcom_scm_qseecom_do(struct device *dev, u32 cmd_id,
#define QCOM_SCM_TSENS_INIT_ID 0x5
extern int __qcom_scm_tsens_reinit(struct device *dev, int *tsens_ret);
// OEM Services and Function IDs
#define QCOM_SCM_SVC_OEM_POWER 0x09
#define QCOM_SCM_OEM_POWER_REBOOT 0x22
extern int __qcom_scm_reboot(struct device *dev);
// TOS Services and Function IDs
#define QCOM_SCM_SVC_QSEELOG 0x01
#define QCOM_SCM_QSEELOG_REGISTER 0x06