drivers: remoteproc: Modify callbacks for Rproc during Deepsleep
Handle deviations in Deepsleep requirements by introducing new callbacks that would be invoked during deepsleep suspend. Change-Id: I988a72fa3b175de4338b4e5fa2a90191a438aa4b Signed-off-by: Shreyas K K <quic_shrekk@quicinc.com>
This commit is contained in:
committed by
Jai Kumar Gautam
parent
af8a87a771
commit
1221637cb7
@@ -93,6 +93,7 @@ void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
|
||||
bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon);
|
||||
uint32_t qcom_sysmon_get_txn_id(struct qcom_sysmon *sysmon);
|
||||
int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon, char *buf, size_t len);
|
||||
void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend);
|
||||
#else
|
||||
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
|
||||
const char *name,
|
||||
@@ -120,6 +121,9 @@ static inline int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon,
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon,
|
||||
bool suspend) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <soc/qcom/secure_buffer.h>
|
||||
#include <trace/events/rproc_qcom.h>
|
||||
#include <soc/qcom/qcom_ramdump.h>
|
||||
#include <linux/remoteproc/qcom_rproc.h>
|
||||
|
||||
#include "qcom_common.h"
|
||||
#include "qcom_pil_info.h"
|
||||
@@ -635,6 +636,54 @@ static int adsp_stop(struct rproc *rproc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adsp_shutdown(struct rproc *rproc)
|
||||
{
|
||||
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
||||
int handover;
|
||||
int ret;
|
||||
|
||||
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "enter");
|
||||
|
||||
scm_pas_enable_bw();
|
||||
if (adsp->retry_shutdown)
|
||||
ret = qcom_scm_pas_shutdown_retry(adsp->pas_id);
|
||||
else
|
||||
ret = qcom_scm_pas_shutdown(adsp->pas_id);
|
||||
if (ret)
|
||||
panic("Panicking, remoteproc %s failed to shutdown.\n", rproc->name);
|
||||
|
||||
if (adsp->dtb_pas_id) {
|
||||
ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id);
|
||||
if (ret)
|
||||
panic("Panicking, remoteproc %s dtb failed to shutdown.\n", rproc->name);
|
||||
}
|
||||
|
||||
scm_pas_disable_bw();
|
||||
adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
|
||||
if (adsp->qmp)
|
||||
qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
|
||||
handover = qcom_q6v5_unprepare(&adsp->q6v5);
|
||||
if (handover)
|
||||
qcom_pas_handover(&adsp->q6v5);
|
||||
|
||||
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "exit");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adsp_set_ops_stop(struct rproc *rproc, bool suspend)
|
||||
{
|
||||
struct qcom_adsp *adsp;
|
||||
|
||||
adsp = (struct qcom_adsp *)rproc->priv;
|
||||
qcom_sysmon_set_ops_stop(adsp->sysmon, suspend);
|
||||
if (suspend)
|
||||
rproc->ops->stop = adsp_shutdown;
|
||||
else
|
||||
rproc->ops->stop = adsp_stop;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(adsp_set_ops_stop);
|
||||
|
||||
static int adsp_attach(struct rproc *rproc)
|
||||
{
|
||||
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
||||
|
||||
@@ -775,6 +775,51 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
|
||||
del_timer_sync(&sysmon->timeout_data.timer);
|
||||
}
|
||||
|
||||
static void sysmon_shutdown(struct rproc_subdev *subdev, bool crashed)
|
||||
{
|
||||
unsigned long timeout;
|
||||
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, subdev);
|
||||
|
||||
trace_rproc_qcom_event(dev_name(sysmon->rproc->dev.parent), SYSMON_SUBDEV_NAME,
|
||||
crashed ? "crash stop" : "stop");
|
||||
|
||||
sysmon->shutdown_acked = false;
|
||||
|
||||
mutex_lock(&sysmon->state_lock);
|
||||
sysmon->state = QCOM_SSR_BEFORE_SHUTDOWN;
|
||||
|
||||
sysmon->transaction_id++;
|
||||
dev_info(sysmon->dev, "Incrementing tid for %s to %d\n", sysmon->name,
|
||||
sysmon->transaction_id);
|
||||
|
||||
blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)sysmon);
|
||||
mutex_unlock(&sysmon->state_lock);
|
||||
|
||||
/* Don't request graceful shutdown if we've crashed */
|
||||
if (crashed)
|
||||
return;
|
||||
|
||||
sysmon->timeout_data.timer.function = sysmon_shutdown_notif_timeout_handler;
|
||||
timeout = jiffies + msecs_to_jiffies(SYSMON_NOTIF_TIMEOUT);
|
||||
mod_timer(&sysmon->timeout_data.timer, timeout);
|
||||
|
||||
if (sysmon->ssctl_instance) {
|
||||
if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2))
|
||||
dev_err(sysmon->dev, "timeout waiting for ssctl service\n");
|
||||
}
|
||||
|
||||
del_timer_sync(&sysmon->timeout_data.timer);
|
||||
}
|
||||
|
||||
void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend)
|
||||
{
|
||||
if (suspend)
|
||||
sysmon->subdev.stop = sysmon_shutdown;
|
||||
else
|
||||
sysmon->subdev.stop = sysmon_stop;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_sysmon_set_ops_stop);
|
||||
|
||||
static void sysmon_unprepare(struct rproc_subdev *subdev)
|
||||
{
|
||||
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
|
||||
|
||||
@@ -124,6 +124,7 @@ static int subsys_suspend(struct subsystem_data *ss_data, struct rproc *rproc, u
|
||||
case SUBSYS_DEEPSLEEP:
|
||||
case SUBSYS_HIBERNATE:
|
||||
ss_data->ignore_ssr = true;
|
||||
adsp_set_ops_stop(rproc, true);
|
||||
rproc_shutdown(rproc);
|
||||
ss_data->ignore_ssr = false;
|
||||
break;
|
||||
@@ -144,6 +145,7 @@ static int subsys_resume(struct subsystem_data *ss_data, struct rproc *rproc, u3
|
||||
case SUBSYS_DEEPSLEEP:
|
||||
case SUBSYS_HIBERNATE:
|
||||
ss_data->ignore_ssr = true;
|
||||
adsp_set_ops_stop(rproc, false);
|
||||
ret = rproc_boot(rproc);
|
||||
ss_data->ignore_ssr = false;
|
||||
break;
|
||||
|
||||
@@ -61,6 +61,14 @@ static inline int qcom_rproc_set_dtb_firmware(struct rproc *rproc, const char *d
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_Q6V5_PAS)
|
||||
void adsp_set_ops_stop(struct rproc *rproc, bool suspend);
|
||||
#else
|
||||
static inline void adsp_set_ops_stop(struct rproc *rproc, bool suspend) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user