diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c index 2e6672326a77..ea4dd2ce4e1d 100644 --- a/drivers/slimbus/slim-msm-ngd.c +++ b/drivers/slimbus/slim-msm-ngd.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #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); diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h index fc0a8d23f573..7616e714299c 100644 --- a/drivers/slimbus/slim-msm.h +++ b/drivers/slimbus/slim-msm.h @@ -16,7 +16,6 @@ #include #include #include -#include #include /* 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 { diff --git a/include/soc/qcom/service-notifier.h b/include/soc/qcom/service-notifier.h index 90fceba091b9..598c91f7c9e2 100644 --- a/include/soc/qcom/service-notifier.h +++ b/include/soc/qcom/service-notifier.h @@ -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,