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/of_slimbus.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/msm-sps.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"
|
#include "slim-msm.h"
|
||||||
|
|
||||||
#define NGD_SLIM_NAME "ngd_msm_ctrl"
|
#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 void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
|
||||||
static int ngd_slim_runtime_resume(struct device *device);
|
static int ngd_slim_runtime_resume(struct device *device);
|
||||||
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
|
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)
|
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);
|
SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code);
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case QMI_SERVER_ARRIVE:
|
case QMI_SERVER_ARRIVE:
|
||||||
schedule_work(&qmi->ssr_up);
|
schedule_work(&dev->dsp.dom_up);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -170,31 +175,97 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
|
||||||
return 0;
|
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)
|
void *_cmd)
|
||||||
{
|
{
|
||||||
|
int cur = -1;
|
||||||
struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
|
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,
|
struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
|
||||||
dsp);
|
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) {
|
switch (code) {
|
||||||
case SUBSYS_BEFORE_SHUTDOWN:
|
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 */
|
/* wait for current transaction */
|
||||||
mutex_lock(&dev->tx_lock);
|
mutex_lock(&dev->tx_lock);
|
||||||
/* make sure autosuspend is not called until ADSP comes up*/
|
/* make sure autosuspend is not called until ADSP comes up*/
|
||||||
pm_runtime_get_noresume(dev->dev);
|
pm_runtime_get_noresume(dev->dev);
|
||||||
dev->state = MSM_CTRL_DOWN;
|
dev->state = MSM_CTRL_DOWN;
|
||||||
msm_slim_sps_exit(dev, false);
|
msm_slim_sps_exit(dev, false);
|
||||||
ngd_adsp_down(dev);
|
ngd_dom_down(dev);
|
||||||
mutex_unlock(&dev->tx_lock);
|
mutex_unlock(&dev->tx_lock);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return NOTIFY_DONE;
|
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,
|
static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
|
||||||
void *_cmd)
|
void *_cmd)
|
||||||
{
|
{
|
||||||
|
@ -1492,6 +1563,7 @@ static int ngd_notify_slaves(void *data)
|
||||||
* controller is up
|
* controller is up
|
||||||
*/
|
*/
|
||||||
slim_ctrl_add_boarddevs(&dev->ctrl);
|
slim_ctrl_add_boarddevs(&dev->ctrl);
|
||||||
|
ngd_dom_init(dev);
|
||||||
} else {
|
} else {
|
||||||
slim_framer_booted(ctrl);
|
slim_framer_booted(ctrl);
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1588,7 @@ static int ngd_notify_slaves(void *data)
|
||||||
return 0;
|
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_controller *ctrl = &dev->ctrl;
|
||||||
struct slim_device *sbdev;
|
struct slim_device *sbdev;
|
||||||
|
@ -1530,12 +1602,12 @@ static void ngd_adsp_down(struct msm_slim_ctrl *dev)
|
||||||
mutex_unlock(&dev->ssr_lock);
|
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 =
|
struct msm_slim_ss *dsp =
|
||||||
container_of(work, struct msm_slim_qmi, ssr_up);
|
container_of(work, struct msm_slim_ss, dom_up);
|
||||||
struct msm_slim_ctrl *dev =
|
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);
|
mutex_lock(&dev->ssr_lock);
|
||||||
ngd_slim_enable(dev, true);
|
ngd_slim_enable(dev, true);
|
||||||
mutex_unlock(&dev->ssr_lock);
|
mutex_unlock(&dev->ssr_lock);
|
||||||
|
@ -1572,7 +1644,7 @@ static int ngd_slim_probe(struct platform_device *pdev)
|
||||||
struct resource *irq, *bam_irq;
|
struct resource *irq, *bam_irq;
|
||||||
bool rxreg_access = false;
|
bool rxreg_access = false;
|
||||||
bool slim_mdm = 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,
|
slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||||
"slimbus_physical");
|
"slimbus_physical");
|
||||||
|
@ -1756,33 +1828,17 @@ static int ngd_slim_probe(struct platform_device *pdev)
|
||||||
pm_runtime_set_suspended(dev->dev);
|
pm_runtime_set_suspended(dev->dev);
|
||||||
pm_runtime_enable(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) {
|
if (slim_mdm) {
|
||||||
dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
|
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);
|
&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,
|
dev_err(dev->dev,
|
||||||
"subsys_notif_register_notifier failed %p",
|
"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;
|
dev->qmi.nb.notifier_call = ngd_qmi_available;
|
||||||
pm_runtime_get_noresume(dev->dev);
|
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_SVC_V1,
|
||||||
SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
|
SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
if (!IS_ERR_OR_NULL(dev->dsp.ssr))
|
if (dev->dsp.dom_t == MSM_SLIM_DOM_SS)
|
||||||
subsys_notif_unregister_notifier(dev->dsp.ssr,
|
subsys_notif_unregister_notifier(dev->dsp.domr,
|
||||||
&dev->dsp.nb);
|
&dev->dsp.nb);
|
||||||
if (!IS_ERR_OR_NULL(dev->ext_mdm.ssr))
|
if (dev->dsp.dom_t == MSM_SLIM_DOM_PD)
|
||||||
subsys_notif_unregister_notifier(dev->ext_mdm.ssr,
|
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);
|
&dev->ext_mdm.nb);
|
||||||
kfree(dev->bulk.base);
|
kfree(dev->bulk.base);
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <soc/qcom/msm_qmi_interface.h>
|
#include <soc/qcom/msm_qmi_interface.h>
|
||||||
#include <soc/qcom/subsystem_notif.h>
|
|
||||||
#include <linux/ipc_logging.h>
|
#include <linux/ipc_logging.h>
|
||||||
|
|
||||||
/* Per spec.max 40 bytes per received message */
|
/* Per spec.max 40 bytes per received message */
|
||||||
|
@ -229,14 +228,20 @@ struct msm_slim_qmi {
|
||||||
struct kthread_worker kworker;
|
struct kthread_worker kworker;
|
||||||
struct completion qmi_comp;
|
struct completion qmi_comp;
|
||||||
struct notifier_block nb;
|
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 msm_slim_ss {
|
||||||
struct notifier_block nb;
|
struct notifier_block nb;
|
||||||
void *ssr;
|
void *domr;
|
||||||
enum msm_ctrl_state state;
|
enum msm_ctrl_state state;
|
||||||
|
struct work_struct dom_up;
|
||||||
|
enum msm_slim_dom dom_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_slim_pdata {
|
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 instance_id, struct notifier_block *nb,
|
||||||
int *curr_state)
|
int *curr_state)
|
||||||
{
|
{
|
||||||
return PTR_ERR(-ENODEV);
|
return ERR_PTR(-ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int service_notif_unregister_notifier(void *service_notif_handle,
|
static int service_notif_unregister_notifier(void *service_notif_handle,
|
||||||
|
|
Loading…
Add table
Reference in a new issue