Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1a006c8 authored by Soumya Managoli's avatar Soumya Managoli
Browse files

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: default avatarSoumya Managoli <smanag@codeaurora.org>
parent 12aec928
Loading
Loading
Loading
Loading
+58 −22
Original line number Diff line number Diff line
@@ -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 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
		}

		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;
}