···3535struct imx_pcm_runtime_data {3636 int period;3737 int periods;3838- unsigned long dma_addr;3939- int dma;4038 unsigned long offset;3939+ unsigned long last_offset;4140 unsigned long size;4242- unsigned long period_cnt;4343- void *buf;4441 struct timer_list timer;4545- int period_time;4242+ int poll_time;4643};4444+4545+static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)4646+{4747+ iprtd->timer.expires = jiffies + iprtd->poll_time;4848+}47494850static void imx_ssi_timer_callback(unsigned long data)4951{···5351 struct snd_pcm_runtime *runtime = substream->runtime;5452 struct imx_pcm_runtime_data *iprtd = runtime->private_data;5553 struct pt_regs regs;5454+ unsigned long delta;56555756 get_fiq_regs(®s);5857···6259 else6360 iprtd->offset = regs.ARM_r9 & 0xffff;64616565- iprtd->timer.expires = jiffies + iprtd->period_time;6262+ /* How much data have we transferred since the last period report? */6363+ if (iprtd->offset >= iprtd->last_offset)6464+ delta = iprtd->offset - iprtd->last_offset;6565+ else6666+ delta = runtime->buffer_size + iprtd->offset6767+ - iprtd->last_offset;6868+6969+ /* If we've transferred at least a period then report it and7070+ * reset our poll time */7171+ if (delta >= runtime->period_size) {7272+ snd_pcm_period_elapsed(substream);7373+ iprtd->last_offset = iprtd->offset;7474+7575+ imx_ssi_set_next_poll(iprtd);7676+ }7777+7878+ /* Restart the timer; if we didn't report we'll run on the next tick */6679 add_timer(&iprtd->timer);6767- snd_pcm_period_elapsed(substream);8080+6881}69827083static struct fiq_handler fh = {···95769677 iprtd->size = params_buffer_bytes(params);9778 iprtd->periods = params_periods(params);9898- iprtd->period = params_period_bytes(params);7979+ iprtd->period = params_period_bytes(params) ;9980 iprtd->offset = 0;100100- iprtd->period_time = HZ / (params_rate(params) / params_period_size(params));8181+ iprtd->last_offset = 0;8282+ iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));1018310284 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);10385···134114 case SNDRV_PCM_TRIGGER_START:135115 case SNDRV_PCM_TRIGGER_RESUME:136116 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:137137- iprtd->timer.expires = jiffies + iprtd->period_time;117117+ imx_ssi_set_next_poll(iprtd);138118 add_timer(&iprtd->timer);139119 if (++fiq_enable == 1)140120 enable_fiq(imx_pcm_fiq);