fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ppc / 8xx_io / cs4218_tdm.c
index 99dfab8..b7bb5f0 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/major.h>
-#include <linux/config.h>
 #include <linux/fcntl.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -55,6 +54,8 @@ static int irq_installed = 0;
 static char **sound_buffers = NULL;
 static char **sound_read_buffers = NULL;
 
+static DEFINE_SPINLOCK(cs4218_lock);
+
 /* Local copies of things we put in the control register.  Output
  * volume, like most codecs is really attenuation.
  */
@@ -124,11 +125,11 @@ static int numReadBufs = 4, readbufSize = 32;
 */
 static volatile cbd_t  *rx_base, *rx_cur, *tx_base, *tx_cur;
 
-MODULE_PARM(catchRadius, "i");
-MODULE_PARM(numBufs, "i");
-MODULE_PARM(bufSize, "i");
-MODULE_PARM(numreadBufs, "i");
-MODULE_PARM(readbufSize, "i");
+module_param(catchRadius, int, 0);
+module_param(numBufs, int, 0);
+module_param(bufSize, int, 0);
+module_param(numreadBufs, int, 0);
+module_param(readbufSize, int, 0);
 
 #define arraysize(x)   (sizeof(x)/sizeof(*(x)))
 #define le2be16(x)     (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
@@ -316,7 +317,7 @@ struct cs_sound_settings {
 
 static struct cs_sound_settings sound;
 
-static void *CS_Alloc(unsigned int size, int flags);
+static void *CS_Alloc(unsigned int size, gfp_t flags);
 static void CS_Free(void *ptr, unsigned int size);
 static int CS_IrqInit(void);
 #ifdef MODULE
@@ -330,7 +331,7 @@ static int CS_SetFormat(int format);
 static int CS_SetVolume(int volume);
 static void cs4218_tdm_tx_intr(void *devid);
 static void cs4218_tdm_rx_intr(void *devid);
-static void cs4218_intr(void *devid, struct pt_regs *regs);
+static void cs4218_intr(void *devid);
 static int cs_get_volume(uint reg);
 static int cs_volume_setter(int volume, int mute);
 static int cs_get_gain(uint reg);
@@ -957,7 +958,7 @@ static TRANS transCSNormalRead = {
 
 /*** Low level stuff *********************************************************/
 
-static void *CS_Alloc(unsigned int size, int flags)
+static void *CS_Alloc(unsigned int size, gfp_t flags)
 {
        int     order;
 
@@ -1011,8 +1012,7 @@ static void CS_IrqCleanup(void)
        */
        cpm_free_handler(CPMVEC_SMC2);
 
-       if (beep_buf)
-               kfree(beep_buf);
+       kfree(beep_buf);
        kd_mksound = orig_mksound;
 }
 #endif /* MODULE */
@@ -1206,7 +1206,8 @@ static void CS_Play(void)
        volatile cbd_t  *bdp;
        volatile cpm8xx_t *cp;
 
-       save_flags(flags); cli();
+       /* Protect buffer */
+       spin_lock_irqsave(&cs4218_lock, flags);
 #if 0
        if (awacs_beep_state) {
                /* sound takes precedence over beeps */
@@ -1263,7 +1264,7 @@ static void CS_Play(void)
 
                ++sq.active;
        }
-       restore_flags(flags);
+       spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
 
@@ -1275,7 +1276,8 @@ static void CS_Record(void)
        if (read_sq.active)
                return;
 
-       save_flags(flags); cli();
+       /* Protect buffer */
+       spin_lock_irqsave(&cs4218_lock, flags);
 
        /* This is all we have to do......Just start it up.
        */
@@ -1284,7 +1286,7 @@ static void CS_Record(void)
 
        read_sq.active = 1;
 
-        restore_flags(flags);
+        spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
 
@@ -1365,17 +1367,18 @@ static void cs_nosound(unsigned long xx)
 {
        unsigned long flags;
 
-       save_flags(flags); cli();
+       /* not sure if this is needed, since hardware command is #if 0'd */
+       spin_lock_irqsave(&cs4218_lock, flags);
        if (beep_playing) {
 #if 0
                st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
 #endif
                beep_playing = 0;
        }
-       restore_flags(flags);
+       spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
-static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0);
+static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
 };
 
 static void cs_mksound(unsigned int hz, unsigned int ticks)
@@ -1401,21 +1404,22 @@ static void cs_mksound(unsigned int hz, unsigned int ticks)
                return;
 #endif
        }
-       save_flags(flags); cli();
+       /* lock while modifying beep_timer */
+       spin_lock_irqsave(&cs4218_lock, flags);
        del_timer(&beep_timer);
        if (ticks) {
                beep_timer.expires = jiffies + ticks;
                add_timer(&beep_timer);
        }
        if (beep_playing || sq.active || beep_buf == NULL) {
-               restore_flags(flags);
+               spin_unlock_irqrestore(&cs4218_lock, flags);
                return;         /* too hard, sorry :-( */
        }
        beep_playing = 1;
 #if 0
        st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
 #endif
-       restore_flags(flags);
+       spin_unlock_irqrestore(&cs4218_lock, flags);
 
        if (hz == beep_hz_cache && beep_volume == beep_volume_cache) {
                nsamples = beep_nsamples_cache;
@@ -1442,7 +1446,7 @@ static void cs_mksound(unsigned int hz, unsigned int ticks)
        st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
        awacs_beep_state = 1;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&cs4218_lock, flags);
        if (beep_playing) {     /* i.e. haven't been terminated already */
                out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
                out_le32(&awacs->control,
@@ -1452,8 +1456,8 @@ static void cs_mksound(unsigned int hz, unsigned int ticks)
                out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
                out_le32(&awacs_txdma->control, RUN | (RUN << 16));
        }
+       spin_unlock_irqrestore(&cs4218_lock, flags);
 #endif
-       restore_flags(flags);
 }
 
 static MACHINE mach_cs4218 = {
@@ -1619,7 +1623,7 @@ static ssize_t sound_copy_translate_read(const u_char *userPtr,
 static int mixer_open(struct inode *inode, struct file *file)
 {
        mixer.busy = 1;
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 
@@ -2105,7 +2109,7 @@ static int sq_open(struct inode *inode, struct file *file)
                sound_set_format(AFMT_MU_LAW);
        }
 
-       return 0;
+       return nonseekable_open(inode, file);
 
 err_out_nobusy:
        if (file->f_mode & FMODE_WRITE) {
@@ -2161,7 +2165,7 @@ static int sq_release(struct inode *inode, struct file *file)
        int rc = 0;
 
        if (sq.busy)
-               rc = sq_fsync(file, file->f_dentry);
+               rc = sq_fsync(file, file->f_path.dentry);
        sound.soft = sound.dsp;
        sound.hard = sound.dsp;
        sound_silence();
@@ -2214,25 +2218,25 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
                return 0;
        case SNDCTL_DSP_POST:
        case SNDCTL_DSP_SYNC:
-               return sq_fsync(file, file->f_dentry);
+               return sq_fsync(file, file->f_path.dentry);
 
                /* ++TeSche: before changing any of these it's
                 * probably wise to wait until sound playing has
                 * settled down. */
        case SNDCTL_DSP_SPEED:
-               sq_fsync(file, file->f_dentry);
+               sq_fsync(file, file->f_path.dentry);
                IOCTL_IN(arg, data);
                return IOCTL_OUT(arg, sound_set_speed(data));
        case SNDCTL_DSP_STEREO:
-               sq_fsync(file, file->f_dentry);
+               sq_fsync(file, file->f_path.dentry);
                IOCTL_IN(arg, data);
                return IOCTL_OUT(arg, sound_set_stereo(data));
        case SOUND_PCM_WRITE_CHANNELS:
-               sq_fsync(file, file->f_dentry);
+               sq_fsync(file, file->f_path.dentry);
                IOCTL_IN(arg, data);
                return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
        case SNDCTL_DSP_SETFMT:
-               sq_fsync(file, file->f_dentry);
+               sq_fsync(file, file->f_path.dentry);
                IOCTL_IN(arg, data);
                return IOCTL_OUT(arg, sound_set_format(data));
        case SNDCTL_DSP_GETFMTS:
@@ -2404,7 +2408,7 @@ static int state_open(struct inode *inode, struct file *file)
        len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
                       sq.active, sq.syncing);
        state.len = len;
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 
@@ -2463,7 +2467,7 @@ static long long sound_lseek(struct file *file, long long offset, int orig)
 int __init tdm8xx_sound_init(void)
 {
        int i, has_sound;
-       uint                    dp_addr;
+       uint                    dp_offset;
        volatile uint           *sirp;
        volatile cbd_t          *bdp;
        volatile cpm8xx_t       *cp;
@@ -2525,14 +2529,14 @@ int __init tdm8xx_sound_init(void)
        /* We need to allocate a transmit and receive buffer
         * descriptors from dual port ram.
         */
-       dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs);
+       dp_addr = cpm_dpalloc(sizeof(cbd_t) * numReadBufs, 8);
 
        /* Set the physical address of the host memory
         * buffers in the buffer descriptors, and the
         * virtual address for us to work with.
         */
        bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
-       up->smc_rbase = dp_addr;
+       up->smc_rbase = dp_offset;
        rx_cur = rx_base = (cbd_t *)bdp;
 
        for (i=0; i<(numReadBufs-1); i++) {
@@ -2547,10 +2551,10 @@ int __init tdm8xx_sound_init(void)
 
        /* Now, do the same for the transmit buffers.
        */
-       dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs);
+       dp_offset = cpm_dpalloc(sizeof(cbd_t) * numBufs, 8);
 
        bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
-       up->smc_tbase = dp_addr;
+       up->smc_tbase = dp_offset;
        tx_cur = tx_base = (cbd_t *)bdp;
 
        for (i=0; i<(numBufs-1); i++) {
@@ -2597,7 +2601,7 @@ int __init tdm8xx_sound_init(void)
        /* Initialize beep stuff */
        orig_mksound = kd_mksound;
        kd_mksound = cs_mksound;
-       beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
+       beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
        if (beep_buf == NULL)
                printk(KERN_WARNING "dmasound: no memory for "
                       "beep buffer\n");
@@ -2642,7 +2646,7 @@ int __init tdm8xx_sound_init(void)
  * full duplex operation.
  */
 static void
-cs4218_intr(void *dev_id, struct pt_regs *regs)
+cs4218_intr(void *dev_id)
 {
        volatile smc_t  *sp;
        volatile cpm8xx_t       *cp;