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

Commit b2f47936 authored by Rama Krishna Phani A's avatar Rama Krishna Phani A Committed by Matt Wagantall
Browse files

msm: sps: Handle low memory condition in SPS driver



In low memory condition some bam client is sensitive to timing
and may get time out while allocating memory through kzalloc.

Add support to hold memory during connect and disconnect
and to release memory during client driver's deregistration
of its BAM.

Change-Id: Iaf89dc542b62c95f055e7b06d788d896809b0bf8
Signed-off-by: default avatarRama Krishna Phani A <rphani@codeaurora.org>
parent b6eea41d
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2196,6 +2196,7 @@ EXPORT_SYMBOL(sps_register_bam_device);
int sps_deregister_bam_device(unsigned long dev_handle)
{
	struct sps_bam *bam;
	int n;

	SPS_DBG2("sps:%s.", __func__);

@@ -2212,6 +2213,12 @@ int sps_deregister_bam_device(unsigned long dev_handle)

	SPS_DBG2("sps:SPS deregister BAM: phys %pa.", &bam->props.phys_addr);

	if (bam->props.options & SPS_BAM_HOLD_MEM) {
		for (n = 0; n < BAM_MAX_PIPES; n++)
			if (bam->desc_cache_pointers[n] != NULL)
				kfree(bam->desc_cache_pointers[n]);
	}

	/* If this BAM is attached to a BAM-DMA, init the BAM-DMA device */
#ifdef CONFIG_SPS_SUPPORT_BAMDMA
	if ((bam->props.options & SPS_BAM_OPT_BAMDMA)) {
+35 −17
Original line number Diff line number Diff line
@@ -1071,10 +1071,15 @@ int sps_bam_pipe_disconnect(struct sps_bam *dev, u32 pipe_index)
			bam_pipe_exit(dev->base, pipe_index, dev->props.ee);
		if (pipe->sys.desc_cache != NULL) {
			u32 size = pipe->num_descs * sizeof(void *);
			if (pipe->desc_size + size <= PAGE_SIZE)
				kfree(pipe->sys.desc_cache);
			if (pipe->desc_size + size <= PAGE_SIZE) {
				if (dev->props.options & SPS_BAM_HOLD_MEM)
					memset(pipe->sys.desc_cache, 0,
						pipe->desc_size + size);
				else
					kfree(pipe->sys.desc_cache);
			} else {
				vfree(pipe->sys.desc_cache);
			}
			pipe->sys.desc_cache = NULL;
		}
		dev->pipes[pipe_index] = BAM_PIPE_UNASSIGNED;
@@ -1199,16 +1204,36 @@ int sps_bam_pipe_set_params(struct sps_bam *dev, u32 pipe_index, u32 options)
		/* Allocate both descriptor cache and user pointer array */
		size = pipe->num_descs * sizeof(void *);

		if (pipe->desc_size + size <= PAGE_SIZE)
		if (pipe->desc_size + size <= PAGE_SIZE) {
			if ((dev->props.options &
						SPS_BAM_HOLD_MEM)) {
				if (dev->desc_cache_pointers[pipe_index]) {
					pipe->sys.desc_cache =
				kzalloc(pipe->desc_size + size, GFP_KERNEL);
		else {
						dev->desc_cache_pointers
							[pipe_index];
				} else {
					pipe->sys.desc_cache =
						kzalloc(pipe->desc_size + size,
								GFP_KERNEL);
					dev->desc_cache_pointers[pipe_index] =
							pipe->sys.desc_cache;
				}
			} else {
				pipe->sys.desc_cache =
						kzalloc(pipe->desc_size + size,
							GFP_KERNEL);
			}
			if (pipe->sys.desc_cache == NULL) {
				SPS_ERR("sps:No memory for pipe%d of BAM %pa\n",
						pipe_index, BAM_ID(dev));
				return -ENOMEM;
			}
		} else {
			pipe->sys.desc_cache =
				vmalloc(pipe->desc_size + size);

			if (pipe->sys.desc_cache == NULL) {
				SPS_ERR(
					"sps:No memory for pipe %d of BAM %pa\n",
				SPS_ERR("sps:No memory for pipe%d of BAM %pa\n",
						pipe_index, BAM_ID(dev));
				return -ENOMEM;
			}
@@ -1216,13 +1241,6 @@ int sps_bam_pipe_set_params(struct sps_bam *dev, u32 pipe_index, u32 options)
			memset(pipe->sys.desc_cache, 0, pipe->desc_size + size);
		}

		if (pipe->sys.desc_cache == NULL) {
			/*** MUST BE LAST POINT OF FAILURE (see below) *****/
			SPS_ERR("sps:Desc cache error: BAM %pa pipe %d: %d\n",
				BAM_ID(dev), pipe_index,
				pipe->desc_size + size);
			return SPS_ERROR;
		}
		pipe->sys.user_ptrs = (void **)(pipe->sys.desc_cache +
						 pipe->desc_size);
		pipe->sys.cache_offset = pipe->sys.acked_offset;
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -215,6 +215,9 @@ struct sps_bam {
	u32 irq_from_disabled_pipe;
	u32 event_trigger_failures;

	/* Desc cache pointers */
	u8 *desc_cache_pointers[BAM_MAX_PIPES];

};

/**
+2 −0
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@
#define SPS_BAM_SMMU_EN             (1UL << 9)
/* Confirm resource status before access BAM*/
#define SPS_BAM_RES_CONFIRM         (1UL << 7)
/* Hold memory for BAM DMUX */
#define SPS_BAM_HOLD_MEM            (1UL << 8)

/* BAM device management flags */