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 | } | ||
