diff options
author | Markus Pargmann <mpa@pengutronix.de> | 2014-04-28 06:54:43 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-20 18:02:26 -0400 |
commit | f138e6212427d0ea6283e07b706823b657ddf14f (patch) | |
tree | aaddfdb38e47b479a96cb9004736cefa226f2429 | |
parent | 65c961cc59345fa347173e5a1f5866bc866fd626 (diff) |
ASoC: fsl-ssi: Move debugging to seperate file
Move all code that is only used for debugging to a seperate file. This
makes it easier to see what functions are used for debugging only.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-By: Michael Grzeschik <mgr@pengutronix.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | sound/soc/fsl/Makefile | 3 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 241 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.h | 61 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi_dbg.c | 163 |
4 files changed, 232 insertions, 236 deletions
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index b12ad4b9b4da..db254e358c18 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -12,7 +12,8 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o | |||
12 | 12 | ||
13 | # Freescale SSI/DMA/SAI/SPDIF Support | 13 | # Freescale SSI/DMA/SAI/SPDIF Support |
14 | snd-soc-fsl-sai-objs := fsl_sai.o | 14 | snd-soc-fsl-sai-objs := fsl_sai.o |
15 | snd-soc-fsl-ssi-objs := fsl_ssi.o | 15 | snd-soc-fsl-ssi-y := fsl_ssi.o |
16 | snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o | ||
16 | snd-soc-fsl-spdif-objs := fsl_spdif.o | 17 | snd-soc-fsl-spdif-objs := fsl_spdif.o |
17 | snd-soc-fsl-esai-objs := fsl_esai.o | 18 | snd-soc-fsl-esai-objs := fsl_esai.o |
18 | snd-soc-fsl-utils-objs := fsl_utils.o | 19 | snd-soc-fsl-utils-objs := fsl_utils.o |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index fadb264e4cbb..344f752e997d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
38 | #include <linux/debugfs.h> | ||
39 | #include <linux/device.h> | 38 | #include <linux/device.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
@@ -113,8 +112,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | |||
113 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ | 112 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ |
114 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ | 113 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ |
115 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) | 114 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) |
116 | #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) | ||
117 | |||
118 | 115 | ||
119 | enum fsl_ssi_type { | 116 | enum fsl_ssi_type { |
120 | FSL_SSI_MCP8610, | 117 | FSL_SSI_MCP8610, |
@@ -177,31 +174,7 @@ struct fsl_ssi_private { | |||
177 | /* Register values for rx/tx configuration */ | 174 | /* Register values for rx/tx configuration */ |
178 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; | 175 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; |
179 | 176 | ||
180 | struct { | 177 | struct fsl_ssi_dbg dbg_stats; |
181 | unsigned int rfrc; | ||
182 | unsigned int tfrc; | ||
183 | unsigned int cmdau; | ||
184 | unsigned int cmddu; | ||
185 | unsigned int rxt; | ||
186 | unsigned int rdr1; | ||
187 | unsigned int rdr0; | ||
188 | unsigned int tde1; | ||
189 | unsigned int tde0; | ||
190 | unsigned int roe1; | ||
191 | unsigned int roe0; | ||
192 | unsigned int tue1; | ||
193 | unsigned int tue0; | ||
194 | unsigned int tfs; | ||
195 | unsigned int rfs; | ||
196 | unsigned int tls; | ||
197 | unsigned int rls; | ||
198 | unsigned int rff1; | ||
199 | unsigned int rff0; | ||
200 | unsigned int tfe1; | ||
201 | unsigned int tfe0; | ||
202 | } stats; | ||
203 | struct dentry *dbg_dir; | ||
204 | struct dentry *dbg_stats; | ||
205 | 178 | ||
206 | char name[1]; | 179 | char name[1]; |
207 | }; | 180 | }; |
@@ -231,7 +204,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
231 | { | 204 | { |
232 | struct fsl_ssi_private *ssi_private = dev_id; | 205 | struct fsl_ssi_private *ssi_private = dev_id; |
233 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 206 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
234 | irqreturn_t ret = IRQ_NONE; | ||
235 | __be32 sisr; | 207 | __be32 sisr; |
236 | __be32 sisr2; | 208 | __be32 sisr2; |
237 | __be32 sisr_write_mask = 0; | 209 | __be32 sisr_write_mask = 0; |
@@ -258,217 +230,18 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
258 | were interrupted for. We mask it with the Interrupt Enable register | 230 | were interrupted for. We mask it with the Interrupt Enable register |
259 | so that we only check for events that we're interested in. | 231 | so that we only check for events that we're interested in. |
260 | */ | 232 | */ |
261 | sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK; | 233 | sisr = read_ssi(&ssi->sisr); |
262 | |||
263 | if (sisr & CCSR_SSI_SISR_RFRC) { | ||
264 | ssi_private->stats.rfrc++; | ||
265 | ret = IRQ_HANDLED; | ||
266 | } | ||
267 | |||
268 | if (sisr & CCSR_SSI_SISR_TFRC) { | ||
269 | ssi_private->stats.tfrc++; | ||
270 | ret = IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | if (sisr & CCSR_SSI_SISR_CMDAU) { | ||
274 | ssi_private->stats.cmdau++; | ||
275 | ret = IRQ_HANDLED; | ||
276 | } | ||
277 | |||
278 | if (sisr & CCSR_SSI_SISR_CMDDU) { | ||
279 | ssi_private->stats.cmddu++; | ||
280 | ret = IRQ_HANDLED; | ||
281 | } | ||
282 | |||
283 | if (sisr & CCSR_SSI_SISR_RXT) { | ||
284 | ssi_private->stats.rxt++; | ||
285 | ret = IRQ_HANDLED; | ||
286 | } | ||
287 | |||
288 | if (sisr & CCSR_SSI_SISR_RDR1) { | ||
289 | ssi_private->stats.rdr1++; | ||
290 | ret = IRQ_HANDLED; | ||
291 | } | ||
292 | |||
293 | if (sisr & CCSR_SSI_SISR_RDR0) { | ||
294 | ssi_private->stats.rdr0++; | ||
295 | ret = IRQ_HANDLED; | ||
296 | } | ||
297 | |||
298 | if (sisr & CCSR_SSI_SISR_TDE1) { | ||
299 | ssi_private->stats.tde1++; | ||
300 | ret = IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | if (sisr & CCSR_SSI_SISR_TDE0) { | ||
304 | ssi_private->stats.tde0++; | ||
305 | ret = IRQ_HANDLED; | ||
306 | } | ||
307 | |||
308 | if (sisr & CCSR_SSI_SISR_ROE1) { | ||
309 | ssi_private->stats.roe1++; | ||
310 | ret = IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | if (sisr & CCSR_SSI_SISR_ROE0) { | ||
314 | ssi_private->stats.roe0++; | ||
315 | ret = IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | if (sisr & CCSR_SSI_SISR_TUE1) { | ||
319 | ssi_private->stats.tue1++; | ||
320 | ret = IRQ_HANDLED; | ||
321 | } | ||
322 | |||
323 | if (sisr & CCSR_SSI_SISR_TUE0) { | ||
324 | ssi_private->stats.tue0++; | ||
325 | ret = IRQ_HANDLED; | ||
326 | } | ||
327 | |||
328 | if (sisr & CCSR_SSI_SISR_TFS) { | ||
329 | ssi_private->stats.tfs++; | ||
330 | ret = IRQ_HANDLED; | ||
331 | } | ||
332 | |||
333 | if (sisr & CCSR_SSI_SISR_RFS) { | ||
334 | ssi_private->stats.rfs++; | ||
335 | ret = IRQ_HANDLED; | ||
336 | } | ||
337 | |||
338 | if (sisr & CCSR_SSI_SISR_TLS) { | ||
339 | ssi_private->stats.tls++; | ||
340 | ret = IRQ_HANDLED; | ||
341 | } | ||
342 | |||
343 | if (sisr & CCSR_SSI_SISR_RLS) { | ||
344 | ssi_private->stats.rls++; | ||
345 | ret = IRQ_HANDLED; | ||
346 | } | ||
347 | |||
348 | if (sisr & CCSR_SSI_SISR_RFF1) { | ||
349 | ssi_private->stats.rff1++; | ||
350 | ret = IRQ_HANDLED; | ||
351 | } | ||
352 | |||
353 | if (sisr & CCSR_SSI_SISR_RFF0) { | ||
354 | ssi_private->stats.rff0++; | ||
355 | ret = IRQ_HANDLED; | ||
356 | } | ||
357 | |||
358 | if (sisr & CCSR_SSI_SISR_TFE1) { | ||
359 | ssi_private->stats.tfe1++; | ||
360 | ret = IRQ_HANDLED; | ||
361 | } | ||
362 | |||
363 | if (sisr & CCSR_SSI_SISR_TFE0) { | ||
364 | ssi_private->stats.tfe0++; | ||
365 | ret = IRQ_HANDLED; | ||
366 | } | ||
367 | 234 | ||
368 | sisr2 = sisr & sisr_write_mask; | 235 | sisr2 = sisr & sisr_write_mask; |
369 | /* Clear the bits that we set */ | 236 | /* Clear the bits that we set */ |
370 | if (sisr2) | 237 | if (sisr2) |
371 | write_ssi(sisr2, &ssi->sisr); | 238 | write_ssi(sisr2, &ssi->sisr); |
372 | 239 | ||
373 | return ret; | 240 | fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr); |
374 | } | ||
375 | |||
376 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
377 | /* Show the statistics of a flag only if its interrupt is enabled. The | ||
378 | * compiler will optimze this code to a no-op if the interrupt is not | ||
379 | * enabled. | ||
380 | */ | ||
381 | #define SIER_SHOW(flag, name) \ | ||
382 | do { \ | ||
383 | if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \ | ||
384 | seq_printf(s, #name "=%u\n", ssi_private->stats.name); \ | ||
385 | } while (0) | ||
386 | |||
387 | |||
388 | /** | ||
389 | * fsl_sysfs_ssi_show: display SSI statistics | ||
390 | * | ||
391 | * Display the statistics for the current SSI device. To avoid confusion, | ||
392 | * we only show those counts that are enabled. | ||
393 | */ | ||
394 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | ||
395 | { | ||
396 | struct fsl_ssi_private *ssi_private = s->private; | ||
397 | |||
398 | SIER_SHOW(RFRC_EN, rfrc); | ||
399 | SIER_SHOW(TFRC_EN, tfrc); | ||
400 | SIER_SHOW(CMDAU_EN, cmdau); | ||
401 | SIER_SHOW(CMDDU_EN, cmddu); | ||
402 | SIER_SHOW(RXT_EN, rxt); | ||
403 | SIER_SHOW(RDR1_EN, rdr1); | ||
404 | SIER_SHOW(RDR0_EN, rdr0); | ||
405 | SIER_SHOW(TDE1_EN, tde1); | ||
406 | SIER_SHOW(TDE0_EN, tde0); | ||
407 | SIER_SHOW(ROE1_EN, roe1); | ||
408 | SIER_SHOW(ROE0_EN, roe0); | ||
409 | SIER_SHOW(TUE1_EN, tue1); | ||
410 | SIER_SHOW(TUE0_EN, tue0); | ||
411 | SIER_SHOW(TFS_EN, tfs); | ||
412 | SIER_SHOW(RFS_EN, rfs); | ||
413 | SIER_SHOW(TLS_EN, tls); | ||
414 | SIER_SHOW(RLS_EN, rls); | ||
415 | SIER_SHOW(RFF1_EN, rff1); | ||
416 | SIER_SHOW(RFF0_EN, rff0); | ||
417 | SIER_SHOW(TFE1_EN, tfe1); | ||
418 | SIER_SHOW(TFE0_EN, tfe0); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int fsl_ssi_stats_open(struct inode *inode, struct file *file) | ||
424 | { | ||
425 | return single_open(file, fsl_ssi_stats_show, inode->i_private); | ||
426 | } | ||
427 | |||
428 | static const struct file_operations fsl_ssi_stats_ops = { | ||
429 | .open = fsl_ssi_stats_open, | ||
430 | .read = seq_read, | ||
431 | .llseek = seq_lseek, | ||
432 | .release = single_release, | ||
433 | }; | ||
434 | |||
435 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
436 | struct device *dev) | ||
437 | { | ||
438 | ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); | ||
439 | if (!ssi_private->dbg_dir) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO, | ||
443 | ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops); | ||
444 | if (!ssi_private->dbg_stats) { | ||
445 | debugfs_remove(ssi_private->dbg_dir); | ||
446 | return -ENOMEM; | ||
447 | } | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | ||
453 | { | ||
454 | debugfs_remove(ssi_private->dbg_stats); | ||
455 | debugfs_remove(ssi_private->dbg_dir); | ||
456 | } | ||
457 | |||
458 | #else | ||
459 | |||
460 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
461 | struct device *dev) | ||
462 | { | ||
463 | return 0; | ||
464 | } | ||
465 | 241 | ||
466 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | 242 | return IRQ_HANDLED; |
467 | { | ||
468 | } | 243 | } |
469 | 244 | ||
470 | #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ | ||
471 | |||
472 | /* | 245 | /* |
473 | * Enable/Disable all rx/tx config flags at once. | 246 | * Enable/Disable all rx/tx config flags at once. |
474 | */ | 247 | */ |
@@ -1452,7 +1225,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1452 | goto error_dev; | 1225 | goto error_dev; |
1453 | } | 1226 | } |
1454 | 1227 | ||
1455 | ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev); | 1228 | ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); |
1456 | if (ret) | 1229 | if (ret) |
1457 | goto error_dbgfs; | 1230 | goto error_dbgfs; |
1458 | 1231 | ||
@@ -1522,7 +1295,7 @@ error_dai: | |||
1522 | imx_pcm_fiq_exit(pdev); | 1295 | imx_pcm_fiq_exit(pdev); |
1523 | 1296 | ||
1524 | error_pcm: | 1297 | error_pcm: |
1525 | fsl_ssi_debugfs_remove(ssi_private); | 1298 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1526 | 1299 | ||
1527 | error_dbgfs: | 1300 | error_dbgfs: |
1528 | snd_soc_unregister_component(&pdev->dev); | 1301 | snd_soc_unregister_component(&pdev->dev); |
@@ -1548,7 +1321,7 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1548 | { | 1321 | { |
1549 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); | 1322 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); |
1550 | 1323 | ||
1551 | fsl_ssi_debugfs_remove(ssi_private); | 1324 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1552 | 1325 | ||
1553 | if (!ssi_private->new_binding) | 1326 | if (!ssi_private->new_binding) |
1554 | platform_device_unregister(ssi_private->pdev); | 1327 | platform_device_unregister(ssi_private->pdev); |
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index e6b63240a3d7..2e95dd7a2105 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h | |||
@@ -206,5 +206,64 @@ struct ccsr_ssi { | |||
206 | #define CCSR_SSI_SACNT_FV 0x00000002 | 206 | #define CCSR_SSI_SACNT_FV 0x00000002 |
207 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 | 207 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 |
208 | 208 | ||
209 | #endif | ||
210 | 209 | ||
210 | struct device; | ||
211 | |||
212 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
213 | |||
214 | struct fsl_ssi_dbg { | ||
215 | struct dentry *dbg_dir; | ||
216 | struct dentry *dbg_stats; | ||
217 | |||
218 | struct { | ||
219 | unsigned int rfrc; | ||
220 | unsigned int tfrc; | ||
221 | unsigned int cmdau; | ||
222 | unsigned int cmddu; | ||
223 | unsigned int rxt; | ||
224 | unsigned int rdr1; | ||
225 | unsigned int rdr0; | ||
226 | unsigned int tde1; | ||
227 | unsigned int tde0; | ||
228 | unsigned int roe1; | ||
229 | unsigned int roe0; | ||
230 | unsigned int tue1; | ||
231 | unsigned int tue0; | ||
232 | unsigned int tfs; | ||
233 | unsigned int rfs; | ||
234 | unsigned int tls; | ||
235 | unsigned int rls; | ||
236 | unsigned int rff1; | ||
237 | unsigned int rff0; | ||
238 | unsigned int tfe1; | ||
239 | unsigned int tfe0; | ||
240 | } stats; | ||
241 | }; | ||
242 | |||
243 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *ssi_dbg, u32 sisr); | ||
244 | |||
245 | int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev); | ||
246 | |||
247 | void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg); | ||
248 | |||
249 | #else | ||
250 | |||
251 | struct fsl_ssi_dbg { | ||
252 | }; | ||
253 | |||
254 | static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr) | ||
255 | { | ||
256 | } | ||
257 | |||
258 | static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, | ||
259 | struct device *dev) | ||
260 | { | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static inline void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg) | ||
265 | { | ||
266 | } | ||
267 | #endif /* ! IS_ENABLED(CONFIG_DEBUG_FS) */ | ||
268 | |||
269 | #endif | ||
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c new file mode 100644 index 000000000000..5469ffbc0253 --- /dev/null +++ b/sound/soc/fsl/fsl_ssi_dbg.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Freescale SSI ALSA SoC Digital Audio Interface (DAI) debugging functions | ||
3 | * | ||
4 | * Copyright 2014 Markus Pargmann <mpa@pengutronix.de>, Pengutronix | ||
5 | * | ||
6 | * Splitted from fsl_ssi.c | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/debugfs.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/kernel.h> | ||
16 | |||
17 | #include "fsl_ssi.h" | ||
18 | |||
19 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) | ||
20 | { | ||
21 | if (sisr & CCSR_SSI_SISR_RFRC) | ||
22 | dbg->stats.rfrc++; | ||
23 | |||
24 | if (sisr & CCSR_SSI_SISR_TFRC) | ||
25 | dbg->stats.tfrc++; | ||
26 | |||
27 | if (sisr & CCSR_SSI_SISR_CMDAU) | ||
28 | dbg->stats.cmdau++; | ||
29 | |||
30 | if (sisr & CCSR_SSI_SISR_CMDDU) | ||
31 | dbg->stats.cmddu++; | ||
32 | |||
33 | if (sisr & CCSR_SSI_SISR_RXT) | ||
34 | dbg->stats.rxt++; | ||
35 | |||
36 | if (sisr & CCSR_SSI_SISR_RDR1) | ||
37 | dbg->stats.rdr1++; | ||
38 | |||
39 | if (sisr & CCSR_SSI_SISR_RDR0) | ||
40 | dbg->stats.rdr0++; | ||
41 | |||
42 | if (sisr & CCSR_SSI_SISR_TDE1) | ||
43 | dbg->stats.tde1++; | ||
44 | |||
45 | if (sisr & CCSR_SSI_SISR_TDE0) | ||
46 | dbg->stats.tde0++; | ||
47 | |||
48 | if (sisr & CCSR_SSI_SISR_ROE1) | ||
49 | dbg->stats.roe1++; | ||
50 | |||
51 | if (sisr & CCSR_SSI_SISR_ROE0) | ||
52 | dbg->stats.roe0++; | ||
53 | |||
54 | if (sisr & CCSR_SSI_SISR_TUE1) | ||
55 | dbg->stats.tue1++; | ||
56 | |||
57 | if (sisr & CCSR_SSI_SISR_TUE0) | ||
58 | dbg->stats.tue0++; | ||
59 | |||
60 | if (sisr & CCSR_SSI_SISR_TFS) | ||
61 | dbg->stats.tfs++; | ||
62 | |||
63 | if (sisr & CCSR_SSI_SISR_RFS) | ||
64 | dbg->stats.rfs++; | ||
65 | |||
66 | if (sisr & CCSR_SSI_SISR_TLS) | ||
67 | dbg->stats.tls++; | ||
68 | |||
69 | if (sisr & CCSR_SSI_SISR_RLS) | ||
70 | dbg->stats.rls++; | ||
71 | |||
72 | if (sisr & CCSR_SSI_SISR_RFF1) | ||
73 | dbg->stats.rff1++; | ||
74 | |||
75 | if (sisr & CCSR_SSI_SISR_RFF0) | ||
76 | dbg->stats.rff0++; | ||
77 | |||
78 | if (sisr & CCSR_SSI_SISR_TFE1) | ||
79 | dbg->stats.tfe1++; | ||
80 | |||
81 | if (sisr & CCSR_SSI_SISR_TFE0) | ||
82 | dbg->stats.tfe0++; | ||
83 | } | ||
84 | |||
85 | /* Show the statistics of a flag only if its interrupt is enabled. The | ||
86 | * compiler will optimze this code to a no-op if the interrupt is not | ||
87 | * enabled. | ||
88 | */ | ||
89 | #define SIER_SHOW(flag, name) \ | ||
90 | do { \ | ||
91 | if (CCSR_SSI_SIER_##flag) \ | ||
92 | seq_printf(s, #name "=%u\n", ssi_dbg->stats.name); \ | ||
93 | } while (0) | ||
94 | |||
95 | |||
96 | /** | ||
97 | * fsl_sysfs_ssi_show: display SSI statistics | ||
98 | * | ||
99 | * Display the statistics for the current SSI device. To avoid confusion, | ||
100 | * we only show those counts that are enabled. | ||
101 | */ | ||
102 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | ||
103 | { | ||
104 | struct fsl_ssi_dbg *ssi_dbg = s->private; | ||
105 | |||
106 | SIER_SHOW(RFRC_EN, rfrc); | ||
107 | SIER_SHOW(TFRC_EN, tfrc); | ||
108 | SIER_SHOW(CMDAU_EN, cmdau); | ||
109 | SIER_SHOW(CMDDU_EN, cmddu); | ||
110 | SIER_SHOW(RXT_EN, rxt); | ||
111 | SIER_SHOW(RDR1_EN, rdr1); | ||
112 | SIER_SHOW(RDR0_EN, rdr0); | ||
113 | SIER_SHOW(TDE1_EN, tde1); | ||
114 | SIER_SHOW(TDE0_EN, tde0); | ||
115 | SIER_SHOW(ROE1_EN, roe1); | ||
116 | SIER_SHOW(ROE0_EN, roe0); | ||
117 | SIER_SHOW(TUE1_EN, tue1); | ||
118 | SIER_SHOW(TUE0_EN, tue0); | ||
119 | SIER_SHOW(TFS_EN, tfs); | ||
120 | SIER_SHOW(RFS_EN, rfs); | ||
121 | SIER_SHOW(TLS_EN, tls); | ||
122 | SIER_SHOW(RLS_EN, rls); | ||
123 | SIER_SHOW(RFF1_EN, rff1); | ||
124 | SIER_SHOW(RFF0_EN, rff0); | ||
125 | SIER_SHOW(TFE1_EN, tfe1); | ||
126 | SIER_SHOW(TFE0_EN, tfe0); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int fsl_ssi_stats_open(struct inode *inode, struct file *file) | ||
132 | { | ||
133 | return single_open(file, fsl_ssi_stats_show, inode->i_private); | ||
134 | } | ||
135 | |||
136 | static const struct file_operations fsl_ssi_stats_ops = { | ||
137 | .open = fsl_ssi_stats_open, | ||
138 | .read = seq_read, | ||
139 | .llseek = seq_lseek, | ||
140 | .release = single_release, | ||
141 | }; | ||
142 | |||
143 | int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev) | ||
144 | { | ||
145 | ssi_dbg->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); | ||
146 | if (!ssi_dbg->dbg_dir) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO, | ||
150 | ssi_dbg->dbg_dir, ssi_dbg, &fsl_ssi_stats_ops); | ||
151 | if (!ssi_dbg->dbg_stats) { | ||
152 | debugfs_remove(ssi_dbg->dbg_dir); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg) | ||
160 | { | ||
161 | debugfs_remove(ssi_dbg->dbg_stats); | ||
162 | debugfs_remove(ssi_dbg->dbg_dir); | ||
163 | } | ||