summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/slimbus/slim-msm-ngd.c129
-rw-r--r--drivers/slimbus/slim-msm.h13
-rw-r--r--include/soc/qcom/service-notifier.h2
3 files changed, 104 insertions, 40 deletions
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 <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(&reg, 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 (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.ssr))
- subsys_notif_unregister_notifier(dev->ext_mdm.ssr,
+ 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 <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 {
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,