diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 81 |
1 files changed, 59 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index feeed12920b4..e35cfd326df2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -55,7 +55,7 @@ static char *model; | |||
55 | static int position_fix; | 55 | static int position_fix; |
56 | static int probe_mask = -1; | 56 | static int probe_mask = -1; |
57 | static int single_cmd; | 57 | static int single_cmd; |
58 | static int disable_msi; | 58 | static int enable_msi; |
59 | 59 | ||
60 | module_param(index, int, 0444); | 60 | module_param(index, int, 0444); |
61 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 61 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -69,8 +69,8 @@ module_param(probe_mask, int, 0444); | |||
69 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 69 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
70 | module_param(single_cmd, bool, 0444); | 70 | module_param(single_cmd, bool, 0444); |
71 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); | 71 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); |
72 | module_param(disable_msi, int, 0); | 72 | module_param(enable_msi, int, 0); |
73 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 73 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
74 | 74 | ||
75 | 75 | ||
76 | /* just for backward compatibility */ | 76 | /* just for backward compatibility */ |
@@ -86,6 +86,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
86 | "{ATI, SB450}," | 86 | "{ATI, SB450}," |
87 | "{ATI, SB600}," | 87 | "{ATI, SB600}," |
88 | "{ATI, RS600}," | 88 | "{ATI, RS600}," |
89 | "{ATI, RS690}," | ||
89 | "{VIA, VT8251}," | 90 | "{VIA, VT8251}," |
90 | "{VIA, VT8237A}," | 91 | "{VIA, VT8237A}," |
91 | "{SiS, SIS966}," | 92 | "{SiS, SIS966}," |
@@ -336,6 +337,7 @@ struct azx { | |||
336 | unsigned int initialized :1; | 337 | unsigned int initialized :1; |
337 | unsigned int single_cmd :1; | 338 | unsigned int single_cmd :1; |
338 | unsigned int polling_mode :1; | 339 | unsigned int polling_mode :1; |
340 | unsigned int msi :1; | ||
339 | }; | 341 | }; |
340 | 342 | ||
341 | /* driver types */ | 343 | /* driver types */ |
@@ -396,6 +398,7 @@ static char *driver_short_names[] __devinitdata = { | |||
396 | */ | 398 | */ |
397 | #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0) | 399 | #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0) |
398 | 400 | ||
401 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | ||
399 | 402 | ||
400 | /* | 403 | /* |
401 | * Interface for HD codec | 404 | * Interface for HD codec |
@@ -535,6 +538,18 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) | |||
535 | schedule_timeout_interruptible(1); | 538 | schedule_timeout_interruptible(1); |
536 | } while (time_after_eq(timeout, jiffies)); | 539 | } while (time_after_eq(timeout, jiffies)); |
537 | 540 | ||
541 | if (chip->msi) { | ||
542 | snd_printk(KERN_WARNING "hda_intel: No response from codec, " | ||
543 | "disabling MSI...\n"); | ||
544 | free_irq(chip->irq, chip); | ||
545 | chip->irq = -1; | ||
546 | pci_disable_msi(chip->pci); | ||
547 | chip->msi = 0; | ||
548 | if (azx_acquire_irq(chip, 1) < 0) | ||
549 | return -1; | ||
550 | goto again; | ||
551 | } | ||
552 | |||
538 | if (!chip->polling_mode) { | 553 | if (!chip->polling_mode) { |
539 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " | 554 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " |
540 | "switching to polling mode...\n"); | 555 | "switching to polling mode...\n"); |
@@ -1363,6 +1378,20 @@ static int __devinit azx_init_stream(struct azx *chip) | |||
1363 | return 0; | 1378 | return 0; |
1364 | } | 1379 | } |
1365 | 1380 | ||
1381 | static int azx_acquire_irq(struct azx *chip, int do_disconnect) | ||
1382 | { | ||
1383 | if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, | ||
1384 | "HDA Intel", chip)) { | ||
1385 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " | ||
1386 | "disabling device\n", chip->pci->irq); | ||
1387 | if (do_disconnect) | ||
1388 | snd_card_disconnect(chip->card); | ||
1389 | return -1; | ||
1390 | } | ||
1391 | chip->irq = chip->pci->irq; | ||
1392 | return 0; | ||
1393 | } | ||
1394 | |||
1366 | 1395 | ||
1367 | #ifdef CONFIG_PM | 1396 | #ifdef CONFIG_PM |
1368 | /* | 1397 | /* |
@@ -1379,12 +1408,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
1379 | snd_pcm_suspend_all(chip->pcm[i]); | 1408 | snd_pcm_suspend_all(chip->pcm[i]); |
1380 | snd_hda_suspend(chip->bus, state); | 1409 | snd_hda_suspend(chip->bus, state); |
1381 | azx_free_cmd_io(chip); | 1410 | azx_free_cmd_io(chip); |
1382 | if (chip->irq >= 0) | 1411 | if (chip->irq >= 0) { |
1412 | synchronize_irq(chip->irq); | ||
1383 | free_irq(chip->irq, chip); | 1413 | free_irq(chip->irq, chip); |
1384 | if (!disable_msi) | 1414 | chip->irq = -1; |
1415 | } | ||
1416 | if (chip->msi) | ||
1385 | pci_disable_msi(chip->pci); | 1417 | pci_disable_msi(chip->pci); |
1386 | pci_disable_device(pci); | 1418 | pci_disable_device(pci); |
1387 | pci_save_state(pci); | 1419 | pci_save_state(pci); |
1420 | pci_set_power_state(pci, pci_choose_state(pci, state)); | ||
1388 | return 0; | 1421 | return 0; |
1389 | } | 1422 | } |
1390 | 1423 | ||
@@ -1393,15 +1426,20 @@ static int azx_resume(struct pci_dev *pci) | |||
1393 | struct snd_card *card = pci_get_drvdata(pci); | 1426 | struct snd_card *card = pci_get_drvdata(pci); |
1394 | struct azx *chip = card->private_data; | 1427 | struct azx *chip = card->private_data; |
1395 | 1428 | ||
1429 | pci_set_power_state(pci, PCI_D0); | ||
1396 | pci_restore_state(pci); | 1430 | pci_restore_state(pci); |
1397 | pci_enable_device(pci); | 1431 | if (pci_enable_device(pci) < 0) { |
1398 | if (!disable_msi) | 1432 | printk(KERN_ERR "hda-intel: pci_enable_device failed, " |
1399 | pci_enable_msi(pci); | 1433 | "disabling device\n"); |
1400 | /* FIXME: need proper error handling */ | 1434 | snd_card_disconnect(card); |
1401 | request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1435 | return -EIO; |
1402 | "HDA Intel", chip); | 1436 | } |
1403 | chip->irq = pci->irq; | ||
1404 | pci_set_master(pci); | 1437 | pci_set_master(pci); |
1438 | if (chip->msi) | ||
1439 | if (pci_enable_msi(pci) < 0) | ||
1440 | chip->msi = 0; | ||
1441 | if (azx_acquire_irq(chip, 1) < 0) | ||
1442 | return -EIO; | ||
1405 | azx_init_chip(chip); | 1443 | azx_init_chip(chip); |
1406 | snd_hda_resume(chip->bus); | 1444 | snd_hda_resume(chip->bus); |
1407 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 1445 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -1431,15 +1469,14 @@ static int azx_free(struct azx *chip) | |||
1431 | /* disable position buffer */ | 1469 | /* disable position buffer */ |
1432 | azx_writel(chip, DPLBASE, 0); | 1470 | azx_writel(chip, DPLBASE, 0); |
1433 | azx_writel(chip, DPUBASE, 0); | 1471 | azx_writel(chip, DPUBASE, 0); |
1434 | |||
1435 | synchronize_irq(chip->irq); | ||
1436 | } | 1472 | } |
1437 | 1473 | ||
1438 | if (chip->irq >= 0) { | 1474 | if (chip->irq >= 0) { |
1475 | synchronize_irq(chip->irq); | ||
1439 | free_irq(chip->irq, (void*)chip); | 1476 | free_irq(chip->irq, (void*)chip); |
1440 | if (!disable_msi) | ||
1441 | pci_disable_msi(chip->pci); | ||
1442 | } | 1477 | } |
1478 | if (chip->msi) | ||
1479 | pci_disable_msi(chip->pci); | ||
1443 | if (chip->remap_addr) | 1480 | if (chip->remap_addr) |
1444 | iounmap(chip->remap_addr); | 1481 | iounmap(chip->remap_addr); |
1445 | 1482 | ||
@@ -1494,6 +1531,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1494 | chip->pci = pci; | 1531 | chip->pci = pci; |
1495 | chip->irq = -1; | 1532 | chip->irq = -1; |
1496 | chip->driver_type = driver_type; | 1533 | chip->driver_type = driver_type; |
1534 | chip->msi = enable_msi; | ||
1497 | 1535 | ||
1498 | chip->position_fix = position_fix; | 1536 | chip->position_fix = position_fix; |
1499 | chip->single_cmd = single_cmd; | 1537 | chip->single_cmd = single_cmd; |
@@ -1523,16 +1561,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1523 | goto errout; | 1561 | goto errout; |
1524 | } | 1562 | } |
1525 | 1563 | ||
1526 | if (!disable_msi) | 1564 | if (chip->msi) |
1527 | pci_enable_msi(pci); | 1565 | if (pci_enable_msi(pci) < 0) |
1566 | chip->msi = 0; | ||
1528 | 1567 | ||
1529 | if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1568 | if (azx_acquire_irq(chip, 0) < 0) { |
1530 | "HDA Intel", (void*)chip)) { | ||
1531 | snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq); | ||
1532 | err = -EBUSY; | 1569 | err = -EBUSY; |
1533 | goto errout; | 1570 | goto errout; |
1534 | } | 1571 | } |
1535 | chip->irq = pci->irq; | ||
1536 | 1572 | ||
1537 | pci_set_master(pci); | 1573 | pci_set_master(pci); |
1538 | synchronize_irq(chip->irq); | 1574 | synchronize_irq(chip->irq); |
@@ -1677,6 +1713,7 @@ static struct pci_device_id azx_ids[] = { | |||
1677 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ | 1713 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ |
1678 | { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ | 1714 | { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ |
1679 | { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ | 1715 | { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ |
1716 | { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ | ||
1680 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ | 1717 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ |
1681 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ | 1718 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ |
1682 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ | 1719 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ |