aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorWang Xingchao <xingchao.wang@linux.intel.com>2013-05-30 10:07:10 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-06 11:31:56 -0400
commit99a2008d0b32d72dfc2a54e7be1eb698dd2e3bd6 (patch)
treea4966a9b0e4c03e329875c17e998959e8a394e1b /sound/pci/hda/hda_intel.c
parent5c90680e42b08a1e4a6800ca02e75ad201f8037f (diff)
ALSA: hda - Add power-welll support for haswell HDA
For Intel Haswell chip, HDA controller and codec have power well dependency from GPU side. This patch added support to request/release power well in audio driver. Power save feature should be enabled to get runtime power saving. There's deadlock when request_module(i915) in azx_probe. It looks like: device_lock(audio pci device) -> azx_probe -> module_request (or symbol_request) -> modprobe (userspace) -> i915 init -> drm_pci_init -> pci_register_driver -> bus_add_driver -> driver_attach -> which in turn tries all locks on pci bus, and when it tries the one on the audio device, it will deadlock. This patch introduce a work to store remaining probe stuff, and let request_module run in safe work context. Signed-off-by: Wang Xingchao <xingchao.wang@linux.intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 3e3126ba8276..35e9f8b010a7 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -62,6 +62,7 @@
62#include <linux/vga_switcheroo.h> 62#include <linux/vga_switcheroo.h>
63#include <linux/firmware.h> 63#include <linux/firmware.h>
64#include "hda_codec.h" 64#include "hda_codec.h"
65#include "hda_i915.h"
65 66
66 67
67static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -541,6 +542,10 @@ struct azx {
541 /* for pending irqs */ 542 /* for pending irqs */
542 struct work_struct irq_pending_work; 543 struct work_struct irq_pending_work;
543 544
545#ifdef CONFIG_SND_HDA_I915
546 struct work_struct probe_work;
547#endif
548
544 /* reboot notifier (for mysterious hangup problem at power-down) */ 549 /* reboot notifier (for mysterious hangup problem at power-down) */
545 struct notifier_block reboot_notifier; 550 struct notifier_block reboot_notifier;
546 551
@@ -594,6 +599,7 @@ enum {
594#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 599#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
595#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ 600#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
596#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ 601#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
602#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 power well support */
597 603
598/* quirks for Intel PCH */ 604/* quirks for Intel PCH */
599#define AZX_DCAPS_INTEL_PCH_NOPM \ 605#define AZX_DCAPS_INTEL_PCH_NOPM \
@@ -2900,6 +2906,8 @@ static int azx_suspend(struct device *dev)
2900 pci_disable_device(pci); 2906 pci_disable_device(pci);
2901 pci_save_state(pci); 2907 pci_save_state(pci);
2902 pci_set_power_state(pci, PCI_D3hot); 2908 pci_set_power_state(pci, PCI_D3hot);
2909 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2910 hda_display_power(false);
2903 return 0; 2911 return 0;
2904} 2912}
2905 2913
@@ -2912,6 +2920,8 @@ static int azx_resume(struct device *dev)
2912 if (chip->disabled) 2920 if (chip->disabled)
2913 return 0; 2921 return 0;
2914 2922
2923 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2924 hda_display_power(true);
2915 pci_set_power_state(pci, PCI_D0); 2925 pci_set_power_state(pci, PCI_D0);
2916 pci_restore_state(pci); 2926 pci_restore_state(pci);
2917 if (pci_enable_device(pci) < 0) { 2927 if (pci_enable_device(pci) < 0) {
@@ -2944,6 +2954,8 @@ static int azx_runtime_suspend(struct device *dev)
2944 2954
2945 azx_stop_chip(chip); 2955 azx_stop_chip(chip);
2946 azx_clear_irq_pending(chip); 2956 azx_clear_irq_pending(chip);
2957 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2958 hda_display_power(false);
2947 return 0; 2959 return 0;
2948} 2960}
2949 2961
@@ -2952,6 +2964,8 @@ static int azx_runtime_resume(struct device *dev)
2952 struct snd_card *card = dev_get_drvdata(dev); 2964 struct snd_card *card = dev_get_drvdata(dev);
2953 struct azx *chip = card->private_data; 2965 struct azx *chip = card->private_data;
2954 2966
2967 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2968 hda_display_power(true);
2955 azx_init_pci(chip); 2969 azx_init_pci(chip);
2956 azx_init_chip(chip, 1); 2970 azx_init_chip(chip, 1);
2957 return 0; 2971 return 0;
@@ -3176,6 +3190,10 @@ static int azx_free(struct azx *chip)
3176 if (chip->fw) 3190 if (chip->fw)
3177 release_firmware(chip->fw); 3191 release_firmware(chip->fw);
3178#endif 3192#endif
3193 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3194 hda_display_power(false);
3195 hda_i915_exit();
3196 }
3179 kfree(chip); 3197 kfree(chip);
3180 3198
3181 return 0; 3199 return 0;
@@ -3401,6 +3419,13 @@ static void azx_check_snoop_available(struct azx *chip)
3401 } 3419 }
3402} 3420}
3403 3421
3422#ifdef CONFIG_SND_HDA_I915
3423static void azx_probe_work(struct work_struct *work)
3424{
3425 azx_probe_continue(container_of(work, struct azx, probe_work));
3426}
3427#endif
3428
3404/* 3429/*
3405 * constructor 3430 * constructor
3406 */ 3431 */
@@ -3476,7 +3501,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
3476 return err; 3501 return err;
3477 } 3502 }
3478 3503
3504#ifdef CONFIG_SND_HDA_I915
3505 /* continue probing in work context as may trigger request module */
3506 INIT_WORK(&chip->probe_work, azx_probe_work);
3507#endif
3508
3479 *rchip = chip; 3509 *rchip = chip;
3510
3480 return 0; 3511 return 0;
3481} 3512}
3482 3513
@@ -3747,6 +3778,16 @@ static int azx_probe(struct pci_dev *pci,
3747 } 3778 }
3748#endif /* CONFIG_SND_HDA_PATCH_LOADER */ 3779#endif /* CONFIG_SND_HDA_PATCH_LOADER */
3749 3780
3781 /* continue probing in work context, avoid request_module deadlock */
3782 if (probe_now && (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)) {
3783#ifdef CONFIG_SND_HDA_I915
3784 probe_now = false;
3785 schedule_work(&chip->probe_work);
3786#else
3787 snd_printk(KERN_ERR SFX "Haswell must build in CONFIG_SND_HDA_I915\n");
3788#endif
3789 }
3790
3750 if (probe_now) { 3791 if (probe_now) {
3751 err = azx_probe_continue(chip); 3792 err = azx_probe_continue(chip);
3752 if (err < 0) 3793 if (err < 0)
@@ -3769,6 +3810,16 @@ static int azx_probe_continue(struct azx *chip)
3769 int dev = chip->dev_index; 3810 int dev = chip->dev_index;
3770 int err; 3811 int err;
3771 3812
3813 /* Request power well for Haswell HDA controller and codec */
3814 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3815 err = hda_i915_init();
3816 if (err < 0) {
3817 snd_printk(KERN_ERR SFX "Error request power-well from i915\n");
3818 goto out_free;
3819 }
3820 hda_display_power(true);
3821 }
3822
3772 err = azx_first_init(chip); 3823 err = azx_first_init(chip);
3773 if (err < 0) 3824 if (err < 0)
3774 goto out_free; 3825 goto out_free;
@@ -3863,11 +3914,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3863 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, 3914 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
3864 /* Haswell */ 3915 /* Haswell */
3865 { PCI_DEVICE(0x8086, 0x0a0c), 3916 { PCI_DEVICE(0x8086, 0x0a0c),
3866 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3917 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3918 AZX_DCAPS_I915_POWERWELL },
3867 { PCI_DEVICE(0x8086, 0x0c0c), 3919 { PCI_DEVICE(0x8086, 0x0c0c),
3868 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3920 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3921 AZX_DCAPS_I915_POWERWELL },
3869 { PCI_DEVICE(0x8086, 0x0d0c), 3922 { PCI_DEVICE(0x8086, 0x0d0c),
3870 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3923 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3924 AZX_DCAPS_I915_POWERWELL },
3871 /* 5 Series/3400 */ 3925 /* 5 Series/3400 */
3872 { PCI_DEVICE(0x8086, 0x3b56), 3926 { PCI_DEVICE(0x8086, 0x3b56),
3873 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 3927 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },