diff options
author | Fengguang Wu <fengguang.wu@intel.com> | 2012-07-29 07:39:09 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-07-30 04:11:14 -0400 |
commit | e5b35420ef7e6dc92a6cc5914bc9e5e5c1d48819 (patch) | |
tree | 92a962c472447e706a64889aec56962c9cb627fe | |
parent | e427c2375646789ecd0ccaef1a1e41458559ab2d (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.h | 1 | ||||
-rw-r--r-- | sound/isa/es1688/es1688_lib.c | 34 |
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 | ||
33 | struct snd_es1688 { | 34 | struct 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 | ||
613 | static int snd_es1688_free(struct snd_es1688 *chip) | 613 | static 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); |
704 | exit: | ||
705 | if (err) | ||
706 | snd_es1688_free(chip); | ||
707 | return err; | ||
696 | } | 708 | } |
697 | 709 | ||
698 | static struct snd_pcm_ops snd_es1688_playback_ops = { | 710 | static struct snd_pcm_ops snd_es1688_playback_ops = { |