aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-03-28 07:39:25 -0400
committerMark Brown <broonie@linaro.org>2014-04-14 12:26:05 -0400
commit413312aa17ceefe7003ad690778ab72f023128f0 (patch)
tree72d5103b91be1b4c611dec70118cc41057652381
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
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: Nicolin Chen <Guangyu.Chen@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/fsl/fsl_sai.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 56da8c8c5960..7194d9280020 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -30,62 +30,88 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
30{ 30{
31 struct fsl_sai *sai = (struct fsl_sai *)devid; 31 struct fsl_sai *sai = (struct fsl_sai *)devid;
32 struct device *dev = &sai->pdev->dev; 32 struct device *dev = &sai->pdev->dev;
33 u32 xcsr, mask; 33 u32 flags, xcsr, mask;
34 bool irq_none = true;
34 35
35 /* Only handle those what we enabled */ 36 /*
37 * Both IRQ status bits and IRQ mask bits are in the xCSR but
38 * different shifts. And we here create a mask only for those
39 * IRQs that we activated.
40 */
36 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; 41 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
37 42
38 /* Tx IRQ */ 43 /* Tx IRQ */
39 regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); 44 regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
40 xcsr &= mask; 45 flags = xcsr & mask;
41 46
42 if (xcsr & FSL_SAI_CSR_WSF) 47 if (flags)
48 irq_none = false;
49 else
50 goto irq_rx;
51
52 if (flags & FSL_SAI_CSR_WSF)
43 dev_dbg(dev, "isr: Start of Tx word detected\n"); 53 dev_dbg(dev, "isr: Start of Tx word detected\n");
44 54
45 if (xcsr & FSL_SAI_CSR_SEF) 55 if (flags & FSL_SAI_CSR_SEF)
46 dev_warn(dev, "isr: Tx Frame sync error detected\n"); 56 dev_warn(dev, "isr: Tx Frame sync error detected\n");
47 57
48 if (xcsr & FSL_SAI_CSR_FEF) { 58 if (flags & FSL_SAI_CSR_FEF) {
49 dev_warn(dev, "isr: Transmit underrun detected\n"); 59 dev_warn(dev, "isr: Transmit underrun detected\n");
50 /* FIFO reset for safety */ 60 /* FIFO reset for safety */
51 xcsr |= FSL_SAI_CSR_FR; 61 xcsr |= FSL_SAI_CSR_FR;
52 } 62 }
53 63
54 if (xcsr & FSL_SAI_CSR_FWF) 64 if (flags & FSL_SAI_CSR_FWF)
55 dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); 65 dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");
56 66
57 if (xcsr & FSL_SAI_CSR_FRF) 67 if (flags & FSL_SAI_CSR_FRF)
58 dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); 68 dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");
59 69
60 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 70 flags &= FSL_SAI_CSR_xF_W_MASK;
61 FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); 71 xcsr &= ~FSL_SAI_CSR_xF_MASK;
72
73 if (flags)
74 regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
62 75
76irq_rx:
63 /* Rx IRQ */ 77 /* Rx IRQ */
64 regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); 78 regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
65 xcsr &= mask; 79 flags = xcsr & mask;
66 80
67 if (xcsr & FSL_SAI_CSR_WSF) 81 if (flags)
82 irq_none = false;
83 else
84 goto out;
85
86 if (flags & FSL_SAI_CSR_WSF)
68 dev_dbg(dev, "isr: Start of Rx word detected\n"); 87 dev_dbg(dev, "isr: Start of Rx word detected\n");
69 88
70 if (xcsr & FSL_SAI_CSR_SEF) 89 if (flags & FSL_SAI_CSR_SEF)
71 dev_warn(dev, "isr: Rx Frame sync error detected\n"); 90 dev_warn(dev, "isr: Rx Frame sync error detected\n");
72 91
73 if (xcsr & FSL_SAI_CSR_FEF) { 92 if (flags & FSL_SAI_CSR_FEF) {
74 dev_warn(dev, "isr: Receive overflow detected\n"); 93 dev_warn(dev, "isr: Receive overflow detected\n");
75 /* FIFO reset for safety */ 94 /* FIFO reset for safety */
76 xcsr |= FSL_SAI_CSR_FR; 95 xcsr |= FSL_SAI_CSR_FR;
77 } 96 }
78 97
79 if (xcsr & FSL_SAI_CSR_FWF) 98 if (flags & FSL_SAI_CSR_FWF)
80 dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); 99 dev_dbg(dev, "isr: Enabled receive FIFO is full\n");
81 100
82 if (xcsr & FSL_SAI_CSR_FRF) 101 if (flags & FSL_SAI_CSR_FRF)
83 dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); 102 dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");
84 103
85 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 104 flags &= FSL_SAI_CSR_xF_W_MASK;
86 FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); 105 xcsr &= ~FSL_SAI_CSR_xF_MASK;
87 106
88 return IRQ_HANDLED; 107 if (flags)
108 regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
109
110out:
111 if (irq_none)
112 return IRQ_NONE;
113 else
114 return IRQ_HANDLED;
89} 115}
90 116
91static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, 117static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,