dsp: adsp-loader: Support ADSP restart recovery when stuck

Changes to support silent restart of adsp subsys
based on the apr callback when packet transfer
to adsp timesout.

Change-Id: Icedb76907a441792d1953a08dd071791e5b08706
Signed-off-by: Soumya Managoli <smanag@codeaurora.org>
This commit is contained in:
Soumya Managoli
2019-09-13 19:32:03 +05:30
parent 12aec928b6
commit d1a006c81e

View File

@@ -55,6 +55,51 @@ static struct work_struct adsp_ldr_work;
static struct platform_device *adsp_private;
static void adsp_loader_unload(struct platform_device *pdev);
static int adsp_restart_subsys(void)
{
struct subsys_device *adsp_dev = NULL;
struct platform_device *pdev = adsp_private;
struct adsp_loader_private *priv = NULL;
int rc = -EINVAL;
priv = platform_get_drvdata(pdev);
if (!priv)
return rc;
adsp_dev = (struct subsys_device *)priv->pil_h;
if (!adsp_dev)
return rc;
/* subsystem_restart_dev has worker queue to handle */
rc = subsystem_restart_dev(adsp_dev);
if (rc) {
dev_err(&pdev->dev, "subsystem_restart_dev failed\n");
return rc;
}
pr_debug("%s :: Restart Success %d\n", __func__, rc);
return rc;
}
static void adsp_load_state_notify_cb(enum apr_subsys_state state,
void *phandle)
{
struct platform_device *pdev = adsp_private;
struct adsp_loader_private *priv = NULL;
priv = platform_get_drvdata(pdev);
if (!priv)
return;
if (phandle != adsp_private) {
pr_err("%s:callback is not for adsp-loader client\n", __func__);
return;
}
pr_debug("%s:: Received cb for ADSP restart\n", __func__);
if (state == APR_SUBSYS_UNKNOWN)
adsp_restart_subsys();
else
pr_debug("%s:Ignore restart request for ADSP", __func__);
}
static void adsp_load_fw(struct work_struct *adsp_ldr_work)
{
struct platform_device *pdev = adsp_private;
@@ -63,6 +108,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
int rc = 0;
u32 adsp_state;
const char *img_name;
void *padsp_restart_cb = &adsp_load_state_notify_cb;
if (!pdev) {
dev_err(&pdev->dev, "%s: Platform device null\n", __func__);
@@ -119,7 +165,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
}
dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__);
return;
goto success;
}
load_adsp:
@@ -153,10 +199,13 @@ load_adsp:
}
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
return;
apr_register_adsp_state_cb(padsp_restart_cb, adsp_private);
goto success;
}
fail:
dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__);
success:
return;
}
static void adsp_loader_do(struct platform_device *pdev)
@@ -170,37 +219,24 @@ static ssize_t adsp_ssr_store(struct kobject *kobj,
size_t count)
{
int ssr_command = 0;
struct subsys_device *adsp_dev = NULL;
struct platform_device *pdev = adsp_private;
struct adsp_loader_private *priv = NULL;
int rc;
int rc = -EINVAL;
dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__);
priv = platform_get_drvdata(pdev);
if (!priv)
return rc;
if (kstrtoint(buf, 10, &ssr_command) < 0)
return -EINVAL;
if (ssr_command != SSR_RESET_CMD)
return -EINVAL;
priv = platform_get_drvdata(pdev);
if (!priv)
return -EINVAL;
adsp_dev = (struct subsys_device *)priv->pil_h;
if (!adsp_dev)
return -EINVAL;
dev_err(&pdev->dev, "requesting for ADSP restart\n");
/* subsystem_restart_dev has worker queue to handle */
rc = subsystem_restart_dev(adsp_dev);
if (rc) {
dev_err(&pdev->dev, "subsystem_restart_dev failed\n");
return rc;
}
dev_dbg(&pdev->dev, "ADSP restarted\n");
adsp_restart_subsys();
dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__);
return count;
}