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

Commit 6af5792b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: sps: check the BAM clock status before access a BAM"

parents 9d98549c 0dc1d186
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -2340,6 +2340,32 @@ int sps_pipe_reset(unsigned long dev, u32 pipe)
}
EXPORT_SYMBOL(sps_pipe_reset);

/*
 * Process any pending IRQ of a BAM
 */
int sps_bam_process_irq(unsigned long dev)
{
	struct sps_bam *bam;

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

	if (!dev) {
		SPS_ERR("sps:%s:BAM handle is NULL.\n", __func__);
		return SPS_ERROR;
	}

	bam = sps_h2bam(dev);
	if (bam == NULL) {
		SPS_ERR("sps:%s:BAM is not found by handle.\n", __func__);
		return SPS_ERROR;
	}

	sps_bam_check_irq(bam);

	return 0;
}
EXPORT_SYMBOL(sps_bam_process_irq);

/**
 * Allocate client state context
 *
+72 −17
Original line number Diff line number Diff line
@@ -118,22 +118,17 @@ int sps_bam_driver_init(u32 options)
	return 0;
}

/**
 * BAM interrupt service routine
 *
 * This function is the BAM interrupt service routine.
 *
 * @ctxt - pointer to ISR's registered argument
 *
 * @return void
/*
 * Check BAM interrupt
 */
static irqreturn_t bam_isr(int irq, void *ctxt)
int sps_bam_check_irq(struct sps_bam *dev)
{
	struct sps_bam *dev = ctxt;
	struct sps_pipe *pipe;
	u32 source;
	unsigned long flags = 0;
	int ret = 0;

	SPS_DBG1("sps:%s:bam=%pa.\n", __func__, BAM_ID(dev));

	spin_lock_irqsave(&dev->isr_lock, flags);

@@ -144,11 +139,11 @@ static irqreturn_t bam_isr(int irq, void *ctxt)
		source = bam_check_irq_source(dev->base, dev->props.ee,
						mask, &cb_case);

		SPS_DBG1("sps:bam_isr:bam=%pa;source=0x%x;mask=0x%x.\n",
		SPS_DBG1("sps:bam=%pa;source=0x%x;mask=0x%x.\n",
				BAM_ID(dev), source, mask);

		if ((source & (1UL << 31)) && (dev->props.callback)) {
			SPS_DBG1("sps:bam_isr:bam=%pa;callback for case %d.\n",
			SPS_DBG1("sps:bam=%pa;callback for case %d.\n",
				BAM_ID(dev), cb_case);
			dev->props.callback(cb_case, dev->props.user);
		}
@@ -159,7 +154,7 @@ static irqreturn_t bam_isr(int irq, void *ctxt)
		/* If MTIs are used, must poll each active pipe */
		source = dev->pipe_active_mask;

		SPS_DBG1("sps:bam_isr for MTI:bam=%pa;source=0x%x.\n",
		SPS_DBG1("sps:MTI:bam=%pa;source=0x%x.\n",
				BAM_ID(dev), source);
	}

@@ -188,6 +183,50 @@ static irqreturn_t bam_isr(int irq, void *ctxt)

	spin_unlock_irqrestore(&dev->isr_lock, flags);

	return ret;
}

/**
 * BAM interrupt service routine
 *
 * This function is the BAM interrupt service routine.
 *
 * @ctxt - pointer to ISR's registered argument
 *
 * @return void
 */
static irqreturn_t bam_isr(int irq, void *ctxt)
{
	struct sps_bam *dev = ctxt;

	SPS_DBG1("sps:bam_isr: bam:%pa; IRQ #:%d.\n",
		BAM_ID(dev), irq);

	if (dev->props.options & SPS_BAM_RES_CONFIRM) {
		if (dev->props.callback) {
			bool ready = false;
			dev->props.callback(SPS_CALLBACK_BAM_RES_REQ, &ready);
			if (ready) {
				SPS_DBG1(
					"sps:bam_isr: handle IRQ for bam:%pa IRQ #:%d.\n",
					BAM_ID(dev), irq);
				sps_bam_check_irq(dev);
				dev->props.callback(SPS_CALLBACK_BAM_RES_REL,
							&ready);
			} else {
				SPS_DBG1(
					"sps:bam_isr: BAM is not ready and thus skip IRQ for bam:%pa IRQ #:%d.\n",
					BAM_ID(dev), irq);
			}
		} else {
			SPS_ERR(
				"sps:Client of BAM %pa requires confirmation but does not register callback\n",
				BAM_ID(dev));
		}
	} else {
		sps_bam_check_irq(dev);
	}

	return IRQ_HANDLED;
}

@@ -220,10 +259,26 @@ int sps_bam_enable(struct sps_bam *dev)
		dev->state &= ~BAM_STATE_IRQ;
	} else {
		/* Register BAM ISR */
		if (dev->props.irq > 0)
		if (dev->props.irq > 0) {
			if (dev->props.options & SPS_BAM_RES_CONFIRM) {
				result = request_irq(dev->props.irq,
					(irq_handler_t) bam_isr,
					IRQF_TRIGGER_RISING, "sps", dev);
				SPS_DBG(
					"sps:BAM %pa uses edge for IRQ# %d\n",
					BAM_ID(dev), dev->props.irq);
			} else {
				result = request_irq(dev->props.irq,
					(irq_handler_t) bam_isr,
					IRQF_TRIGGER_HIGH, "sps", dev);
				SPS_DBG(
					"sps:BAM %pa uses level for IRQ# %d\n",
					BAM_ID(dev), dev->props.irq);
			}
		} else {
			SPS_DBG1("sps:BAM %pa does not have an vaild IRQ# %d\n",
				BAM_ID(dev), dev->props.irq);
		}

		if (result) {
			SPS_ERR("sps:Failed to enable BAM %pa IRQ %d\n",
+9 −0
Original line number Diff line number Diff line
@@ -569,4 +569,13 @@ int sps_bam_pipe_timer_ctrl(struct sps_bam *dev, u32 pipe_index,
int sps_bam_pipe_get_unused_desc_num(struct sps_bam *dev, u32 pipe_index,
					u32 *desc_num);

/*
 * sps_bam_check_irq - check IRQ of a BAM device.
 * @dev - pointer to BAM device descriptor
 *
 * This function checks any pending interrupt of a BAM device.
 *
 * Return: 0 on success, negative value on error
 */
int sps_bam_check_irq(struct sps_bam *dev);
#endif	/* _SPSBAM_H_ */
+19 −1
Original line number Diff line number Diff line
@@ -109,7 +109,8 @@
#define SPS_BAM_NO_LOCAL_CLK_GATING (1UL << 5)
/* Don't enable writeback cancel*/
#define SPS_BAM_CANCEL_WB           (1UL << 6)

/* Confirm resource status before access BAM*/
#define SPS_BAM_RES_CONFIRM         (1UL << 7)

/* BAM device management flags */

@@ -296,6 +297,8 @@ enum sps_callback_case {
	SPS_CALLBACK_BAM_ERROR_IRQ = 1,     /* BAM ERROR IRQ */
	SPS_CALLBACK_BAM_HRESP_ERR_IRQ,	    /* Erroneous HResponse */
	SPS_CALLBACK_BAM_TIMER_IRQ,	    /* Inactivity timer */
	SPS_CALLBACK_BAM_RES_REQ,	    /* Request resource */
	SPS_CALLBACK_BAM_RES_REL,	    /* Release resource */
};

/*
@@ -1358,6 +1361,16 @@ int sps_ctrl_bam_dma_clk(bool clk_on);
 * Return: 0 on success, negative value on error
 */
int sps_pipe_reset(unsigned long dev, u32 pipe);

/*
 * sps_bam_process_irq - process IRQ of a BAM.
 * @dev:	BAM device handle
 *
 * This function processes any pending IRQ of a BAM.
 *
 * Return: 0 on success, negative value on error
 */
int sps_bam_process_irq(unsigned long dev);
#else
static inline int sps_register_bam_device(const struct sps_bam_props
			*bam_props, unsigned long *dev_handle)
@@ -1530,6 +1543,11 @@ static inline int sps_pipe_reset(unsigned long dev, u32 pipe)
{
	return -EPERM;
}

static inline int sps_bam_process_irq(unsigned long dev)
{
	return -EPERM;
}
#endif

#endif /* _SPS_H_ */