aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-04-26 06:13:25 -0400
committerTakashi Iwai <tiwai@suse.de>2012-05-14 08:49:17 -0400
commit9121947d696df7ea259c0102e449da9621b9cf92 (patch)
treed9924ab48c80ba91649c2e4bae8adc1b44ad11b2 /sound/pci/hda/hda_intel.c
parentd9bbb4756dbc05764cebd0e3e2f49a56c9504e4d (diff)
ALSA: hda - Check the dead HDMI audio controller by vga-switcheroo
When a discrete-GPU is disabled by the VGA switcheroo, the corresponding HD-audio controller for HDMI output is also disabled. Such a dead controller still appears in the PCI device list, but you can't access properly any longer (even calling pci_read_config_*() triggers Oops!) which leads the stall of the whole communication of the driver. This patch adds a check of graphics controller at the probe time to see whether it's disabled by vga-switcheroo. If disabled, skip the whole initialization of this controller. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43155 Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a70d7e5443aa..06a4ad3e5cd2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -53,6 +53,7 @@
53#endif 53#endif
54#include <sound/core.h> 54#include <sound/core.h>
55#include <sound/initval.h> 55#include <sound/initval.h>
56#include <linux/vgaarb.h>
56#include "hda_codec.h" 57#include "hda_codec.h"
57 58
58 59
@@ -2494,6 +2495,45 @@ static int azx_dev_free(struct snd_device *device)
2494} 2495}
2495 2496
2496/* 2497/*
2498 * Check of disabled HDMI controller by vga-switcheroo
2499 */
2500static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci)
2501{
2502 struct pci_dev *p;
2503
2504 /* check only discrete GPU */
2505 switch (pci->vendor) {
2506 case PCI_VENDOR_ID_ATI:
2507 case PCI_VENDOR_ID_AMD:
2508 case PCI_VENDOR_ID_NVIDIA:
2509 if (pci->devfn == 1) {
2510 p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
2511 pci->bus->number, 0);
2512 if (p) {
2513 if ((p->class >> 8) == PCI_CLASS_DISPLAY_VGA)
2514 return p;
2515 pci_dev_put(p);
2516 }
2517 }
2518 break;
2519 }
2520 return NULL;
2521}
2522
2523static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
2524{
2525 bool vga_inactive = false;
2526 struct pci_dev *p = get_bound_vga(pci);
2527
2528 if (p) {
2529 if (vga_default_device() && p != vga_default_device())
2530 vga_inactive = true;
2531 pci_dev_put(p);
2532 }
2533 return vga_inactive;
2534}
2535
2536/*
2497 * white/black-listing for position_fix 2537 * white/black-listing for position_fix
2498 */ 2538 */
2499static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2539static struct snd_pci_quirk position_fix_list[] __devinitdata = {
@@ -2928,6 +2968,12 @@ static int __devinit azx_probe(struct pci_dev *pci,
2928 return -ENOENT; 2968 return -ENOENT;
2929 } 2969 }
2930 2970
2971 if (check_hdmi_disabled(pci)) {
2972 snd_printk(KERN_INFO SFX
2973 "Inactive VGA controller; disabled audio, too\n");
2974 goto out;
2975 }
2976
2931 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 2977 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
2932 if (err < 0) { 2978 if (err < 0) {
2933 snd_printk(KERN_ERR SFX "Error creating card!\n"); 2979 snd_printk(KERN_ERR SFX "Error creating card!\n");
@@ -2984,8 +3030,10 @@ static int __devinit azx_probe(struct pci_dev *pci,
2984 power_down_all_codecs(chip); 3030 power_down_all_codecs(chip);
2985 azx_notifier_register(chip); 3031 azx_notifier_register(chip);
2986 3032
3033 out:
2987 dev++; 3034 dev++;
2988 return err; 3035 return 0;
3036
2989out_free: 3037out_free:
2990 snd_card_free(card); 3038 snd_card_free(card);
2991 return err; 3039 return err;
@@ -2993,7 +3041,9 @@ out_free:
2993 3041
2994static void __devexit azx_remove(struct pci_dev *pci) 3042static void __devexit azx_remove(struct pci_dev *pci)
2995{ 3043{
2996 snd_card_free(pci_get_drvdata(pci)); 3044 struct snd_card *card = pci_get_drvdata(pci);
3045 if (card)
3046 snd_card_free(card);
2997 pci_set_drvdata(pci, NULL); 3047 pci_set_drvdata(pci, NULL);
2998} 3048}
2999 3049