aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFengguang Wu <fengguang.wu@intel.com>2012-07-29 07:39:09 -0400
committerTakashi Iwai <tiwai@suse.de>2012-07-30 04:11:14 -0400
commite5b35420ef7e6dc92a6cc5914bc9e5e5c1d48819 (patch)
tree92a962c472447e706a64889aec56962c9cb627fe
parente427c2375646789ecd0ccaef1a1e41458559ab2d (diff)
ALSA: es1688 - freeup resources on init failure
This will fix the following oops: [ 6.169981] genirq: Flags mismatch irq 5. 00000000 (ES1688) vs. 00000000 (ES1688) [ 6.170851] Pid: 1, comm: swapper Not tainted 3.5.0-00004-gceee0e9 #14 [ 6.170851] Call Trace: [ 6.170851] [<c1062237>] ? __setup_irq+0x3c7/0x420 [ 6.170851] [<c1062486>] ? request_threaded_irq+0x76/0x140 [ 6.170851] [<c1290220>] ? snd_es1688_ioctl+0x10/0x10 [ 6.170851] [<c10624c2>] ? request_threaded_irq+0xb2/0x140 [ 6.170851] [<c1291196>] ? snd_es1688_create+0x96/0x330 [ 6.170851] [<c138365d>] ? snd_gusextreme_probe+0x18d/0x5a2 [ 6.170851] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.170851] [<c10db22f>] ? sysfs_create_link+0xf/0x20 [ 6.170851] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.170851] [<c11d1502>] ? isa_bus_probe+0x12/0x20 [ 6.170851] [<c11c9b95>] ? driver_probe_device+0x55/0x1c0 [ 6.170851] [<c13ae04f>] ? _raw_spin_unlock+0xf/0x30 [ 6.170851] [<c13705ea>] ? klist_next+0x6a/0xe0 [ 6.170851] [<c11d15c1>] ? isa_bus_match+0x21/0x40 [ 6.170851] [<c11c8a24>] ? bus_for_each_drv+0x34/0x70 [ 6.170851] [<c11c9e4b>] ? device_attach+0x7b/0x90 [ 6.170851] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.170851] [<c11c8bff>] ? bus_probe_device+0x5f/0x80 [ 6.170851] [<c11c7493>] ? device_add+0x573/0x620 [ 6.170851] [<c1042820>] ? complete_all+0x40/0x60 [ 6.170851] [<c13ae08a>] ? _raw_spin_unlock_irqrestore+0x1a/0x30 [ 6.170851] [<c11d16c6>] ? isa_register_driver+0xb6/0x150 [ 6.170851] [<c15c9002>] ? alsa_card_gusmax_init+0xf/0xf [ 6.170851] [<c15a99bc>] ? do_one_initcall+0x7f/0x12b [ 6.170851] [<c15a9b7a>] ? kernel_init+0x112/0x1a9 [ 6.170851] [<c15a9423>] ? do_early_param+0x77/0x77 [ 6.170851] [<c15a9a68>] ? do_one_initcall+0x12b/0x12b [ 6.170851] [<c13aefbe>] ? kernel_thread_helper+0x6/0xd [ 6.190170] es1688: can't grab IRQ 5 [ 6.190613] genirq: Flags mismatch irq 5. 00000000 (ES1688) vs. 00000000 (ES1688) [ 6.191566] Pid: 1, comm: swapper Not tainted 3.5.0-00004-gceee0e9 #14 [ 6.192394] Call Trace: [ 6.192685] [<c1062237>] ? __setup_irq+0x3c7/0x420 [ 6.193342] [<c1062486>] ? request_threaded_irq+0x76/0x140 [ 6.194081] [<c1290220>] ? snd_es1688_ioctl+0x10/0x10 [ 6.194607] [<c10624c2>] ? request_threaded_irq+0xb2/0x140 [ 6.194607] [<c1291196>] ? snd_es1688_create+0x96/0x330 [ 6.194607] [<c138365d>] ? snd_gusextreme_probe+0x18d/0x5a2 [ 6.194607] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.194607] [<c10db22f>] ? sysfs_create_link+0xf/0x20 [ 6.194607] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.194607] [<c11d1502>] ? isa_bus_probe+0x12/0x20 [ 6.194607] [<c11c9b95>] ? driver_probe_device+0x55/0x1c0 [ 6.194607] [<c13ae04f>] ? _raw_spin_unlock+0xf/0x30 [ 6.194607] [<c13705ea>] ? klist_next+0x6a/0xe0 [ 6.194607] [<c11d15c1>] ? isa_bus_match+0x21/0x40 [ 6.194607] [<c11c8a24>] ? bus_for_each_drv+0x34/0x70 [ 6.194607] [<c11c9e4b>] ? device_attach+0x7b/0x90 [ 6.194607] [<c11c9d80>] ? __driver_attach+0x80/0x80 [ 6.194607] [<c11c8bff>] ? bus_probe_device+0x5f/0x80 [ 6.194607] [<c11c7493>] ? device_add+0x573/0x620 [ 6.194607] [<c1042820>] ? complete_all+0x40/0x60 [ 6.194607] [<c13ae08a>] ? _raw_spin_unlock_irqrestore+0x1a/0x30 [ 6.194607] [<c11d16c6>] ? isa_register_driver+0xb6/0x150 [ 6.194607] [<c15c9002>] ? alsa_card_gusmax_init+0xf/0xf [ 6.194607] [<c15a99bc>] ? do_one_initcall+0x7f/0x12b [ 6.194607] [<c15a9b7a>] ? kernel_init+0x112/0x1a9 [ 6.194607] [<c15a9423>] ? do_early_param+0x77/0x77 [ 6.194607] [<c15a9a68>] ? do_one_initcall+0x12b/0x12b [ 6.194607] [<c13aefbe>] ? kernel_thread_helper+0x6/0xd [ 6.210779] es1688: can't grab IRQ 5 [ 6.211305] gusextreme: probe of gusextreme.0 failed with error -16 Signed-off-by: Daniel Mack <zonque@gmail.com> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/es1688.h1
-rw-r--r--sound/isa/es1688/es1688_lib.c34
2 files changed, 24 insertions, 11 deletions
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
index 3ec7ecbe2502..f752dd33dfaf 100644
--- a/include/sound/es1688.h
+++ b/include/sound/es1688.h
@@ -29,6 +29,7 @@
29#define ES1688_HW_AUTO 0x0000 29#define ES1688_HW_AUTO 0x0000
30#define ES1688_HW_688 0x0001 30#define ES1688_HW_688 0x0001
31#define ES1688_HW_1688 0x0002 31#define ES1688_HW_1688 0x0002
32#define ES1688_HW_UNDEF 0x0003
32 33
33struct snd_es1688 { 34struct snd_es1688 {
34 unsigned long port; /* port of ESS chip */ 35 unsigned long port; /* port of ESS chip */
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 1d47be8170b5..b3b4f15e45ba 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -612,10 +612,10 @@ static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
612 612
613static int snd_es1688_free(struct snd_es1688 *chip) 613static int snd_es1688_free(struct snd_es1688 *chip)
614{ 614{
615 if (chip->res_port) { 615 if (chip->hardware != ES1688_HW_UNDEF)
616 snd_es1688_init(chip, 0); 616 snd_es1688_init(chip, 0);
617 if (chip->res_port)
617 release_and_free_resource(chip->res_port); 618 release_and_free_resource(chip->res_port);
618 }
619 if (chip->irq >= 0) 619 if (chip->irq >= 0)
620 free_irq(chip->irq, (void *) chip); 620 free_irq(chip->irq, (void *) chip);
621 if (chip->dma8 >= 0) { 621 if (chip->dma8 >= 0) {
@@ -657,19 +657,27 @@ int snd_es1688_create(struct snd_card *card,
657 return -ENOMEM; 657 return -ENOMEM;
658 chip->irq = -1; 658 chip->irq = -1;
659 chip->dma8 = -1; 659 chip->dma8 = -1;
660 chip->hardware = ES1688_HW_UNDEF;
660 661
661 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 662 chip->res_port = request_region(port + 4, 12, "ES1688");
663 if (chip->res_port == NULL) {
662 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 664 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
663 return -EBUSY; 665 err = -EBUSY;
666 goto exit;
664 } 667 }
665 if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) { 668
669 err = request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip);
670 if (err < 0) {
666 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 671 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
667 return -EBUSY; 672 goto exit;
668 } 673 }
674
669 chip->irq = irq; 675 chip->irq = irq;
670 if (request_dma(dma8, "ES1688")) { 676 err = request_dma(dma8, "ES1688");
677
678 if (err < 0) {
671 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 679 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
672 return -EBUSY; 680 goto exit;
673 } 681 }
674 chip->dma8 = dma8; 682 chip->dma8 = dma8;
675 683
@@ -685,14 +693,18 @@ int snd_es1688_create(struct snd_card *card,
685 693
686 err = snd_es1688_probe(chip); 694 err = snd_es1688_probe(chip);
687 if (err < 0) 695 if (err < 0)
688 return err; 696 goto exit;
689 697
690 err = snd_es1688_init(chip, 1); 698 err = snd_es1688_init(chip, 1);
691 if (err < 0) 699 if (err < 0)
692 return err; 700 goto exit;
693 701
694 /* Register device */ 702 /* Register device */
695 return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 703 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
704exit:
705 if (err)
706 snd_es1688_free(chip);
707 return err;
696} 708}
697 709
698static struct snd_pcm_ops snd_es1688_playback_ops = { 710static struct snd_pcm_ops snd_es1688_playback_ops = {