diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c1771929466b..0e292dc4fd87 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -337,6 +337,7 @@ struct azx { | |||
337 | unsigned int initialized :1; | 337 | unsigned int initialized :1; |
338 | unsigned int single_cmd :1; | 338 | unsigned int single_cmd :1; |
339 | unsigned int polling_mode :1; | 339 | unsigned int polling_mode :1; |
340 | unsigned int msi :1; | ||
340 | }; | 341 | }; |
341 | 342 | ||
342 | /* driver types */ | 343 | /* driver types */ |
@@ -397,6 +398,7 @@ static char *driver_short_names[] __devinitdata = { | |||
397 | */ | 398 | */ |
398 | #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) |
399 | 400 | ||
401 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | ||
400 | 402 | ||
401 | /* | 403 | /* |
402 | * Interface for HD codec | 404 | * Interface for HD codec |
@@ -536,6 +538,18 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) | |||
536 | schedule_timeout_interruptible(1); | 538 | schedule_timeout_interruptible(1); |
537 | } while (time_after_eq(timeout, jiffies)); | 539 | } while (time_after_eq(timeout, jiffies)); |
538 | 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 | |||
539 | if (!chip->polling_mode) { | 553 | if (!chip->polling_mode) { |
540 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " | 554 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " |
541 | "switching to polling mode...\n"); | 555 | "switching to polling mode...\n"); |
@@ -1364,6 +1378,20 @@ static int __devinit azx_init_stream(struct azx *chip) | |||
1364 | return 0; | 1378 | return 0; |
1365 | } | 1379 | } |
1366 | 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 | |||
1367 | 1395 | ||
1368 | #ifdef CONFIG_PM | 1396 | #ifdef CONFIG_PM |
1369 | /* | 1397 | /* |
@@ -1385,7 +1413,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
1385 | free_irq(chip->irq, chip); | 1413 | free_irq(chip->irq, chip); |
1386 | chip->irq = -1; | 1414 | chip->irq = -1; |
1387 | } | 1415 | } |
1388 | if (!disable_msi) | 1416 | if (chip->msi) |
1389 | pci_disable_msi(chip->pci); | 1417 | pci_disable_msi(chip->pci); |
1390 | pci_disable_device(pci); | 1418 | pci_disable_device(pci); |
1391 | pci_save_state(pci); | 1419 | pci_save_state(pci); |
@@ -1407,16 +1435,11 @@ static int azx_resume(struct pci_dev *pci) | |||
1407 | return -EIO; | 1435 | return -EIO; |
1408 | } | 1436 | } |
1409 | pci_set_master(pci); | 1437 | pci_set_master(pci); |
1410 | if (!disable_msi) | 1438 | if (chip->msi) |
1411 | pci_enable_msi(pci); | 1439 | if (pci_enable_msi(pci) < 0) |
1412 | if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1440 | chip->msi = 0; |
1413 | "HDA Intel", chip)) { | 1441 | if (azx_acquire_irq(chip, 1) < 0) |
1414 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " | ||
1415 | "disabling device\n", pci->irq); | ||
1416 | snd_card_disconnect(card); | ||
1417 | return -EIO; | 1442 | return -EIO; |
1418 | } | ||
1419 | chip->irq = pci->irq; | ||
1420 | azx_init_chip(chip); | 1443 | azx_init_chip(chip); |
1421 | snd_hda_resume(chip->bus); | 1444 | snd_hda_resume(chip->bus); |
1422 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 1445 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -1452,7 +1475,7 @@ static int azx_free(struct azx *chip) | |||
1452 | synchronize_irq(chip->irq); | 1475 | synchronize_irq(chip->irq); |
1453 | free_irq(chip->irq, (void*)chip); | 1476 | free_irq(chip->irq, (void*)chip); |
1454 | } | 1477 | } |
1455 | if (!disable_msi) | 1478 | if (chip->msi) |
1456 | pci_disable_msi(chip->pci); | 1479 | pci_disable_msi(chip->pci); |
1457 | if (chip->remap_addr) | 1480 | if (chip->remap_addr) |
1458 | iounmap(chip->remap_addr); | 1481 | iounmap(chip->remap_addr); |
@@ -1508,6 +1531,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1508 | chip->pci = pci; | 1531 | chip->pci = pci; |
1509 | chip->irq = -1; | 1532 | chip->irq = -1; |
1510 | chip->driver_type = driver_type; | 1533 | chip->driver_type = driver_type; |
1534 | chip->msi = !disable_msi; | ||
1511 | 1535 | ||
1512 | chip->position_fix = position_fix; | 1536 | chip->position_fix = position_fix; |
1513 | chip->single_cmd = single_cmd; | 1537 | chip->single_cmd = single_cmd; |
@@ -1537,16 +1561,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1537 | goto errout; | 1561 | goto errout; |
1538 | } | 1562 | } |
1539 | 1563 | ||
1540 | if (!disable_msi) | 1564 | if (chip->msi) |
1541 | pci_enable_msi(pci); | 1565 | if (pci_enable_msi(pci) < 0) |
1566 | chip->msi = 0; | ||
1542 | 1567 | ||
1543 | if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1568 | if (azx_acquire_irq(chip, 0) < 0) { |
1544 | "HDA Intel", (void*)chip)) { | ||
1545 | snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq); | ||
1546 | err = -EBUSY; | 1569 | err = -EBUSY; |
1547 | goto errout; | 1570 | goto errout; |
1548 | } | 1571 | } |
1549 | chip->irq = pci->irq; | ||
1550 | 1572 | ||
1551 | pci_set_master(pci); | 1573 | pci_set_master(pci); |
1552 | synchronize_irq(chip->irq); | 1574 | synchronize_irq(chip->irq); |