diff options
author | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-03-28 07:39:25 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-04-14 12:26:05 -0400 |
commit | 413312aa17ceefe7003ad690778ab72f023128f0 (patch) | |
tree | 72d5103b91be1b4c611dec70118cc41057652381 | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (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.c | 64 |
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 | ||
76 | irq_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 | |||
110 | out: | ||
111 | if (irq_none) | ||
112 | return IRQ_NONE; | ||
113 | else | ||
114 | return IRQ_HANDLED; | ||
89 | } | 115 | } |
90 | 116 | ||
91 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | 117 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, |