#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>
-#include <linux/pm_legacy.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;
/* 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;
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);
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);
}
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);
}
}
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;
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;
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 */
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;
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;
mixer_push_state(card);
}
- if((ret=request_irq(card->irq, ess_interrupt, SA_SHIRQ, card_names[card_type], card)))
+ if((ret=request_irq(card->irq, ess_interrupt, IRQF_SHARED, card_names[card_type], card)))
{
printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq);
unregister_sound_mixer(card->dev_mixer);
{
int rc;
- rc = pci_module_init(&maestro_pci_driver);
+ rc = pci_register_driver(&maestro_pci_driver);
if (rc < 0)
return rc;
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);
}
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);