Commit 413312aa authored by Nicolin Chen's avatar Nicolin Chen Committed by Mark Brown
Browse files

ASoC: fsl_sai: Improve fsl_sai_isr()



This patch improves fsl_sai_isr() in these ways:
1, Add comment for mask fetching code.
2, Return IRQ_NONE if the IRQ is not for the device.
3, Use regmap_write() instead of regmap_update_bits().

Signed-off-by: default avatarNicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent c9eaa447
Loading
Loading
Loading
Loading
+45 −19
Original line number Diff line number Diff line
@@ -30,61 +30,87 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
{
	struct fsl_sai *sai = (struct fsl_sai *)devid;
	struct device *dev = &sai->pdev->dev;
	u32 xcsr, mask;
	u32 flags, xcsr, mask;
	bool irq_none = true;

	/* Only handle those what we enabled */
	/*
	 * Both IRQ status bits and IRQ mask bits are in the xCSR but
	 * different shifts. And we here create a mask only for those
	 * IRQs that we activated.
	 */
	mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;

	/* Tx IRQ */
	regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
	xcsr &= mask;
	flags = xcsr & mask;

	if (xcsr & FSL_SAI_CSR_WSF)
	if (flags)
		irq_none = false;
	else
		goto irq_rx;

	if (flags & FSL_SAI_CSR_WSF)
		dev_dbg(dev, "isr: Start of Tx word detected\n");

	if (xcsr & FSL_SAI_CSR_SEF)
	if (flags & FSL_SAI_CSR_SEF)
		dev_warn(dev, "isr: Tx Frame sync error detected\n");

	if (xcsr & FSL_SAI_CSR_FEF) {
	if (flags & FSL_SAI_CSR_FEF) {
		dev_warn(dev, "isr: Transmit underrun detected\n");
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

	if (xcsr & FSL_SAI_CSR_FWF)
	if (flags & FSL_SAI_CSR_FWF)
		dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");

	if (xcsr & FSL_SAI_CSR_FRF)
	if (flags & FSL_SAI_CSR_FRF)
		dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");

	regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
			   FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;

	if (flags)
		regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);

irq_rx:
	/* Rx IRQ */
	regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
	xcsr &= mask;
	flags = xcsr & mask;

	if (xcsr & FSL_SAI_CSR_WSF)
	if (flags)
		irq_none = false;
	else
		goto out;

	if (flags & FSL_SAI_CSR_WSF)
		dev_dbg(dev, "isr: Start of Rx word detected\n");

	if (xcsr & FSL_SAI_CSR_SEF)
	if (flags & FSL_SAI_CSR_SEF)
		dev_warn(dev, "isr: Rx Frame sync error detected\n");

	if (xcsr & FSL_SAI_CSR_FEF) {
	if (flags & FSL_SAI_CSR_FEF) {
		dev_warn(dev, "isr: Receive overflow detected\n");
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

	if (xcsr & FSL_SAI_CSR_FWF)
	if (flags & FSL_SAI_CSR_FWF)
		dev_dbg(dev, "isr: Enabled receive FIFO is full\n");

	if (xcsr & FSL_SAI_CSR_FRF)
	if (flags & FSL_SAI_CSR_FRF)
		dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");

	regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
			   FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;

	if (flags)
		regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);

out:
	if (irq_none)
		return IRQ_NONE;
	else
		return IRQ_HANDLED;
}