Merge branch 'for-2.6.34' of git://opensource.wolfsonmicro.com/linux-2.6-asoc into topic/asoc

+30 -10
+30 -10
sound/soc/imx/imx-pcm-fiq.c
··· 35 35 struct imx_pcm_runtime_data { 36 36 int period; 37 37 int periods; 38 - unsigned long dma_addr; 39 - int dma; 40 38 unsigned long offset; 39 + unsigned long last_offset; 41 40 unsigned long size; 42 - unsigned long period_cnt; 43 - void *buf; 44 41 struct timer_list timer; 45 - int period_time; 42 + int poll_time; 46 43 }; 44 + 45 + static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) 46 + { 47 + iprtd->timer.expires = jiffies + iprtd->poll_time; 48 + } 47 49 48 50 static void imx_ssi_timer_callback(unsigned long data) 49 51 { ··· 53 51 struct snd_pcm_runtime *runtime = substream->runtime; 54 52 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 55 53 struct pt_regs regs; 54 + unsigned long delta; 56 55 57 56 get_fiq_regs(&regs); 58 57 ··· 62 59 else 63 60 iprtd->offset = regs.ARM_r9 & 0xffff; 64 61 65 - iprtd->timer.expires = jiffies + iprtd->period_time; 62 + /* How much data have we transferred since the last period report? */ 63 + if (iprtd->offset >= iprtd->last_offset) 64 + delta = iprtd->offset - iprtd->last_offset; 65 + else 66 + delta = runtime->buffer_size + iprtd->offset 67 + - iprtd->last_offset; 68 + 69 + /* If we've transferred at least a period then report it and 70 + * reset our poll time */ 71 + if (delta >= runtime->period_size) { 72 + snd_pcm_period_elapsed(substream); 73 + iprtd->last_offset = iprtd->offset; 74 + 75 + imx_ssi_set_next_poll(iprtd); 76 + } 77 + 78 + /* Restart the timer; if we didn't report we'll run on the next tick */ 66 79 add_timer(&iprtd->timer); 67 - snd_pcm_period_elapsed(substream); 80 + 68 81 } 69 82 70 83 static struct fiq_handler fh = { ··· 95 76 96 77 iprtd->size = params_buffer_bytes(params); 97 78 iprtd->periods = params_periods(params); 98 - iprtd->period = params_period_bytes(params); 79 + iprtd->period = params_period_bytes(params) ; 99 80 iprtd->offset = 0; 100 - iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); 81 + iprtd->last_offset = 0; 82 + iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); 101 83 102 84 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 103 85 ··· 134 114 case SNDRV_PCM_TRIGGER_START: 135 115 case SNDRV_PCM_TRIGGER_RESUME: 136 116 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 137 - iprtd->timer.expires = jiffies + iprtd->period_time; 117 + imx_ssi_set_next_poll(iprtd); 138 118 add_timer(&iprtd->timer); 139 119 if (++fiq_enable == 1) 140 120 enable_fiq(imx_pcm_fiq);