Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / sound / oss / maestro.c
index 52d2db4..e647f2f 100644 (file)
 #include <linux/reboot.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/mutex.h>
+
 
 #include <asm/current.h>
 #include <asm/dma.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
-#include <linux/pm.h>
-static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);
-
 #include "maestro.h"
 
 static struct pci_driver maestro_pci_driver;
@@ -400,7 +399,7 @@ struct ess_state {
        /* this locks around the oss state in the driver */
        spinlock_t lock;
        /* only let 1 be opening at a time */
-       struct semaphore open_sem;
+       struct mutex open_mutex;
        wait_queue_head_t open_wait;
        mode_t open_mode;
 
@@ -2356,7 +2355,7 @@ ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
        }
 
 rec_return_free:
-       if(combbuf) kfree(combbuf);
+       kfree(combbuf);
        return ret;
 }
 
@@ -3023,26 +3022,26 @@ ess_open(struct inode *inode, struct file *file)
                VALIDATE_STATE(s);
        file->private_data = s;
        /* wait for device to become free */
-       down(&s->open_sem);
+       mutex_lock(&s->open_mutex);
        while (s->open_mode & file->f_mode) {
                if (file->f_flags & O_NONBLOCK) {
-                       up(&s->open_sem);
+                       mutex_unlock(&s->open_mutex);
                        return -EWOULDBLOCK;
                }
-               up(&s->open_sem);
+               mutex_unlock(&s->open_mutex);
                interruptible_sleep_on(&s->open_wait);
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               down(&s->open_sem);
+               mutex_lock(&s->open_mutex);
        }
 
        /* under semaphore.. */
        if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
-               up(&s->open_sem);
+               mutex_unlock(&s->open_mutex);
                return -ENOMEM;
        }
 
-       /* we're covered by the open_sem */
+       /* we're covered by the open_mutex */
        if( ! s->card->dsps_open )  {
                maestro_power(s->card,ACPI_D0);
                start_bob(s);
@@ -3079,7 +3078,7 @@ ess_open(struct inode *inode, struct file *file)
        set_fmt(s, fmtm, fmts);
        s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
 
-       up(&s->open_sem);
+       mutex_unlock(&s->open_mutex);
        return nonseekable_open(inode, file);
 }
 
@@ -3092,7 +3091,7 @@ ess_release(struct inode *inode, struct file *file)
        lock_kernel();
        if (file->f_mode & FMODE_WRITE)
                drain_dac(s, file->f_flags & O_NONBLOCK);
-       down(&s->open_sem);
+       mutex_lock(&s->open_mutex);
        if (file->f_mode & FMODE_WRITE) {
                stop_dac(s);
        }
@@ -3101,7 +3100,7 @@ ess_release(struct inode *inode, struct file *file)
        }
                
        s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-       /* we're covered by the open_sem */
+       /* we're covered by the open_mutex */
        M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
        if( --s->card->dsps_open <= 0) {
                s->card->dsps_open = 0;
@@ -3109,7 +3108,7 @@ ess_release(struct inode *inode, struct file *file)
                free_buffers(s);
                maestro_power(s->card,ACPI_D2);
        }
-       up(&s->open_sem);
+       mutex_unlock(&s->open_mutex);
        wake_up(&s->open_wait);
        unlock_kernel();
        return 0;
@@ -3403,7 +3402,6 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
        int i, ret;
        struct ess_card *card;
        struct ess_state *ess;
-       struct pm_dev *pmdev;
        int num = 0;
 
 /* when built into the kernel, we only print version if device is found */
@@ -3449,11 +3447,6 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
        memset(card, 0, sizeof(*card));
        card->pcidev = pcidev;
 
-       pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev),
-                       maestro_pm_callback);
-       if (pmdev)
-               pmdev->data = card;
-
        card->iobase = iobase;
        card->card_type = card_type;
        card->irq = pcidev->irq;
@@ -3475,7 +3468,7 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
                init_waitqueue_head(&s->dma_dac.wait);
                init_waitqueue_head(&s->open_wait);
                spin_lock_init(&s->lock);
-               init_MUTEX(&s->open_sem);
+               mutex_init(&s->open_mutex);
                s->magic = ESS_STATE_MAGIC;
                
                s->apu[0] = 6*i;
@@ -3633,7 +3626,7 @@ static int __init init_maestro(void)
 {
        int rc;
 
-       rc = pci_module_init(&maestro_pci_driver);
+       rc = pci_register_driver(&maestro_pci_driver);
        if (rc < 0)
                return rc;
 
@@ -3669,7 +3662,6 @@ static int maestro_notifier(struct notifier_block *nb, unsigned long event, void
 static void cleanup_maestro(void) {
        M_printk("maestro: unloading\n");
        pci_unregister_driver(&maestro_pci_driver);
-       pm_unregister_all(maestro_pm_callback);
        unregister_reboot_notifier(&maestro_nb);
 }
 
@@ -3690,143 +3682,5 @@ check_suspend(struct ess_card *card)
        current->state = TASK_RUNNING;
 }
 
-static int 
-maestro_suspend(struct ess_card *card)
-{
-       unsigned long flags;
-       int i,j;
-
-       spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-       M_printk("maestro: apm in dev %p\n",card);
-
-       /* we have to read from the apu regs, need
-               to power it up */
-       maestro_power(card,ACPI_D0);
-
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *s = &card->channels[i];
-
-               if(s->dev_audio == -1)
-                       continue;
-
-               M_printk("maestro: stopping apus for device %d\n",i);
-               stop_dac(s);
-               stop_adc(s);
-               for(j=0;j<6;j++) 
-                       card->apu_map[s->apu[j]][5]=apu_get_register(s,j,5);
-
-       }
-
-       /* get rid of interrupts? */
-       if( card->dsps_open > 0)
-               stop_bob(&card->channels[0]);
-
-       card->in_suspend++;
-
-       spin_unlock_irqrestore(&card->lock,flags);
-
-       /* we trust in the bios to power down the chip on suspend.
-        * XXX I'm also not sure that in_suspend will protect
-        * against all reg accesses from here on out. 
-        */
-       return 0;
-}
-static int 
-maestro_resume(struct ess_card *card)
-{
-       unsigned long flags;
-       int i;
-
-       spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-       card->in_suspend = 0;
-
-       M_printk("maestro: resuming card at %p\n",card);
-
-       /* restore all our config */
-       maestro_config(card);
-       /* need to restore the base pointers.. */ 
-       if(card->dmapages) 
-               set_base_registers(&card->channels[0],card->dmapages);
-
-       mixer_push_state(card);
-
-       /* set each channels' apu control registers before
-        * restoring audio 
-        */
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *s = &card->channels[i];
-               int chan,reg;
-
-               if(s->dev_audio == -1)
-                       continue;
-
-               for(chan = 0 ; chan < 6 ; chan++) {
-                       wave_set_register(s,s->apu[chan]<<3,s->apu_base[chan]);
-                       for(reg = 1 ; reg < NR_APU_REGS ; reg++)  
-                               apu_set_register(s,chan,reg,s->card->apu_map[s->apu[chan]][reg]);
-               }
-               for(chan = 0 ; chan < 6 ; chan++)  
-                       apu_set_register(s,chan,0,s->card->apu_map[s->apu[chan]][0] & 0xFF0F);
-       }
-
-       /* now we flip on the music */
-
-       if( card->dsps_open <= 0) {
-               /* this card's idle */
-               maestro_power(card,ACPI_D2);
-       } else {
-               /* ok, we're actually playing things on
-                       this card */
-               maestro_power(card,ACPI_D0);
-               start_bob(&card->channels[0]);
-               for(i=0;i<NR_DSPS;i++) {
-                       struct ess_state *s = &card->channels[i];
-
-                       /* these use the apu_mode, and can handle
-                               spurious calls */
-                       start_dac(s);   
-                       start_adc(s);   
-               }
-       }
-
-       spin_unlock_irqrestore(&card->lock,flags);
-
-       /* all right, we think things are ready, 
-               wake up people who were using the device
-               when we suspended */
-       wake_up(&(card->suspend_queue));
-
-       return 0;
-}
-
-int 
-maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) 
-{
-       struct ess_card *card = (struct ess_card*) dev->data;
-
-       if ( ! card ) goto out;
-
-       M_printk("maestro: pm event 0x%x received for card %p\n", rqst, card);
-       
-       switch (rqst) {
-               case PM_SUSPEND: 
-                       maestro_suspend(card);
-               break;
-               case PM_RESUME: 
-                       maestro_resume(card);
-               break;
-               /*
-                * we'd also like to find out about
-                * power level changes because some biosen
-                * do mean things to the maestro when they
-                * change their power state.
-                */
-        }
-out:
-       return 0;
-}
-
 module_init(init_maestro);
 module_exit(cleanup_maestro);