From 0acebab6a8dbba30a2051547103eab48dfbf89f5 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 8 Jun 2016 22:24:16 -0700 Subject: [PATCH] firmware: qcom-scm: Expose mss_restart through a reset-controller Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-32.c | 8 +++++--- drivers/firmware/qcom_scm-64.c | 11 +++-------- drivers/firmware/qcom_scm.c | 36 ++++++++++++++++++++++------------ drivers/firmware/qcom_scm.h | 3 ++- include/linux/qcom_scm.h | 1 - 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 246e4c28b779..ca24cb6bf012 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -501,11 +501,13 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } -int __qcom_scm_restart_proc(u32 proc_id, int restart, u32 *resp) +int __qcom_scm_pas_mss_reset(bool reset) { + __le32 val = cpu_to_le32(reset); + __le32 resp; - return qcom_scm_call(QCOM_SCM_SVC_PIL, proc_id, - &restart, sizeof(restart), + return qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET, + &val, sizeof(val), &resp, sizeof(resp)); } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index e785f9cfadd1..7784f1dc8977 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -472,20 +472,15 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) return ret; } -int __qcom_scm_restart_proc(u32 proc_id, int restart, u32 *resp) +int __qcom_scm_pas_mss_reset(bool reset) { - int ret; struct qcom_scm_desc desc = {0}; - desc.args[0] = restart; + desc.args[0] = reset; desc.args[1] = 0; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(QCOM_SCM_SVC_PIL, proc_id, - &desc); - *resp = desc.ret[0]; - - return ret; + return qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET, &desc); } bool __qcom_scm_pas_supported(u32 peripheral) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4628c30ca01a..b760fae77d19 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "qcom_scm.h" @@ -28,6 +29,8 @@ struct qcom_scm { struct clk *core_clk; struct clk *iface_clk; struct clk *bus_clk; + + struct reset_controller_dev reset; }; static struct qcom_scm *__scm; @@ -148,19 +151,6 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) } EXPORT_SYMBOL(qcom_scm_hdcp_req); -int qcom_scm_restart_proc(u32 pid, int restart, u32 *resp) -{ - int ret; - - ret = qcom_scm_clk_enable(); - if (ret) - return ret; - - ret = __qcom_scm_restart_proc(pid, restart, resp); - qcom_scm_clk_disable(); - return ret; -} -EXPORT_SYMBOL(qcom_scm_restart_proc); /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial @@ -402,6 +392,21 @@ static int __init qcom_scm_init(void) return __qcom_scm_init(); } +static int qcom_scm_reset_assert(struct reset_controller_dev *rcdev, unsigned long idx) +{ + return __qcom_scm_pas_mss_reset(1); +} + +static int qcom_scm_reset_deassert(struct reset_controller_dev *rcdev, unsigned long idx) +{ + return __qcom_scm_pas_mss_reset(0); +} + +static struct reset_control_ops scm_reset_ops = { + .assert = qcom_scm_reset_assert, + .deassert = qcom_scm_reset_deassert, +}; + static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; @@ -445,6 +450,11 @@ static int qcom_scm_probe(struct platform_device *pdev) scm->bus_clk = NULL; } + scm->reset.ops = &scm_reset_ops; + scm->reset.nr_resets = 1; + scm->reset.of_node = pdev->dev.of_node; + reset_controller_register(&scm->reset); + /* vote for max clk rate for highest performance */ rate = clk_round_rate(scm->core_clk, INT_MAX); ret = clk_set_rate(scm->core_clk, rate); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 5c10ccced748..e1d6a42ba466 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,11 +42,13 @@ extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, #define QCOM_SCM_PAS_AUTH_AND_RESET_CMD 0x5 #define QCOM_SCM_PAS_SHUTDOWN_CMD 0x6 #define QCOM_SCM_PAS_IS_SUPPORTED_CMD 0x7 +#define QCOM_SCM_PAS_MSS_RESET 0xa extern bool __qcom_scm_pas_supported(u32 peripheral); extern int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys); extern int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size); extern int __qcom_scm_pas_auth_and_reset(u32 peripheral); extern int __qcom_scm_pas_shutdown(u32 peripheral); +extern int __qcom_scm_pas_mss_reset(bool reset); /* common error codes */ #define QCOM_SCM_ENOMEM -5 @@ -111,7 +113,6 @@ extern int __qcom_scm_iommu_secure_unmap(u32 id, u32 ctx_id, u64 va, extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id); extern int __qcom_scm_get_feat_version(u32 feat); extern int __qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); -extern int __qcom_scm_restart_proc(u32 proc_id, int restart, u32 *resp); extern int __qcom_scm_set_video_state(u32 state, u32 spare); extern int __qcom_scm_mem_protect_video_var(u32 start, u32 size, diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 536f34671bde..93819720e2a4 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -32,7 +32,6 @@ extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); extern bool qcom_scm_pas_supported(u32 peripheral); -extern int qcom_scm_restart_proc(u32 pid, int restart, u32 *resp); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size); extern int qcom_scm_pas_auth_and_reset(u32 peripheral); -- 2.39.2