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

Commit f5c0c7a0 authored by Bhalchandra Gajare's avatar Bhalchandra Gajare Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: wcd-dsp-mgr: handle codec down and up events



It is possible that codec hardware can be reset in case of subsystem
restart scenarios. It is required to reset the codec DSP as well in
such cases to make sure the DSP is in usable state after the codec
hardware is reset. Change adds support to handle codec down and up
events and perform the necessary reset on codec DSP.

Change-Id: I79502c043f5e16947c895aab7cd584d72ad1a7dc
Signed-off-by: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent d0b17cbf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -69,6 +69,10 @@ enum wdsp_signal {
	/* Hardware generated interrupts signalled to manager */
	WDSP_IPC1_INTR,
	WDSP_ERR_INTR,

	/* Other signals */
	WDSP_CDC_DOWN_SIGNAL,
	WDSP_CDC_UP_SIGNAL,
};

/*
+32 −10
Original line number Diff line number Diff line
@@ -684,17 +684,18 @@ static void wdsp_ssr_work_fn(struct work_struct *work)

	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);

	/* Issue ramdumps and shutdown only if DSP is currently booted */
	if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) {
		wdsp_collect_ramdumps(wdsp);

	/* In case of CDC_DOWN event, the DSP is already shutdown */
	if (wdsp->ssr_type != WDSP_SSR_TYPE_CDC_DOWN) {
		ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL,
					 WDSP_EVENT_DO_SHUTDOWN, NULL);
		if (IS_ERR_VALUE(ret))
			WDSP_ERR(wdsp, "Failed WDSP shutdown, err = %d", ret);
	}
	wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL);

		wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN,
					     NULL);
		WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_BOOTED);
	}

	WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
	ret = wait_for_completion_timeout(&wdsp->ready_compl,
@@ -761,16 +762,29 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg,
	switch (ssr_type) {

	case WDSP_SSR_TYPE_WDSP_DOWN:
	case WDSP_SSR_TYPE_CDC_DOWN:
		__wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY);
		if (ssr_type == WDSP_SSR_TYPE_CDC_DOWN)
			__wdsp_clr_ready_locked(wdsp,
						WDSP_SSR_STATUS_CDC_READY);
		wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN,
					     NULL);
		schedule_work(&wdsp->ssr_work);
		break;

	case WDSP_SSR_TYPE_CDC_DOWN:
		__wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY);
		/*
		 * If DSP is booted when CDC_DOWN is received, it needs
		 * to be shutdown.
		 */
		if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) {
			__wdsp_clr_ready_locked(wdsp,
						WDSP_SSR_STATUS_WDSP_READY);
			wdsp_broadcast_event_downseq(wdsp,
						     WDSP_EVENT_PRE_SHUTDOWN,
						     NULL);
		}

		schedule_work(&wdsp->ssr_work);
		break;

	case WDSP_SSR_TYPE_CDC_UP:
		__wdsp_set_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY, true);
		break;
@@ -799,6 +813,8 @@ static int wdsp_signal_handler(struct device *wdsp_dev,
	wdsp = dev_get_drvdata(wdsp_dev);
	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex);

	WDSP_DBG(wdsp, "Raised signal %d", signal);

	switch (signal) {
	case WDSP_IPC1_INTR:
		ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_IPC,
@@ -807,6 +823,12 @@ static int wdsp_signal_handler(struct device *wdsp_dev,
	case WDSP_ERR_INTR:
		ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_WDSP_DOWN);
		break;
	case WDSP_CDC_DOWN_SIGNAL:
		ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_DOWN);
		break;
	case WDSP_CDC_UP_SIGNAL:
		ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP);
		break;
	default:
		ret = -EINVAL;
		break;