vserver 2.0 rc7
[linux-2.6.git] / sound / pci / cs46xx / cs46xx_lib.c
index 0dcfee8..5f2ffb7 100644 (file)
@@ -1217,9 +1217,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *r
                        c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
                        if ((chip->midcr & MIDCR_RIE) == 0)
                                continue;
-                       spin_unlock(&chip->reg_lock);
                        snd_rawmidi_receive(chip->midi_input, &c, 1);
-                       spin_lock(&chip->reg_lock);
                }
                while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
                        if ((chip->midcr & MIDCR_TIE) == 0)
@@ -2690,37 +2688,28 @@ int __devinit snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmi
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 
-typedef struct snd_cs46xx_gameport {
-       struct gameport info;
-       cs46xx_t *chip;
-} cs46xx_gameport_t;
-
 static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
 {
-       cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport;
-       cs46xx_t *chip;
-       snd_assert(gp, return);
-       chip = gp->chip;
+       cs46xx_t *chip = gameport_get_port_data(gameport);
+
+       snd_assert(chip, return);
        snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
 }
 
 static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
 {
-       cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport;
-       cs46xx_t *chip;
-       snd_assert(gp, return 0);
-       chip = gp->chip;
+       cs46xx_t *chip = gameport_get_port_data(gameport);
+
+       snd_assert(chip, return 0);
        return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
 }
 
 static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-       cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport;
-       cs46xx_t *chip;
+       cs46xx_t *chip = gameport_get_port_data(gameport);
        unsigned js1, js2, jst;
-       
-       snd_assert(gp, return 0);
-       chip = gp->chip;
+
+       snd_assert(chip, return 0);
 
        js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
        js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
@@ -2751,33 +2740,44 @@ static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
        return 0;
 }
 
-void __devinit snd_cs46xx_gameport(cs46xx_t *chip)
+int __devinit snd_cs46xx_gameport(cs46xx_t *chip)
 {
-       cs46xx_gameport_t *gp;
-       gp = kmalloc(sizeof(*gp), GFP_KERNEL);
-       if (! gp) {
-               snd_printk("cannot allocate gameport area\n");
-               return;
+       struct gameport *gp;
+
+       chip->gameport = gp = gameport_allocate_port();
+       if (!gp) {
+               printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n");
+               return -ENOMEM;
        }
-       memset(gp, 0, sizeof(*gp));
-       gp->info.open = snd_cs46xx_gameport_open;
-       gp->info.read = snd_cs46xx_gameport_read;
-       gp->info.trigger = snd_cs46xx_gameport_trigger;
-       gp->info.cooked_read = snd_cs46xx_gameport_cooked_read;
-       gp->chip = chip;
-       chip->gameport = gp;
+
+       gameport_set_name(gp, "CS46xx Gameport");
+       gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
+       gameport_set_dev_parent(gp, &chip->pci->dev);
+       gameport_set_port_data(gp, chip);
+
+       gp->open = snd_cs46xx_gameport_open;
+       gp->read = snd_cs46xx_gameport_read;
+       gp->trigger = snd_cs46xx_gameport_trigger;
+       gp->cooked_read = snd_cs46xx_gameport_cooked_read;
 
        snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
        snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
-       gameport_register_port(&gp->info);
-}
 
-#else
+       gameport_register_port(gp);
 
-void __devinit snd_cs46xx_gameport(cs46xx_t *chip)
-{
+       return 0;
 }
 
+static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip)
+{
+       if (chip->gameport) {
+               gameport_unregister_port(chip->gameport);
+               chip->gameport = NULL;
+       }
+}
+#else
+int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { return -ENOSYS; }
+static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) { }
 #endif /* CONFIG_GAMEPORT */
 
 /*
@@ -2893,12 +2893,7 @@ static int snd_cs46xx_free(cs46xx_t *chip)
        if (chip->active_ctrl)
                chip->active_ctrl(chip, 1);
 
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-       if (chip->gameport) {
-               gameport_unregister_port(&chip->gameport->info);
-               kfree(chip->gameport);
-       }
-#endif
+       snd_cs46xx_remove_gameport(chip);
 
        if (chip->amplifier_ctrl)
                chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
@@ -3704,7 +3699,7 @@ static struct cs_card_type __devinitdata cards[] = {
  * APM support
  */
 #ifdef CONFIG_PM
-static int snd_cs46xx_suspend(snd_card_t *card, unsigned int state)
+static int snd_cs46xx_suspend(snd_card_t *card, pm_message_t state)
 {
        cs46xx_t *chip = card->pm_private_data;
        int amp_saved;
@@ -3728,7 +3723,7 @@ static int snd_cs46xx_suspend(snd_card_t *card, unsigned int state)
        return 0;
 }
 
-static int snd_cs46xx_resume(snd_card_t *card, unsigned int state)
+static int snd_cs46xx_resume(snd_card_t *card)
 {
        cs46xx_t *chip = card->pm_private_data;
        int amp_saved;