From 49c9a88333e015b3494de923f84db6d9e61077a6 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Mon, 4 Oct 2010 12:10:29 -0700 Subject: [PATCH] [ARM] tegra_i2s_audio: add more elaborate error counts This patch replaces the error counter with two separate error counters, one for late dma callbacks, and another for overruns (during recording) or underruns (during playback). The ioctls TEGRA_AUDIO_IN_GET_ERROR_COUNT and TEGRA_AUDIO_OUT_GET_ERROR_COUNT now take a pointer to a struct containing both error counters. Signed-off-by: Iliyan Malchev --- arch/arm/mach-tegra/tegra_i2s_audio.c | 18 +++++++++--------- include/linux/tegra_audio.h | 9 +++++++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-tegra/tegra_i2s_audio.c b/arch/arm/mach-tegra/tegra_i2s_audio.c index 4cbcf9897095..b1344fc67ddc 100644 --- a/arch/arm/mach-tegra/tegra_i2s_audio.c +++ b/arch/arm/mach-tegra/tegra_i2s_audio.c @@ -72,7 +72,7 @@ struct audio_stream { struct completion fifo_completion; struct scatterlist sg; - unsigned errors; + struct tegra_audio_error_counts errors; int i2s_fifo_atn_level; @@ -559,7 +559,7 @@ static bool stop_playback_if_necessary(struct audio_stream *aos) if (kfifo_is_empty(&aos->fifo)) { sound_ops->stop_playback(aos); if (aos->active) - aos->errors++; + aos->errors.full_empty++; /* underflow */ spin_unlock_irqrestore(&aos->dma_req_lock, flags); pm_qos_update_request(aos->pm_qos, PM_QOS_DEFAULT_VALUE); return true; @@ -575,7 +575,7 @@ static bool stop_recording_if_necessary_nosync(struct audio_stream *ais) if (ads->recording_cancelled || kfifo_is_full(&ais->fifo)) { if (kfifo_is_full(&ais->fifo)) - ais->errors++; + ais->errors.full_empty++; /* overflow */ sound_ops->stop_recording(ais); return true; } @@ -697,7 +697,7 @@ static void dma_tx_complete_callback(struct tegra_dma_req *req) if (delta_us > max_delay_us) { pr_debug("%s: too late by %lld us\n", __func__, delta_us - max_delay_us); - aos->errors++; + aos->errors.late_dma++; } kfifo_dma_out_finish(&aos->fifo, count); @@ -1074,7 +1074,7 @@ static irqreturn_t i2s_interrupt(int irq, void *data) if (status & I2S_I2S_FIFO_RX_ERR) { ads->pio_stats.rx_fifo_errors++; - ads->in.errors++; + ads->in.errors.full_empty++; } if (status & I2S_FIFO_ERR) @@ -1283,7 +1283,7 @@ static long tegra_audio_out_ioctl(struct file *file, sizeof(aos->errors))) rc = -EFAULT; if (!rc) - aos->errors = 0; + memset(&aos->errors, 0, sizeof(aos->errors)); break; case TEGRA_AUDIO_OUT_PRELOAD_FIFO: { struct tegra_audio_out_preload preload; @@ -1422,7 +1422,7 @@ static long tegra_audio_in_ioctl(struct file *file, sizeof(ais->errors))) rc = -EFAULT; if (!rc) - ais->errors = 0; + memset(&ais->errors, 0, sizeof(ais->errors)); break; default: rc = -EINVAL; @@ -1698,7 +1698,7 @@ static int tegra_audio_out_open(struct inode *inode, struct file *file) mutex_lock(&ads->out.lock); if (!ads->out.opened++) { pr_info("%s: resetting fifo and error count\n", __func__); - ads->out.errors = 0; + memset(&ads->out.errors, 0, sizeof(ads->out.errors)); kfifo_reset(&ads->out.fifo); } mutex_unlock(&ads->out.lock); @@ -1735,7 +1735,7 @@ static int tegra_audio_in_open(struct inode *inode, struct file *file) * input device. */ ads->recording_cancelled = false; - ads->in.errors = 0; + memset(&ads->in.errors, 0, sizeof(ads->in.errors)); kfifo_reset(&ads->in.fifo); } mutex_unlock(&ads->in.lock); diff --git a/include/linux/tegra_audio.h b/include/linux/tegra_audio.h index 15139cc31d84..07192b28a936 100644 --- a/include/linux/tegra_audio.h +++ b/include/linux/tegra_audio.h @@ -52,11 +52,16 @@ struct tegra_audio_buf_config { #define TEGRA_AUDIO_OUT_GET_BUF_CONFIG _IOR(TEGRA_AUDIO_MAGIC, 7, \ struct tegra_audio_buf_config *) +struct tegra_audio_error_counts { + unsigned late_dma; + unsigned full_empty; /* empty for playback, full for recording */ +}; + #define TEGRA_AUDIO_IN_GET_ERROR_COUNT _IOR(TEGRA_AUDIO_MAGIC, 8, \ - unsigned *) + struct tegra_audio_error_counts *) #define TEGRA_AUDIO_OUT_GET_ERROR_COUNT _IOR(TEGRA_AUDIO_MAGIC, 9, \ - unsigned *) + struct tegra_audio_error_counts *) struct tegra_audio_out_preload { void *data; -- 2.34.1