diff options
author | Markus Pargmann <mpa@pengutronix.de> | 2013-12-20 08:11:31 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-08 12:20:31 -0500 |
commit | 0888efd166fa99b733b0b68e70d2fb3c3c7684ec (patch) | |
tree | 7cafde2d003bae33f61bd6f93e4b87007fd444d7 /sound/soc/fsl | |
parent | c1953bfe1329eeb16991d430d574c4280697ad17 (diff) |
ASoC: fsl-ssi: Fix interrupt stats for imx
irqs should only be requested/released with enabled DMA. Previously
interrupt statistics where disabled for IMX Processors because of
different writeable SISR bits.
This patch introduces support for irqstats on imx processors again by
creating a sisr writeback mask and introducing a imx35-ssi compatible.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 671be33aa9d2..bc904696d820 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -127,6 +127,7 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | |||
127 | enum fsl_ssi_type { | 127 | enum fsl_ssi_type { |
128 | FSL_SSI_MCP8610, | 128 | FSL_SSI_MCP8610, |
129 | FSL_SSI_MX21, | 129 | FSL_SSI_MX21, |
130 | FSL_SSI_MX35, | ||
130 | FSL_SSI_MX51, | 131 | FSL_SSI_MX51, |
131 | }; | 132 | }; |
132 | 133 | ||
@@ -151,6 +152,7 @@ struct fsl_ssi_private { | |||
151 | struct snd_soc_dai_driver cpu_dai_drv; | 152 | struct snd_soc_dai_driver cpu_dai_drv; |
152 | struct platform_device *pdev; | 153 | struct platform_device *pdev; |
153 | 154 | ||
155 | enum fsl_ssi_type hw_type; | ||
154 | bool new_binding; | 156 | bool new_binding; |
155 | bool ssi_on_imx; | 157 | bool ssi_on_imx; |
156 | bool imx_ac97; | 158 | bool imx_ac97; |
@@ -199,6 +201,7 @@ struct fsl_ssi_private { | |||
199 | static const struct of_device_id fsl_ssi_ids[] = { | 201 | static const struct of_device_id fsl_ssi_ids[] = { |
200 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, | 202 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, |
201 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, | 203 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, |
204 | { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35}, | ||
202 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, | 205 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, |
203 | {} | 206 | {} |
204 | }; | 207 | }; |
@@ -222,7 +225,26 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
222 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 225 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
223 | irqreturn_t ret = IRQ_NONE; | 226 | irqreturn_t ret = IRQ_NONE; |
224 | __be32 sisr; | 227 | __be32 sisr; |
225 | __be32 sisr2 = 0; | 228 | __be32 sisr2; |
229 | __be32 sisr_write_mask = 0; | ||
230 | |||
231 | switch (ssi_private->hw_type) { | ||
232 | case FSL_SSI_MX21: | ||
233 | sisr_write_mask = 0; | ||
234 | break; | ||
235 | |||
236 | case FSL_SSI_MCP8610: | ||
237 | case FSL_SSI_MX35: | ||
238 | sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | ||
239 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
240 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
241 | break; | ||
242 | |||
243 | case FSL_SSI_MX51: | ||
244 | sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
245 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
246 | break; | ||
247 | } | ||
226 | 248 | ||
227 | /* We got an interrupt, so read the status register to see what we | 249 | /* We got an interrupt, so read the status register to see what we |
228 | were interrupted for. We mask it with the Interrupt Enable register | 250 | were interrupted for. We mask it with the Interrupt Enable register |
@@ -232,13 +254,11 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
232 | 254 | ||
233 | if (sisr & CCSR_SSI_SISR_RFRC) { | 255 | if (sisr & CCSR_SSI_SISR_RFRC) { |
234 | ssi_private->stats.rfrc++; | 256 | ssi_private->stats.rfrc++; |
235 | sisr2 |= CCSR_SSI_SISR_RFRC; | ||
236 | ret = IRQ_HANDLED; | 257 | ret = IRQ_HANDLED; |
237 | } | 258 | } |
238 | 259 | ||
239 | if (sisr & CCSR_SSI_SISR_TFRC) { | 260 | if (sisr & CCSR_SSI_SISR_TFRC) { |
240 | ssi_private->stats.tfrc++; | 261 | ssi_private->stats.tfrc++; |
241 | sisr2 |= CCSR_SSI_SISR_TFRC; | ||
242 | ret = IRQ_HANDLED; | 262 | ret = IRQ_HANDLED; |
243 | } | 263 | } |
244 | 264 | ||
@@ -279,25 +299,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
279 | 299 | ||
280 | if (sisr & CCSR_SSI_SISR_ROE1) { | 300 | if (sisr & CCSR_SSI_SISR_ROE1) { |
281 | ssi_private->stats.roe1++; | 301 | ssi_private->stats.roe1++; |
282 | sisr2 |= CCSR_SSI_SISR_ROE1; | ||
283 | ret = IRQ_HANDLED; | 302 | ret = IRQ_HANDLED; |
284 | } | 303 | } |
285 | 304 | ||
286 | if (sisr & CCSR_SSI_SISR_ROE0) { | 305 | if (sisr & CCSR_SSI_SISR_ROE0) { |
287 | ssi_private->stats.roe0++; | 306 | ssi_private->stats.roe0++; |
288 | sisr2 |= CCSR_SSI_SISR_ROE0; | ||
289 | ret = IRQ_HANDLED; | 307 | ret = IRQ_HANDLED; |
290 | } | 308 | } |
291 | 309 | ||
292 | if (sisr & CCSR_SSI_SISR_TUE1) { | 310 | if (sisr & CCSR_SSI_SISR_TUE1) { |
293 | ssi_private->stats.tue1++; | 311 | ssi_private->stats.tue1++; |
294 | sisr2 |= CCSR_SSI_SISR_TUE1; | ||
295 | ret = IRQ_HANDLED; | 312 | ret = IRQ_HANDLED; |
296 | } | 313 | } |
297 | 314 | ||
298 | if (sisr & CCSR_SSI_SISR_TUE0) { | 315 | if (sisr & CCSR_SSI_SISR_TUE0) { |
299 | ssi_private->stats.tue0++; | 316 | ssi_private->stats.tue0++; |
300 | sisr2 |= CCSR_SSI_SISR_TUE0; | ||
301 | ret = IRQ_HANDLED; | 317 | ret = IRQ_HANDLED; |
302 | } | 318 | } |
303 | 319 | ||
@@ -341,6 +357,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
341 | ret = IRQ_HANDLED; | 357 | ret = IRQ_HANDLED; |
342 | } | 358 | } |
343 | 359 | ||
360 | sisr2 = sisr & sisr_write_mask; | ||
344 | /* Clear the bits that we set */ | 361 | /* Clear the bits that we set */ |
345 | if (sisr2) | 362 | if (sisr2) |
346 | write_ssi(sisr2, &ssi->sisr); | 363 | write_ssi(sisr2, &ssi->sisr); |
@@ -1180,6 +1197,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1180 | 1197 | ||
1181 | ssi_private->use_dma = !of_property_read_bool(np, | 1198 | ssi_private->use_dma = !of_property_read_bool(np, |
1182 | "fsl,fiq-stream-filter"); | 1199 | "fsl,fiq-stream-filter"); |
1200 | ssi_private->hw_type = hw_type; | ||
1183 | 1201 | ||
1184 | if (ac97) { | 1202 | if (ac97) { |
1185 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, | 1203 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, |
@@ -1299,7 +1317,13 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1299 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1317 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); |
1300 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, | 1318 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, |
1301 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1319 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); |
1302 | } else if (ssi_private->use_dma) { | 1320 | } |
1321 | |||
1322 | /* | ||
1323 | * Enable interrupts only for MCP8610 and MX51. The other MXs have | ||
1324 | * different writeable interrupt status registers. | ||
1325 | */ | ||
1326 | if (ssi_private->use_dma) { | ||
1303 | /* The 'name' should not have any slashes in it. */ | 1327 | /* The 'name' should not have any slashes in it. */ |
1304 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, | 1328 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, |
1305 | fsl_ssi_isr, 0, ssi_private->name, | 1329 | fsl_ssi_isr, 0, ssi_private->name, |