Merge tag 'sound-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[sfrench/cifs-2.6.git] / sound / pcmcia / pdaudiocf / pdaudiocf_irq.c
index dcd32201bc8c5cf4dfec40b0deba7edfaafe91ea..ecf0fbd9179467ed05a819dd99512862f842d100 100644 (file)
@@ -30,6 +30,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev)
 {
        struct snd_pdacf *chip = dev;
        unsigned short stat;
+       bool wake_thread = false;
 
        if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|
                                  PDAUDIOCF_STAT_IS_CONFIGURED|
@@ -41,13 +42,13 @@ irqreturn_t pdacf_interrupt(int irq, void *dev)
                if (stat & PDAUDIOCF_IRQOVR)    /* should never happen */
                        snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n");
                if (chip->pcm_substream)
-                       tasklet_schedule(&chip->tq);
+                       wake_thread = true;
                if (!(stat & PDAUDIOCF_IRQAKM))
                        stat |= PDAUDIOCF_IRQAKM;       /* check rate */
        }
        if (get_irq_regs() != NULL)
                snd_ak4117_check_rate_and_errors(chip->ak4117, 0);
-       return IRQ_HANDLED;
+       return wake_thread ? IRQ_WAKE_THREAD : IRQ_HANDLED;
 }
 
 static inline void pdacf_transfer_mono16(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
@@ -256,16 +257,16 @@ static void pdacf_transfer(struct snd_pdacf *chip, unsigned int size, unsigned i
        }
 }
 
-void pdacf_tasklet(unsigned long private_data)
+irqreturn_t pdacf_threaded_irq(int irq, void *dev)
 {
-       struct snd_pdacf *chip = (struct snd_pdacf *) private_data;
+       struct snd_pdacf *chip = dev;
        int size, off, cont, rdp, wdp;
 
        if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|PDAUDIOCF_STAT_IS_CONFIGURED)) != PDAUDIOCF_STAT_IS_CONFIGURED)
-               return;
+               return IRQ_HANDLED;
        
        if (chip->pcm_substream == NULL || chip->pcm_substream->runtime == NULL || !snd_pcm_running(chip->pcm_substream))
-               return;
+               return IRQ_HANDLED;
 
        rdp = inw(chip->port + PDAUDIOCF_REG_RDP);
        wdp = inw(chip->port + PDAUDIOCF_REG_WDP);
@@ -311,15 +312,15 @@ void pdacf_tasklet(unsigned long private_data)
                size -= cont;
        }
 #endif
-       spin_lock(&chip->reg_lock);
+       mutex_lock(&chip->reg_lock);
        while (chip->pcm_tdone >= chip->pcm_period) {
                chip->pcm_hwptr += chip->pcm_period;
                chip->pcm_hwptr %= chip->pcm_size;
                chip->pcm_tdone -= chip->pcm_period;
-               spin_unlock(&chip->reg_lock);
+               mutex_unlock(&chip->reg_lock);
                snd_pcm_period_elapsed(chip->pcm_substream);
-               spin_lock(&chip->reg_lock);
+               mutex_lock(&chip->reg_lock);
        }
-       spin_unlock(&chip->reg_lock);
-       /* printk(KERN_DEBUG "TASKLET: end\n"); */
+       mutex_unlock(&chip->reg_lock);
+       return IRQ_HANDLED;
 }