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

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

ASoC: msm-cpe-lsm: Buffer allocation cleanup



The buffer used for look ahead buffering is allocated by cpe core
driver. Fix to perform cleanup of data structures shared across platform
driver and cpe core to allow buffer allocation to be done by platform
driver.

Change-Id: Ifaff24025292f2e5be6572ca50dcc281ed8d4f84
Signed-off-by: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent bef1abf1
Loading
Loading
Loading
Loading
+4 −39
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <sound/lsm_params.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>

enum {
	CMD_INIT_STATE = 0,
@@ -40,47 +39,13 @@ struct wcd_cpe_afe_port_cfg {
	u32 sample_rate;
};

enum wcd_cpe_lab_thread {
	MSM_LSM_LAB_THREAD_STOP,
	MSM_LSM_LAB_THREAD_RUNNING,
	MSM_LSM_LAB_THREAD_ERROR,
};

struct wcd_cpe_data_pcm_buf {
	u8 *mem;
	phys_addr_t phys;
};

struct wcd_cpe_lab_hw_params {
	u16 sample_rate;
	u16 sample_size;
	u32 buf_sz;
	u32 period_count;
};

struct wcd_cpe_lsm_lab {
	u32 lab_enable;
	void *core_handle;
	atomic_t in_count;
	atomic_t abort_read;
	u32 dma_write;
	u32 buf_idx;
	u32 pcm_size;
	enum wcd_cpe_lab_thread thread_status;
	struct cpe_lsm_session *lsm_s;
	struct snd_pcm_substream *substream;
	struct wcd_cpe_lab_hw_params hw_params;
	struct wcd_cpe_data_pcm_buf *pcm_buf;
	wait_queue_head_t period_wait;
	struct completion thread_complete;
	struct completion comp;
};

struct cpe_lsm_session {
	/* sound model related */
	void *snd_model_data;
	u8 *conf_levels;
	void *cmi_reg_handle;

	/* Clients private data */
	void *priv_d;

	void (*event_cb) (void *priv_data,
@@ -97,8 +62,9 @@ struct cpe_lsm_session {
	u8 id;
	u8 num_confidence_levels;
	struct task_struct *lsm_lab_thread;
	struct wcd_cpe_lsm_lab lab;
	bool started;

	u32 lab_enable;
};

struct wcd_cpe_afe_ops {
@@ -156,7 +122,6 @@ struct wcd_cpe_lsm_ops {

	int (*lsm_lab_control)(void *core_handle,
			       struct cpe_lsm_session *session,
			       u32 bufsz, u32 bufcnt,
			       bool enable);

	int (*lab_ch_setup)(void *core_handle,
+10 −193
Original line number Diff line number Diff line
@@ -2561,7 +2561,7 @@ end_ret:
 * @lsm_priv_d: lsm private data
 */
static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session(
	void *core_handle, void *lsm_priv_d,
	void *core_handle, void *client_data,
	void (*event_cb) (void *, u8, u8, u8 *))
{
	struct cpe_lsm_session *session;
@@ -2619,7 +2619,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session(
			__func__);
		goto err_ret;
	}
	session->priv_d = lsm_priv_d;
	session->priv_d = client_data;
	mutex_init(&session->lsm_lock);
	if (afe_register_service) {
		/* Register for AFE Service */
@@ -2700,157 +2700,17 @@ static int wcd_cpe_lsm_config_lab_latency(
}

/*
 * wcd_cpe_buf_alloc: allocate lab DMA buffer.
 * @core: handle to wcd_cpe_core
 * @session: lsm session to be deallocated
 */
static int wcd_cpe_buf_alloc(void *core_handle,
			     struct cpe_lsm_session *session,
			     u32 bufsz, u32 bufcnt)
{
	int rc = 0;
	int dma_alloc = 0;
	u32 count = 0;
	struct wcd_cpe_data_pcm_buf *pcm_buf = NULL;
	struct wcd_cpe_core *core = (struct wcd_cpe_core *)core_handle;
	struct wcd_cpe_lsm_lab *lab = NULL;
	struct snd_soc_codec *codec;
	struct wcd9xxx *wcd9xxx;


	pr_debug("%s:Buf Size %d Buf count %d\n", __func__,
		 bufsz, bufcnt);

	if (bufcnt <= 0 || bufsz <= 0) {
		pr_err("%s:HW Params Error for LAB\n", __func__);
		rc = -EINVAL;
		goto exit;
	}
	if (core == NULL || session == NULL) {
		pr_err("%s:Err core handle/Session ptr NULL\n", __func__);
		rc = -EINVAL;
		goto exit;
	}
	codec = core->codec;
	wcd9xxx = dev_get_drvdata(codec->dev->parent);
	if (session)
		lab = &session->lab;
	else {
		pr_err("%s: Session ptr NULL\n", __func__);
		rc = -EINVAL;
		goto exit;

	}
	pcm_buf = kzalloc(((sizeof(struct wcd_cpe_data_pcm_buf)) * bufcnt),
			  GFP_KERNEL);
	if (!pcm_buf) {
		pr_err("%s: No memory for pcm_buf\n", __func__);
		rc = -ENOMEM;
		goto exit;
	}
	lab->pcm_buf = pcm_buf;
	dma_alloc = bufsz * bufcnt;
	pcm_buf->mem = NULL;
	pcm_buf->mem = dma_alloc_coherent(wcd9xxx->slim->dev.parent,
					  dma_alloc,
					  &(pcm_buf->phys),
					  GFP_KERNEL);

	if (pcm_buf->mem == NULL) {
		pr_err("%s:DMA alloc failed size = %x\n",
		       __func__, dma_alloc);
		rc = -ENOMEM;
		goto fail;
	}
	count = 0;
	while (count < bufcnt) {
		pcm_buf[count].mem =  pcm_buf[0].mem + (count * bufsz);
		pcm_buf[count].phys =  pcm_buf[0].phys + (count * bufsz);
		if (!pcm_buf[count].mem) {
			pr_err("%s: pcm buf mem Null\n", __func__);
				rc = -EINVAL;
				goto fail;
		}
		pr_debug("%s: pcm_buf[%d].mem %p pcm_buf[%d].phys %pa\n",
			 __func__, count,
			 (void *)pcm_buf[count].mem,
			 count, &(pcm_buf[count].phys));
		count++;
	}

	return 0;
fail:
	if (pcm_buf) {
		if (pcm_buf->mem)
			dma_free_coherent(wcd9xxx->slim->dev.parent, dma_alloc,
					  pcm_buf->mem, pcm_buf->phys);
		kfree(pcm_buf);
	}
exit:
	return rc;
}

/*
 * wcd_cpe_buf_dealloc: deallocate DMA buffers
 * wcd_cpe_lsm_lab_control: enable/disable lab
 * @core: handle to wcd_cpe_core
 * @session: lsm session
 * @bufz: buffer size
 * @bufCnt: no of period or buffers
 * @enable: Indicates whether to enable / disable lab
 */
static int wcd_cpe_buf_dealloc(void *core_handle,
			       struct cpe_lsm_session *session,
			       u32 bufsz, u32 bufcnt)
{
	int rc = 0;
	int dma_alloc = 0;
	struct wcd_cpe_data_pcm_buf *pcm_buf = NULL;
	struct wcd_cpe_core *core = (struct wcd_cpe_core *)core_handle;
	struct wcd_cpe_lsm_lab *lab = NULL;
	struct snd_soc_codec *codec;
	struct wcd9xxx *wcd9xxx;

	pr_debug("%s:Buf Size %d Buf count %d\n", __func__,
		 bufsz, bufcnt);

	if (bufcnt <= 0 || bufsz <= 0) {
		pr_err("%s:HW Params Error for LAB\n", __func__);
		return -EINVAL;
	}

	if (core == NULL || session == NULL) {
		pr_err("%s:Err core handle/Session ptr NULL\n", __func__);
		rc = -ENOMEM;
		return rc;
	}
	codec = core->codec;
	wcd9xxx = dev_get_drvdata(codec->dev->parent);
	if (session)
		lab = &session->lab;
	else {
		pr_err("%s: Session ptr NULL\n", __func__);
		rc = -EINVAL;
		return rc;
	}
	pcm_buf = lab->pcm_buf;
	dma_alloc = bufsz * bufcnt;
	if (pcm_buf)
		dma_free_coherent(wcd9xxx->slim->dev.parent, dma_alloc,
				  pcm_buf->mem, pcm_buf->phys);
	kfree(pcm_buf);
	lab->pcm_buf = NULL;
	return rc;
}

/*
 * wcd_cpe_lsm_lab_enable_disable: enable/disable lab
 * @core: handle to wcd_cpe_core
 * @session: lsm session
 */
static int wcd_cpe_lsm_lab_enable_disable(
				struct wcd_cpe_core *core,
static int wcd_cpe_lsm_lab_control(
		void *core_handle,
		struct cpe_lsm_session *session,
		bool enable)
{
	struct wcd_cpe_core *core = core_handle;
	int ret = 0, pld_size = CPE_PARAM_SIZE_LSM_LAB_CONTROL;
	struct cpe_lsm_control_lab cpe_lab_enable;
	struct cpe_lsm_lab_enable *lab_enable = &cpe_lab_enable.lab_enable;
@@ -2886,49 +2746,6 @@ static int wcd_cpe_lsm_lab_enable_disable(
	return 0;
}

static int wcd_cpe_lsm_control_lab(void *core_handle,
				   struct cpe_lsm_session *session,
				   u32 bufsz, u32 bufcnt, bool enable)
{
	int rc = 0;
	struct wcd_cpe_core *core = (struct wcd_cpe_core *)core_handle;

	if (enable) {
		rc = wcd_cpe_buf_alloc(core_handle, session, bufsz, bufcnt);
		if (rc) {
			pr_err("%s: DMA buffer allocation failed rc %d\n",
			       __func__, rc);
			return rc;
		}
		rc = wcd_cpe_lsm_lab_enable_disable(core, session, enable);
		if (rc) {
			pr_err("%s: LAB disable/ Enable failed rc %d\n",
			       __func__, rc);
			return rc;
		}
		session->lab.core_handle = core_handle;
		session->lab.lsm_s = session;
	} else {
		rc = wcd_cpe_buf_dealloc(core_handle, session, bufsz, bufcnt);
		/* do not return error for DMA dealloc put
		 * session in detection mode
		 */
		if (rc) {
			pr_err("%s: DMA buffer De-allocation failed, rc %d\n",
			       __func__, rc);
		}

		rc = wcd_cpe_lsm_lab_enable_disable(core, session, enable);
		if (rc) {
			pr_err("%s: LAB disable/ Enable failed rc %d\n",
			       __func__, rc);
			return rc;
		}
		session->lab.lab_enable = false;
	}
	return rc;
}

/*
 * wcd_cpe_lsm_eob: stop lab
 * @core: handle to wcd_cpe_core
@@ -3122,7 +2939,7 @@ int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops)
	lsm_ops->lsm_deregister_snd_model = wcd_cpe_lsm_dereg_snd_model;
	lsm_ops->lsm_start = wcd_cpe_cmd_lsm_start;
	lsm_ops->lsm_stop = wcd_cpe_cmd_lsm_stop;
	lsm_ops->lsm_lab_control = wcd_cpe_lsm_control_lab;
	lsm_ops->lsm_lab_control = wcd_cpe_lsm_lab_control;
	lsm_ops->lab_ch_setup = wcd_cpe_lab_ch_setup;
	lsm_ops->lsm_set_data = wcd_cpe_lsm_set_data;
	return 0;
+381 −189

File changed.

Preview size limit exceeded, changes collapsed.