runtime->private_data = NULL;
 }
 
-static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id)
+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream)
 {
-       struct bcm2835_alsa_stream *alsa_stream = dev_id;
        unsigned int consumed = 0;
        int new_period = 0;
 
                audio_warning(" unexpected NULL substream\n");
        }
        audio_info(" .. OUT\n");
-
-       return IRQ_HANDLED;
 }
 
 /* open callback */
        sema_init(&alsa_stream->control_sem, 0);
        spin_lock_init(&alsa_stream->lock);
 
-       /* Enabled in start trigger, called on each "fifo irq" after that */
-       alsa_stream->enable_fifo_irq = 0;
-       alsa_stream->fifo_irq_handler = bcm2835_playback_fifo_irq;
-
        err = bcm2835_audio_open(alsa_stream);
        if (err) {
                kfree(alsa_stream);
 
                              size);
 }
 
+static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 ||
+                                               'M' << 8  | 'A');
+static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 ||
+                                               'T' << 8  | 'A');
+
 struct bcm2835_audio_work {
        struct work_struct my_work;
        struct bcm2835_alsa_stream *alsa_stream;
                complete(&instance->msg_avail_comp);
        } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
                struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream;
-#if defined(CONFIG_64BIT)
-               irq_handler_t callback =
-                       (irq_handler_t) (((unsigned long) m.u.complete.callbackl) |
-                       ((unsigned long) m.u.complete.callbackh << 32));
-#else
-               irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
-#endif
                LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n",
                        instance, m.u.complete.count);
-               if (alsa_stream && callback) {
-                       atomic_add(m.u.complete.count, &alsa_stream->retrieved);
-                       callback(0, alsa_stream);
+               if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 ||
+                   m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2)
+                       LOG_ERR(" .. response is corrupt\n");
+               else if (alsa_stream) {
+                       atomic_add(m.u.complete.count,
+                                  &alsa_stream->retrieved);
+                       bcm2835_playback_fifo(alsa_stream);
                } else {
-                       LOG_ERR(" .. unexpected alsa_stream=%p, callback=%p\n",
-                               alsa_stream, callback);
+                       LOG_ERR(" .. unexpected alsa_stream=%p\n",
+                               alsa_stream);
                }
        } else {
                LOG_ERR(" .. unexpected m.type=%d\n", m.type);
        m.u.write.count = count;
        // old version uses bulk, new version uses control
        m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000;
-#if defined(CONFIG_64BIT)
-       m.u.write.callbackl = (u32) (((unsigned long) alsa_stream->fifo_irq_handler)&0xFFFFFFFF);
-       m.u.write.callbackh = (u32) ((((unsigned long) alsa_stream->fifo_irq_handler) >> 32)&0xFFFFFFFF);
-#else
-       m.u.write.callback = alsa_stream->fifo_irq_handler;
-       m.u.write.cookie = alsa_stream;
-#endif
+       m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1;
+       m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2;
        m.u.write.silence = src == NULL;
 
        /* Send the message to the videocore */
 
        unsigned int buffer_size;
        unsigned int period_size;
 
-       unsigned int enable_fifo_irq;
-       irq_handler_t fifo_irq_handler;
-
        atomic_t retrieved;
        struct bcm2835_audio_instance *instance;
        struct workqueue_struct *my_wq;
 int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
                        unsigned int count,
                        void *src);
+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream);
 unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream);
 void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream);
 void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream);