From patchwork Mon Aug 5 02:56:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 2838542 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0042BBF535 for ; Mon, 5 Aug 2013 06:36:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EDFEA20160 for ; Mon, 5 Aug 2013 06:36:52 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id DCB2720157 for ; Mon, 5 Aug 2013 06:36:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C6D0CE5ED8 for ; Sun, 4 Aug 2013 23:36:51 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 04578E5D1F for ; Sun, 4 Aug 2013 19:56:25 -0700 (PDT) Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r752uP3I004504 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 4 Aug 2013 22:56:25 -0400 Received: from prime.bne.redhat.com (dhcp-41-132.bne.redhat.com [10.64.41.132]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r752u7SD028182; Sun, 4 Aug 2013 22:56:21 -0400 From: Dave Airlie To: dri-devel@lists.freedesktop.org Subject: [PATCH 4/4] snd/hda: add runtime suspend/resume on optimus support (v3) Date: Mon, 5 Aug 2013 12:56:04 +1000 Message-Id: <1375671364-1088-5-git-send-email-airlied@gmail.com> In-Reply-To: <1375671364-1088-1-git-send-email-airlied@gmail.com> References: <1375671364-1088-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Cc: tiwai@suse.de X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for HDMI audio device on VGA cards that powerdown to D3cold using non-standard ACPI/PCI infrastructure (optimus). This does a couple of things to make it work: a) add a set of power ops for the hdmi domain, and enables them via vga_switcheroo when we are a switcheroo controlled card. This just replaces the runtime resume operation so that when the card is in D3cold the userspace pci config space access via sysfs, the vga switcheroon runtime resume gets called first and it calls the GPU resume callback before calling the sound card runtime resume. b) standard ACPI/PCI stacks won't put a device into D3cold without an ACPI handle, but since the hdmi audio devices on gpus don't have an ACPI handle, we need to manually force the device into D3cold after suspend from the switcheroo path only. c) don't try and do runtime s/r when the GPU is off. d) call runtime suspend/resume during switcheroo suspend/resume this is to make sure the runtime stack knows to try and resume the hdmi audio device for pci config space access. v2: fix incorrect runtime call suspend->resume. v3: rework irq handler to avoid false irq when we are resuming but haven't runtime resumed yet, don't bother trying D3cold, it won't work, just set it manually ourselves, move runtime s/r calls outside the main s/r hook. enable dnyamic pm properly by dropping reference. Signed-off-by: Dave Airlie --- sound/pci/hda/hda_intel.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8860dd5..4c4f546 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -555,6 +555,9 @@ struct azx { #ifdef CONFIG_SND_HDA_DSP_LOADER struct azx_dev saved_azx_dev; #endif + + /* secondary power domain for hdmi audio under vga device */ + struct dev_pm_domain hdmi_pm_domain; }; #define CREATE_TRACE_POINTS @@ -1396,11 +1399,6 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) u8 sd_status; int i, ok; -#ifdef CONFIG_PM_RUNTIME - if (chip->pci->dev.power.runtime_status != RPM_ACTIVE) - return IRQ_NONE; -#endif - spin_lock(&chip->reg_lock); if (chip->disabled) { @@ -1409,7 +1407,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) } status = azx_readl(chip, INTSTS); - if (status == 0) { + if (status == 0 || status == 0xffffffff) { spin_unlock(&chip->reg_lock); return IRQ_NONE; } @@ -2971,6 +2969,12 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; + if (chip->disabled) + return 0; + + if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) + return 0; + azx_stop_chip(chip); azx_enter_link_reset(chip); azx_clear_irq_pending(chip); @@ -2984,6 +2988,12 @@ static int azx_runtime_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; + if (chip->disabled) + return 0; + + if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) + return 0; + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) hda_display_power(true); azx_init_pci(chip); @@ -2996,6 +3006,9 @@ static int azx_runtime_idle(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; + if (chip->disabled) + return 0; + if (!power_save_controller || !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) return -EBUSY; @@ -3078,13 +3091,19 @@ static void azx_vs_set_state(struct pci_dev *pci, "%s: %s via VGA-switcheroo\n", pci_name(chip->pci), disabled ? "Disabling" : "Enabling"); if (disabled) { + pm_runtime_put_sync_suspend(&pci->dev); azx_suspend(&pci->dev); + /* when we get suspended by vga switcheroo we end up in D3cold, + * however we have no ACPI handle, so pci/acpi can't put us there, + * put ourselves there */ + pci->current_state = PCI_D3cold; chip->disabled = true; if (snd_hda_lock_devices(chip->bus)) snd_printk(KERN_WARNING SFX "%s: Cannot lock devices!\n", pci_name(chip->pci)); } else { snd_hda_unlock_devices(chip->bus); + pm_runtime_get_noresume(&pci->dev); chip->disabled = false; azx_resume(&pci->dev); } @@ -3139,6 +3158,9 @@ static int register_vga_switcheroo(struct azx *chip) if (err < 0) return err; chip->vga_switcheroo_registered = 1; + + /* register as an optimus hdmi audio power domain */ + vga_switcheroo_init_domain_pm_optimus_hdmi_audio(&chip->pci->dev, &chip->hdmi_pm_domain); return 0; } #else @@ -3887,7 +3909,7 @@ static int azx_probe_continue(struct azx *chip) power_down_all_codecs(chip); azx_notifier_register(chip); azx_add_card_list(chip); - if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME) + if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo) pm_runtime_put_noidle(&pci->dev); return 0;