Merge "slim: ngd: Handle Process Domain restart"
This commit is contained in:
commit
521c0c89d9
3 changed files with 104 additions and 40 deletions
|
@ -26,6 +26,9 @@
|
|||
#include <linux/of_slimbus.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/msm-sps.h>
|
||||
#include <soc/qcom/service-locator.h>
|
||||
#include <soc/qcom/service-notifier.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include "slim-msm.h"
|
||||
|
||||
#define NGD_SLIM_NAME "ngd_msm_ctrl"
|
||||
|
@ -84,7 +87,9 @@ enum ngd_status {
|
|||
static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
|
||||
static int ngd_slim_runtime_resume(struct device *device);
|
||||
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
|
||||
static void ngd_adsp_down(struct msm_slim_ctrl *dev);
|
||||
static void ngd_dom_down(struct msm_slim_ctrl *dev);
|
||||
static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
|
||||
void *_cmd);
|
||||
|
||||
static irqreturn_t ngd_slim_interrupt(int irq, void *d)
|
||||
{
|
||||
|
@ -162,7 +167,7 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
|
|||
SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code);
|
||||
switch (code) {
|
||||
case QMI_SERVER_ARRIVE:
|
||||
schedule_work(&qmi->ssr_up);
|
||||
schedule_work(&dev->dsp.dom_up);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -170,31 +175,97 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dsp_ssr_notify_cb(struct notifier_block *n, unsigned long code,
|
||||
static void ngd_reg_ssr(struct msm_slim_ctrl *dev)
|
||||
{
|
||||
int ret;
|
||||
const char *subsys_name = NULL;
|
||||
|
||||
dev->dsp.dom_t = MSM_SLIM_DOM_NONE;
|
||||
ret = of_property_read_string(dev->dev->of_node,
|
||||
"qcom,subsys-name", &subsys_name);
|
||||
if (ret)
|
||||
subsys_name = "adsp";
|
||||
|
||||
dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
|
||||
dev->dsp.domr = subsys_notif_register_notifier(subsys_name,
|
||||
&dev->dsp.nb);
|
||||
if (IS_ERR_OR_NULL(dev->dsp.domr)) {
|
||||
dev_err(dev->dev,
|
||||
"subsys_notif_register_notifier failed %ld",
|
||||
PTR_ERR(dev->dsp.domr));
|
||||
return;
|
||||
}
|
||||
dev->dsp.dom_t = MSM_SLIM_DOM_SS;
|
||||
SLIM_INFO(dev, "reg-SSR with:%s, PDR not available\n",
|
||||
subsys_name);
|
||||
}
|
||||
|
||||
static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
|
||||
void *_cmd)
|
||||
{
|
||||
int cur = -1;
|
||||
struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
|
||||
struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
|
||||
dsp);
|
||||
struct pd_qmi_client_data *reg;
|
||||
|
||||
SLIM_INFO(dev, "SLIM DSP SSR/PDR notify cb:0x%lx, type:%d\n",
|
||||
code, dsp->dom_t);
|
||||
switch (code) {
|
||||
case SUBSYS_BEFORE_SHUTDOWN:
|
||||
SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code);
|
||||
case SERVREG_NOTIF_SERVICE_STATE_DOWN_V01:
|
||||
/* wait for current transaction */
|
||||
mutex_lock(&dev->tx_lock);
|
||||
/* make sure autosuspend is not called until ADSP comes up*/
|
||||
pm_runtime_get_noresume(dev->dev);
|
||||
dev->state = MSM_CTRL_DOWN;
|
||||
msm_slim_sps_exit(dev, false);
|
||||
ngd_adsp_down(dev);
|
||||
ngd_dom_down(dev);
|
||||
mutex_unlock(&dev->tx_lock);
|
||||
break;
|
||||
case LOCATOR_UP:
|
||||
reg = _cmd;
|
||||
dev->dsp.domr = service_notif_register_notifier(
|
||||
reg->domain_list->name,
|
||||
reg->domain_list->instance_id,
|
||||
&dev->dsp.nb,
|
||||
&cur);
|
||||
SLIM_INFO(dev, "reg-PD client:%s with service:%s\n",
|
||||
reg->client_name, reg->service_name);
|
||||
SLIM_INFO(dev, "reg-PD dom:%s instance:%d, cur:%d\n",
|
||||
reg->domain_list->name,
|
||||
reg->domain_list->instance_id, cur);
|
||||
if (IS_ERR_OR_NULL(dev->dsp.domr))
|
||||
ngd_reg_ssr(dev);
|
||||
else
|
||||
dev->dsp.dom_t = MSM_SLIM_DOM_PD;
|
||||
break;
|
||||
case LOCATOR_DOWN:
|
||||
ngd_reg_ssr(dev);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static void ngd_dom_init(struct msm_slim_ctrl *dev)
|
||||
{
|
||||
struct pd_qmi_client_data reg;
|
||||
int ret;
|
||||
|
||||
memset(®, 0, sizeof(struct pd_qmi_client_data));
|
||||
dev->dsp.nb.priority = 4;
|
||||
dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
|
||||
scnprintf(reg.client_name, QMI_SERVREG_LOC_NAME_LENGTH_V01, "appsngd%d",
|
||||
dev->ctrl.nr);
|
||||
scnprintf(reg.service_name, QMI_SERVREG_LOC_NAME_LENGTH_V01,
|
||||
"avs/audio");
|
||||
ret = get_service_location(reg.client_name, reg.service_name,
|
||||
&dev->dsp.nb);
|
||||
if (ret)
|
||||
ngd_reg_ssr(dev);
|
||||
}
|
||||
|
||||
static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
|
||||
void *_cmd)
|
||||
{
|
||||
|
@ -1492,6 +1563,7 @@ static int ngd_notify_slaves(void *data)
|
|||
* controller is up
|
||||
*/
|
||||
slim_ctrl_add_boarddevs(&dev->ctrl);
|
||||
ngd_dom_init(dev);
|
||||
} else {
|
||||
slim_framer_booted(ctrl);
|
||||
}
|
||||
|
@ -1516,7 +1588,7 @@ static int ngd_notify_slaves(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ngd_adsp_down(struct msm_slim_ctrl *dev)
|
||||
static void ngd_dom_down(struct msm_slim_ctrl *dev)
|
||||
{
|
||||
struct slim_controller *ctrl = &dev->ctrl;
|
||||
struct slim_device *sbdev;
|
||||
|
@ -1530,12 +1602,12 @@ static void ngd_adsp_down(struct msm_slim_ctrl *dev)
|
|||
mutex_unlock(&dev->ssr_lock);
|
||||
}
|
||||
|
||||
static void ngd_adsp_up(struct work_struct *work)
|
||||
static void ngd_dom_up(struct work_struct *work)
|
||||
{
|
||||
struct msm_slim_qmi *qmi =
|
||||
container_of(work, struct msm_slim_qmi, ssr_up);
|
||||
struct msm_slim_ss *dsp =
|
||||
container_of(work, struct msm_slim_ss, dom_up);
|
||||
struct msm_slim_ctrl *dev =
|
||||
container_of(qmi, struct msm_slim_ctrl, qmi);
|
||||
container_of(dsp, struct msm_slim_ctrl, dsp);
|
||||
mutex_lock(&dev->ssr_lock);
|
||||
ngd_slim_enable(dev, true);
|
||||
mutex_unlock(&dev->ssr_lock);
|
||||
|
@ -1572,7 +1644,7 @@ static int ngd_slim_probe(struct platform_device *pdev)
|
|||
struct resource *irq, *bam_irq;
|
||||
bool rxreg_access = false;
|
||||
bool slim_mdm = false;
|
||||
const char *ext_modem_id = NULL, *subsys_name = NULL;
|
||||
const char *ext_modem_id = NULL;
|
||||
|
||||
slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"slimbus_physical");
|
||||
|
@ -1756,33 +1828,17 @@ static int ngd_slim_probe(struct platform_device *pdev)
|
|||
pm_runtime_set_suspended(dev->dev);
|
||||
pm_runtime_enable(dev->dev);
|
||||
|
||||
dev->dsp.nb.priority = 4;
|
||||
ret = of_property_read_string(pdev->dev.of_node,
|
||||
"qcom,subsys-name", &subsys_name);
|
||||
if (ret) {
|
||||
dev->dsp.nb.notifier_call = dsp_ssr_notify_cb;
|
||||
dev->dsp.ssr = subsys_notif_register_notifier("adsp",
|
||||
&dev->dsp.nb);
|
||||
} else {
|
||||
dev->dsp.nb.notifier_call = dsp_ssr_notify_cb;
|
||||
dev->dsp.ssr = subsys_notif_register_notifier(subsys_name,
|
||||
&dev->dsp.nb);
|
||||
}
|
||||
if (IS_ERR_OR_NULL(dev->dsp.ssr))
|
||||
dev_err(dev->dev,
|
||||
"subsys_notif_register_notifier failed %p",
|
||||
dev->dsp.ssr);
|
||||
if (slim_mdm) {
|
||||
dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
|
||||
dev->ext_mdm.ssr = subsys_notif_register_notifier(ext_modem_id,
|
||||
dev->ext_mdm.domr = subsys_notif_register_notifier(ext_modem_id,
|
||||
&dev->ext_mdm.nb);
|
||||
if (IS_ERR_OR_NULL(dev->ext_mdm.ssr))
|
||||
if (IS_ERR_OR_NULL(dev->ext_mdm.domr))
|
||||
dev_err(dev->dev,
|
||||
"subsys_notif_register_notifier failed %p",
|
||||
dev->ext_mdm.ssr);
|
||||
dev->ext_mdm.domr);
|
||||
}
|
||||
|
||||
INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
|
||||
INIT_WORK(&dev->dsp.dom_up, ngd_dom_up);
|
||||
dev->qmi.nb.notifier_call = ngd_qmi_available;
|
||||
pm_runtime_get_noresume(dev->dev);
|
||||
|
||||
|
@ -1837,11 +1893,14 @@ static int ngd_slim_remove(struct platform_device *pdev)
|
|||
SLIMBUS_QMI_SVC_V1,
|
||||
SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!IS_ERR_OR_NULL(dev->dsp.ssr))
|
||||
subsys_notif_unregister_notifier(dev->dsp.ssr,
|
||||
if (dev->dsp.dom_t == MSM_SLIM_DOM_SS)
|
||||
subsys_notif_unregister_notifier(dev->dsp.domr,
|
||||
&dev->dsp.nb);
|
||||
if (!IS_ERR_OR_NULL(dev->ext_mdm.ssr))
|
||||
subsys_notif_unregister_notifier(dev->ext_mdm.ssr,
|
||||
if (dev->dsp.dom_t == MSM_SLIM_DOM_PD)
|
||||
service_notif_unregister_notifier(dev->dsp.domr,
|
||||
&dev->dsp.nb);
|
||||
if (!IS_ERR_OR_NULL(dev->ext_mdm.domr))
|
||||
subsys_notif_unregister_notifier(dev->ext_mdm.domr,
|
||||
&dev->ext_mdm.nb);
|
||||
kfree(dev->bulk.base);
|
||||
free_irq(dev->irq, dev);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <soc/qcom/msm_qmi_interface.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
|
||||
/* Per spec.max 40 bytes per received message */
|
||||
|
@ -229,14 +228,20 @@ struct msm_slim_qmi {
|
|||
struct kthread_worker kworker;
|
||||
struct completion qmi_comp;
|
||||
struct notifier_block nb;
|
||||
struct work_struct ssr_down;
|
||||
struct work_struct ssr_up;
|
||||
};
|
||||
|
||||
enum msm_slim_dom {
|
||||
MSM_SLIM_DOM_NONE,
|
||||
MSM_SLIM_DOM_PD,
|
||||
MSM_SLIM_DOM_SS,
|
||||
};
|
||||
|
||||
struct msm_slim_ss {
|
||||
struct notifier_block nb;
|
||||
void *ssr;
|
||||
void *domr;
|
||||
enum msm_ctrl_state state;
|
||||
struct work_struct dom_up;
|
||||
enum msm_slim_dom dom_t;
|
||||
};
|
||||
|
||||
struct msm_slim_pdata {
|
||||
|
|
|
@ -53,7 +53,7 @@ static void *service_notif_register_notifier(const char *service_path,
|
|||
int instance_id, struct notifier_block *nb,
|
||||
int *curr_state)
|
||||
{
|
||||
return PTR_ERR(-ENODEV);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static int service_notif_unregister_notifier(void *service_notif_handle,
|
||||
|
|
Loading…
Add table
Reference in a new issue