#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/stddef.h>
-
+#include <linux/spinlock.h>
#include "sound_config.h"
#define DEBUGNOISE(x)
in ad1816_info */
int irq_ok;
int *osp;
-
+ spinlock_t lock;
} ad1816_info;
static int nr_ad1816_devs;
CHECK_FOR_POWER;
- save_flags (flags); /* make register access atomic */
- cli ();
+ spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
outb ((unsigned char) (reg & 0x3f), devc->base+0);
result = inb(devc->base+2);
result+= inb(devc->base+3)<<8;
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
return (result);
}
CHECK_FOR_POWER;
- save_flags (flags); /* make register access atomic */
- cli ();
+ spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
outb ((unsigned char) (reg & 0xff), devc->base+0);
outb ((unsigned char) (data & 0xff),devc->base+2);
outb ((unsigned char) ((data>>8)&0xff),devc->base+3);
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
DEBUGINFO (printk("ad1816: halt_input called\n"));
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
if(!isa_dma_bridge_buggy) {
disable_dma(audio_devs[dev]->dmap_in->dma);
outb (~0x40, devc->base+1);
devc->audio_mode &= ~PCM_ENABLE_INPUT;
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1816_halt_output (int dev)
DEBUGINFO (printk("ad1816: halt_output called!\n"));
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
/* Mute pcm output */
ad_write(devc, 4, ad_read(devc,4)|0x8080);
outb ((unsigned char)~0x80, devc->base+1);
devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
static void ad1816_output_block (int dev, unsigned long buf,
cnt = count/4 - 1;
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
/* set transfer count */
ad_write (devc, 8, cnt & 0xffff);
devc->audio_mode |= PCM_ENABLE_OUTPUT;
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
cnt = count/4 - 1;
- save_flags (flags); /* make register access atomic */
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
/* set transfer count */
ad_write (devc, 10, cnt & 0xffff);
devc->audio_mode |= PCM_ENABLE_INPUT;
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
DEBUGINFO (printk ("ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
fmt_bits= (devc->format_bits&0x7)<<3;
ad_write (devc, 2, freq & 0xffff);
ad_write (devc, 3, freq & 0xffff);
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_input(dev);
return 0;
DEBUGINFO (printk ("ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
- save_flags (flags); /* make register access atomic */
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
fmt_bits= (devc->format_bits&0x7)<<3;
/* set mono/stereo mode */
ad_write (devc, 2, freq & 0xffff);
ad_write (devc, 3, freq & 0xffff);
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
ad1816_halt_output(dev);
return 0;
/* mode may have changed */
- save_flags (flags); /* make register access atomic */
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
/* mask out modes not specified on open call */
state &= devc->audio_mode;
/* disable capture */
outb(inb(devc->base+8)&~0x01, devc->base+8);
}
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
devc = (ad1816_info *) audio_devs[dev]->devc;
/* make check if device already open atomic */
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
if (devc->opened) {
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
return -(EBUSY);
}
devc->channels=1;
ad1816_reset(devc->dev_no); /* halt all pending output */
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
return 0;
}
unsigned long flags;
ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
- save_flags (flags);
- cli ();
+ spin_lock_irqsave(&devc->lock,flags);
/* halt all pending output */
ad1816_reset(devc->dev_no);
devc->audio_format=AFMT_U8;
devc->format_bits = 0;
-
- restore_flags (flags);
+ spin_unlock_irqrestore(&devc->lock,flags);
}
unsigned char status;
ad1816_info *devc;
int dev;
- unsigned long flags;
if (irq < 0 || irq > 15) {
devc = (ad1816_info *) audio_devs[dev]->devc;
- save_flags(flags);
- cli();
+ spin_lock(&devc->lock);
/* read interrupt register */
status = inb (devc->base+1);
if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128))
DMAbuf_outputintr (dev, 1);
- restore_flags(flags);
+ spin_unlock(&devc->lock);
}
/* ------------------------------------------------------------------- */
devc->irq = 0;
devc->opened = 0;
devc->osp = osp;
+ spin_lock_init(&devc->lock);
/* base+0: bit 1 must be set but not 255 */
tmp=inb(devc->base);