1e973e31aSSubhransu S. Prusty /*
2e973e31aSSubhransu S. Prusty  * skl-sst-dsp.c - SKL SST library generic function
3e973e31aSSubhransu S. Prusty  *
4e973e31aSSubhransu S. Prusty  * Copyright (C) 2014-15, Intel Corporation.
5e973e31aSSubhransu S. Prusty  * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
6e973e31aSSubhransu S. Prusty  *	Jeeja KP <jeeja.kp@intel.com>
7e973e31aSSubhransu S. Prusty  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8e973e31aSSubhransu S. Prusty  *
9e973e31aSSubhransu S. Prusty  * This program is free software; you can redistribute it and/or modify
10e973e31aSSubhransu S. Prusty  * it under the terms of the GNU General Public License as version 2, as
11e973e31aSSubhransu S. Prusty  * published by the Free Software Foundation.
12e973e31aSSubhransu S. Prusty  *
13e973e31aSSubhransu S. Prusty  * This program is distributed in the hope that it will be useful, but
14e973e31aSSubhransu S. Prusty  * WITHOUT ANY WARRANTY; without even the implied warranty of
15e973e31aSSubhransu S. Prusty  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16e973e31aSSubhransu S. Prusty  * General Public License for more details.
17e973e31aSSubhransu S. Prusty  */
18e973e31aSSubhransu S. Prusty #include <sound/pcm.h>
19e973e31aSSubhransu S. Prusty 
20e973e31aSSubhransu S. Prusty #include "../common/sst-dsp.h"
21e973e31aSSubhransu S. Prusty #include "../common/sst-ipc.h"
22e973e31aSSubhransu S. Prusty #include "../common/sst-dsp-priv.h"
23e973e31aSSubhransu S. Prusty #include "skl-sst-ipc.h"
24e973e31aSSubhransu S. Prusty 
25e973e31aSSubhransu S. Prusty /* various timeout values */
26e973e31aSSubhransu S. Prusty #define SKL_DSP_PU_TO		50
27e973e31aSSubhransu S. Prusty #define SKL_DSP_PD_TO		50
28e973e31aSSubhransu S. Prusty #define SKL_DSP_RESET_TO	50
29e973e31aSSubhransu S. Prusty 
30e973e31aSSubhransu S. Prusty void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
31e973e31aSSubhransu S. Prusty {
32e973e31aSSubhransu S. Prusty 	mutex_lock(&ctx->mutex);
33e973e31aSSubhransu S. Prusty 	ctx->sst_state = state;
34e973e31aSSubhransu S. Prusty 	mutex_unlock(&ctx->mutex);
35e973e31aSSubhransu S. Prusty }
36e973e31aSSubhransu S. Prusty 
37e973e31aSSubhransu S. Prusty static int skl_dsp_core_set_reset_state(struct sst_dsp  *ctx)
38e973e31aSSubhransu S. Prusty {
39e973e31aSSubhransu S. Prusty 	int ret;
40e973e31aSSubhransu S. Prusty 
41e973e31aSSubhransu S. Prusty 	/* update bits */
42e973e31aSSubhransu S. Prusty 	sst_dsp_shim_update_bits_unlocked(ctx,
43e973e31aSSubhransu S. Prusty 			SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK,
44e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK));
45e973e31aSSubhransu S. Prusty 
46e973e31aSSubhransu S. Prusty 	/* poll with timeout to check if operation successful */
47e973e31aSSubhransu S. Prusty 	ret = sst_dsp_register_poll(ctx,
48e973e31aSSubhransu S. Prusty 			SKL_ADSP_REG_ADSPCS,
49e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CRST_MASK,
50e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK),
51e973e31aSSubhransu S. Prusty 			SKL_DSP_RESET_TO,
52e973e31aSSubhransu S. Prusty 			"Set reset");
53e973e31aSSubhransu S. Prusty 	if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
54e973e31aSSubhransu S. Prusty 				SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) !=
55e973e31aSSubhransu S. Prusty 				SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) {
56e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "Set reset state failed\n");
57e973e31aSSubhransu S. Prusty 		ret = -EIO;
58e973e31aSSubhransu S. Prusty 	}
59e973e31aSSubhransu S. Prusty 
60e973e31aSSubhransu S. Prusty 	return ret;
61e973e31aSSubhransu S. Prusty }
62e973e31aSSubhransu S. Prusty 
63e973e31aSSubhransu S. Prusty static int skl_dsp_core_unset_reset_state(struct sst_dsp  *ctx)
64e973e31aSSubhransu S. Prusty {
65e973e31aSSubhransu S. Prusty 	int ret;
66e973e31aSSubhransu S. Prusty 
67e973e31aSSubhransu S. Prusty 	dev_dbg(ctx->dev, "In %s\n", __func__);
68e973e31aSSubhransu S. Prusty 
69e973e31aSSubhransu S. Prusty 	/* update bits */
70e973e31aSSubhransu S. Prusty 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
71e973e31aSSubhransu S. Prusty 					SKL_ADSPCS_CRST_MASK, 0);
72e973e31aSSubhransu S. Prusty 
73e973e31aSSubhransu S. Prusty 	/* poll with timeout to check if operation successful */
74e973e31aSSubhransu S. Prusty 	ret = sst_dsp_register_poll(ctx,
75e973e31aSSubhransu S. Prusty 			SKL_ADSP_REG_ADSPCS,
76e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CRST_MASK,
77e973e31aSSubhransu S. Prusty 			0,
78e973e31aSSubhransu S. Prusty 			SKL_DSP_RESET_TO,
79e973e31aSSubhransu S. Prusty 			"Unset reset");
80e973e31aSSubhransu S. Prusty 
81e973e31aSSubhransu S. Prusty 	if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
82e973e31aSSubhransu S. Prusty 				 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) != 0) {
83e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "Unset reset state failed\n");
84e973e31aSSubhransu S. Prusty 		ret = -EIO;
85e973e31aSSubhransu S. Prusty 	}
86e973e31aSSubhransu S. Prusty 
87e973e31aSSubhransu S. Prusty 	return ret;
88e973e31aSSubhransu S. Prusty }
89e973e31aSSubhransu S. Prusty 
90e973e31aSSubhransu S. Prusty static bool is_skl_dsp_core_enable(struct sst_dsp  *ctx)
91e973e31aSSubhransu S. Prusty {
92e973e31aSSubhransu S. Prusty 	int val;
93e973e31aSSubhransu S. Prusty 	bool is_enable;
94e973e31aSSubhransu S. Prusty 
95e973e31aSSubhransu S. Prusty 	val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
96e973e31aSSubhransu S. Prusty 
97e973e31aSSubhransu S. Prusty 	is_enable = ((val & SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) &&
98e973e31aSSubhransu S. Prusty 			(val & SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK)) &&
99e973e31aSSubhransu S. Prusty 			!(val & SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) &&
100e973e31aSSubhransu S. Prusty 			!(val & SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK)));
101e973e31aSSubhransu S. Prusty 
102e973e31aSSubhransu S. Prusty 	dev_dbg(ctx->dev, "DSP core is enabled=%d\n", is_enable);
103e973e31aSSubhransu S. Prusty 	return is_enable;
104e973e31aSSubhransu S. Prusty }
105e973e31aSSubhransu S. Prusty 
106e973e31aSSubhransu S. Prusty static int skl_dsp_reset_core(struct sst_dsp *ctx)
107e973e31aSSubhransu S. Prusty {
108e973e31aSSubhransu S. Prusty 	/* stall core */
109e973e31aSSubhransu S. Prusty 	sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
110e973e31aSSubhransu S. Prusty 			 sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
111e973e31aSSubhransu S. Prusty 				SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK));
112e973e31aSSubhransu S. Prusty 
113e973e31aSSubhransu S. Prusty 	/* set reset state */
114e973e31aSSubhransu S. Prusty 	return skl_dsp_core_set_reset_state(ctx);
115e973e31aSSubhransu S. Prusty }
116e973e31aSSubhransu S. Prusty 
117e973e31aSSubhransu S. Prusty static int skl_dsp_start_core(struct sst_dsp *ctx)
118e973e31aSSubhransu S. Prusty {
119e973e31aSSubhransu S. Prusty 	int ret;
120e973e31aSSubhransu S. Prusty 
121e973e31aSSubhransu S. Prusty 	/* unset reset state */
122e973e31aSSubhransu S. Prusty 	ret = skl_dsp_core_unset_reset_state(ctx);
123e973e31aSSubhransu S. Prusty 	if (ret < 0) {
124e973e31aSSubhransu S. Prusty 		dev_dbg(ctx->dev, "dsp unset reset fails\n");
125e973e31aSSubhransu S. Prusty 		return ret;
126e973e31aSSubhransu S. Prusty 	}
127e973e31aSSubhransu S. Prusty 
128e973e31aSSubhransu S. Prusty 	/* run core */
129e973e31aSSubhransu S. Prusty 	dev_dbg(ctx->dev, "run core...\n");
130e973e31aSSubhransu S. Prusty 	sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
131e973e31aSSubhransu S. Prusty 			 sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
132e973e31aSSubhransu S. Prusty 				~SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK));
133e973e31aSSubhransu S. Prusty 
134e973e31aSSubhransu S. Prusty 	if (!is_skl_dsp_core_enable(ctx)) {
135e973e31aSSubhransu S. Prusty 		skl_dsp_reset_core(ctx);
136e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "DSP core enable failed\n");
137e973e31aSSubhransu S. Prusty 		ret = -EIO;
138e973e31aSSubhransu S. Prusty 	}
139e973e31aSSubhransu S. Prusty 
140e973e31aSSubhransu S. Prusty 	return ret;
141e973e31aSSubhransu S. Prusty }
142e973e31aSSubhransu S. Prusty 
143e973e31aSSubhransu S. Prusty static int skl_dsp_core_power_up(struct sst_dsp  *ctx)
144e973e31aSSubhransu S. Prusty {
145e973e31aSSubhransu S. Prusty 	int ret;
146e973e31aSSubhransu S. Prusty 
147e973e31aSSubhransu S. Prusty 	/* update bits */
148e973e31aSSubhransu S. Prusty 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
149e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_SPA_MASK, SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK));
150e973e31aSSubhransu S. Prusty 
151e973e31aSSubhransu S. Prusty 	/* poll with timeout to check if operation successful */
152e973e31aSSubhransu S. Prusty 	ret = sst_dsp_register_poll(ctx,
153e973e31aSSubhransu S. Prusty 			SKL_ADSP_REG_ADSPCS,
154e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CPA_MASK,
155e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK),
156e973e31aSSubhransu S. Prusty 			SKL_DSP_PU_TO,
157e973e31aSSubhransu S. Prusty 			"Power up");
158e973e31aSSubhransu S. Prusty 
159e973e31aSSubhransu S. Prusty 	if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
160e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) !=
161e973e31aSSubhransu S. Prusty 			SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) {
162e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "DSP core power up failed\n");
163e973e31aSSubhransu S. Prusty 		ret = -EIO;
164e973e31aSSubhransu S. Prusty 	}
165e973e31aSSubhransu S. Prusty 
166e973e31aSSubhransu S. Prusty 	return ret;
167e973e31aSSubhransu S. Prusty }
168e973e31aSSubhransu S. Prusty 
169e973e31aSSubhransu S. Prusty static int skl_dsp_core_power_down(struct sst_dsp  *ctx)
170e973e31aSSubhransu S. Prusty {
171e973e31aSSubhransu S. Prusty 	/* update bits */
172e973e31aSSubhransu S. Prusty 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
173e973e31aSSubhransu S. Prusty 					SKL_ADSPCS_SPA_MASK, 0);
174e973e31aSSubhransu S. Prusty 
175e973e31aSSubhransu S. Prusty 	/* poll with timeout to check if operation successful */
176e973e31aSSubhransu S. Prusty 	return sst_dsp_register_poll(ctx,
177e973e31aSSubhransu S. Prusty 			SKL_ADSP_REG_ADSPCS,
1786ea8ba33SJeeja KP 			SKL_ADSPCS_CPA_MASK,
179e973e31aSSubhransu S. Prusty 			0,
180e973e31aSSubhransu S. Prusty 			SKL_DSP_PD_TO,
181e973e31aSSubhransu S. Prusty 			"Power down");
182e973e31aSSubhransu S. Prusty }
183e973e31aSSubhransu S. Prusty 
184e973e31aSSubhransu S. Prusty static int skl_dsp_enable_core(struct sst_dsp  *ctx)
185e973e31aSSubhransu S. Prusty {
186e973e31aSSubhransu S. Prusty 	int ret;
187e973e31aSSubhransu S. Prusty 
188e973e31aSSubhransu S. Prusty 	/* power up */
189e973e31aSSubhransu S. Prusty 	ret = skl_dsp_core_power_up(ctx);
190e973e31aSSubhransu S. Prusty 	if (ret < 0) {
191e973e31aSSubhransu S. Prusty 		dev_dbg(ctx->dev, "dsp core power up failed\n");
192e973e31aSSubhransu S. Prusty 		return ret;
193e973e31aSSubhransu S. Prusty 	}
194e973e31aSSubhransu S. Prusty 
195e973e31aSSubhransu S. Prusty 	return skl_dsp_start_core(ctx);
196e973e31aSSubhransu S. Prusty }
197e973e31aSSubhransu S. Prusty 
198e973e31aSSubhransu S. Prusty int skl_dsp_disable_core(struct sst_dsp  *ctx)
199e973e31aSSubhransu S. Prusty {
200e973e31aSSubhransu S. Prusty 	int ret;
201e973e31aSSubhransu S. Prusty 
202e973e31aSSubhransu S. Prusty 	ret = skl_dsp_reset_core(ctx);
203e973e31aSSubhransu S. Prusty 	if (ret < 0) {
204e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "dsp core reset failed\n");
205e973e31aSSubhransu S. Prusty 		return ret;
206e973e31aSSubhransu S. Prusty 	}
207e973e31aSSubhransu S. Prusty 
208e973e31aSSubhransu S. Prusty 	/* power down core*/
209e973e31aSSubhransu S. Prusty 	ret = skl_dsp_core_power_down(ctx);
210e973e31aSSubhransu S. Prusty 	if (ret < 0) {
211e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "dsp core power down failed\n");
212e973e31aSSubhransu S. Prusty 		return ret;
213e973e31aSSubhransu S. Prusty 	}
214e973e31aSSubhransu S. Prusty 
215e973e31aSSubhransu S. Prusty 	if (is_skl_dsp_core_enable(ctx)) {
216e973e31aSSubhransu S. Prusty 		dev_err(ctx->dev, "DSP core disable failed\n");
217e973e31aSSubhransu S. Prusty 		ret = -EIO;
218e973e31aSSubhransu S. Prusty 	}
219e973e31aSSubhransu S. Prusty 
220e973e31aSSubhransu S. Prusty 	return ret;
221e973e31aSSubhransu S. Prusty }
222e973e31aSSubhransu S. Prusty 
223e973e31aSSubhransu S. Prusty int skl_dsp_boot(struct sst_dsp *ctx)
224e973e31aSSubhransu S. Prusty {
225e973e31aSSubhransu S. Prusty 	int ret;
226e973e31aSSubhransu S. Prusty 
227e973e31aSSubhransu S. Prusty 	if (is_skl_dsp_core_enable(ctx)) {
228e973e31aSSubhransu S. Prusty 		dev_dbg(ctx->dev, "dsp core is already enabled, so reset the dap core\n");
229e973e31aSSubhransu S. Prusty 		ret = skl_dsp_reset_core(ctx);
230e973e31aSSubhransu S. Prusty 		if (ret < 0) {
231e973e31aSSubhransu S. Prusty 			dev_err(ctx->dev, "dsp reset failed\n");
232e973e31aSSubhransu S. Prusty 			return ret;
233e973e31aSSubhransu S. Prusty 		}
234e973e31aSSubhransu S. Prusty 
235e973e31aSSubhransu S. Prusty 		ret = skl_dsp_start_core(ctx);
236e973e31aSSubhransu S. Prusty 		if (ret < 0) {
237e973e31aSSubhransu S. Prusty 			dev_err(ctx->dev, "dsp start failed\n");
238e973e31aSSubhransu S. Prusty 			return ret;
239e973e31aSSubhransu S. Prusty 		}
240e973e31aSSubhransu S. Prusty 	} else {
241e973e31aSSubhransu S. Prusty 		dev_dbg(ctx->dev, "disable and enable to make sure DSP is invalid state\n");
242e973e31aSSubhransu S. Prusty 		ret = skl_dsp_disable_core(ctx);
243e973e31aSSubhransu S. Prusty 
244e973e31aSSubhransu S. Prusty 		if (ret < 0) {
245e973e31aSSubhransu S. Prusty 			dev_err(ctx->dev, "dsp disable core failes\n");
246e973e31aSSubhransu S. Prusty 			return ret;
247e973e31aSSubhransu S. Prusty 		}
248e973e31aSSubhransu S. Prusty 		ret = skl_dsp_enable_core(ctx);
249e973e31aSSubhransu S. Prusty 	}
250e973e31aSSubhransu S. Prusty 
251e973e31aSSubhransu S. Prusty 	return ret;
252e973e31aSSubhransu S. Prusty }
253e973e31aSSubhransu S. Prusty 
254e973e31aSSubhransu S. Prusty irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
255e973e31aSSubhransu S. Prusty {
256e973e31aSSubhransu S. Prusty 	struct sst_dsp *ctx = dev_id;
257e973e31aSSubhransu S. Prusty 	u32 val;
258e973e31aSSubhransu S. Prusty 	irqreturn_t result = IRQ_NONE;
259e973e31aSSubhransu S. Prusty 
260e973e31aSSubhransu S. Prusty 	spin_lock(&ctx->spinlock);
261e973e31aSSubhransu S. Prusty 
262e973e31aSSubhransu S. Prusty 	val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS);
263e973e31aSSubhransu S. Prusty 	ctx->intr_status = val;
264e973e31aSSubhransu S. Prusty 
265def656feSJeeja KP 	if (val == 0xffffffff) {
266def656feSJeeja KP 		spin_unlock(&ctx->spinlock);
267def656feSJeeja KP 		return IRQ_NONE;
268def656feSJeeja KP 	}
269def656feSJeeja KP 
270e973e31aSSubhransu S. Prusty 	if (val & SKL_ADSPIS_IPC) {
271e973e31aSSubhransu S. Prusty 		skl_ipc_int_disable(ctx);
272e973e31aSSubhransu S. Prusty 		result = IRQ_WAKE_THREAD;
273e973e31aSSubhransu S. Prusty 	}
274e973e31aSSubhransu S. Prusty 
2756cb00333SSubhransu S. Prusty 	if (val & SKL_ADSPIS_CL_DMA) {
2766cb00333SSubhransu S. Prusty 		skl_cldma_int_disable(ctx);
2776cb00333SSubhransu S. Prusty 		result = IRQ_WAKE_THREAD;
2786cb00333SSubhransu S. Prusty 	}
2796cb00333SSubhransu S. Prusty 
280e973e31aSSubhransu S. Prusty 	spin_unlock(&ctx->spinlock);
281e973e31aSSubhransu S. Prusty 
282e973e31aSSubhransu S. Prusty 	return result;
283e973e31aSSubhransu S. Prusty }
284e973e31aSSubhransu S. Prusty 
285e973e31aSSubhransu S. Prusty int skl_dsp_wake(struct sst_dsp *ctx)
286e973e31aSSubhransu S. Prusty {
287e973e31aSSubhransu S. Prusty 	return ctx->fw_ops.set_state_D0(ctx);
288e973e31aSSubhransu S. Prusty }
289e973e31aSSubhransu S. Prusty EXPORT_SYMBOL_GPL(skl_dsp_wake);
290e973e31aSSubhransu S. Prusty 
291e973e31aSSubhransu S. Prusty int skl_dsp_sleep(struct sst_dsp *ctx)
292e973e31aSSubhransu S. Prusty {
293e973e31aSSubhransu S. Prusty 	return ctx->fw_ops.set_state_D3(ctx);
294e973e31aSSubhransu S. Prusty }
295e973e31aSSubhransu S. Prusty EXPORT_SYMBOL_GPL(skl_dsp_sleep);
296e973e31aSSubhransu S. Prusty 
297e973e31aSSubhransu S. Prusty struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
298e973e31aSSubhransu S. Prusty 		struct sst_dsp_device *sst_dev, int irq)
299e973e31aSSubhransu S. Prusty {
300e973e31aSSubhransu S. Prusty 	int ret;
301e973e31aSSubhransu S. Prusty 	struct sst_dsp *sst;
302e973e31aSSubhransu S. Prusty 
303e973e31aSSubhransu S. Prusty 	sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
304e973e31aSSubhransu S. Prusty 	if (sst == NULL)
305e973e31aSSubhransu S. Prusty 		return NULL;
306e973e31aSSubhransu S. Prusty 
307e973e31aSSubhransu S. Prusty 	spin_lock_init(&sst->spinlock);
308e973e31aSSubhransu S. Prusty 	mutex_init(&sst->mutex);
309e973e31aSSubhransu S. Prusty 	sst->dev = dev;
310e973e31aSSubhransu S. Prusty 	sst->sst_dev = sst_dev;
311e973e31aSSubhransu S. Prusty 	sst->irq = irq;
312e973e31aSSubhransu S. Prusty 	sst->ops = sst_dev->ops;
313e973e31aSSubhransu S. Prusty 	sst->thread_context = sst_dev->thread_context;
314e973e31aSSubhransu S. Prusty 
315e973e31aSSubhransu S. Prusty 	/* Initialise SST Audio DSP */
316e973e31aSSubhransu S. Prusty 	if (sst->ops->init) {
317e973e31aSSubhransu S. Prusty 		ret = sst->ops->init(sst, NULL);
318e973e31aSSubhransu S. Prusty 		if (ret < 0)
319e973e31aSSubhransu S. Prusty 			return NULL;
320e973e31aSSubhransu S. Prusty 	}
321e973e31aSSubhransu S. Prusty 
322e973e31aSSubhransu S. Prusty 	/* Register the ISR */
323e973e31aSSubhransu S. Prusty 	ret = request_threaded_irq(sst->irq, sst->ops->irq_handler,
324e973e31aSSubhransu S. Prusty 		sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
325e973e31aSSubhransu S. Prusty 	if (ret) {
326e973e31aSSubhransu S. Prusty 		dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n",
327e973e31aSSubhransu S. Prusty 			       sst->irq);
328e973e31aSSubhransu S. Prusty 		return NULL;
329e973e31aSSubhransu S. Prusty 	}
330e973e31aSSubhransu S. Prusty 
331e973e31aSSubhransu S. Prusty 	return sst;
332e973e31aSSubhransu S. Prusty }
333e973e31aSSubhransu S. Prusty 
334e973e31aSSubhransu S. Prusty void skl_dsp_free(struct sst_dsp *dsp)
335e973e31aSSubhransu S. Prusty {
336e973e31aSSubhransu S. Prusty 	skl_ipc_int_disable(dsp);
337e973e31aSSubhransu S. Prusty 
338e973e31aSSubhransu S. Prusty 	free_irq(dsp->irq, dsp);
339e973e31aSSubhransu S. Prusty 	skl_dsp_disable_core(dsp);
340e973e31aSSubhransu S. Prusty }
341e973e31aSSubhransu S. Prusty EXPORT_SYMBOL_GPL(skl_dsp_free);
342e973e31aSSubhransu S. Prusty 
343e973e31aSSubhransu S. Prusty bool is_skl_dsp_running(struct sst_dsp *ctx)
344e973e31aSSubhransu S. Prusty {
345e973e31aSSubhransu S. Prusty 	return (ctx->sst_state == SKL_DSP_RUNNING);
346e973e31aSSubhransu S. Prusty }
347e973e31aSSubhransu S. Prusty EXPORT_SYMBOL_GPL(is_skl_dsp_running);
348