|
@@ -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__);
|
|
|
|
|
|
- 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;
|
|
|
+ return rc;
|
|
|
|
|
|
- adsp_dev = (struct subsys_device *)priv->pil_h;
|
|
|
- if (!adsp_dev)
|
|
|
+ if (kstrtoint(buf, 10, &ssr_command) < 0)
|
|
|
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;
|
|
|
- }
|
|
|
+ if (ssr_command != SSR_RESET_CMD)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- dev_dbg(&pdev->dev, "ADSP restarted\n");
|
|
|
+ adsp_restart_subsys();
|
|
|
+ dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__);
|
|
|
return count;
|
|
|
}
|
|
|
|