diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index e99d6a3c72..4be1c0d9c6 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -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; }