From patchwork Fri Feb 28 23:41:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Reid X-Patchwork-Id: 3745411 X-Patchwork-Delegate: tiwai@suse.de Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DF0899F35F for ; Fri, 28 Feb 2014 23:47:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D2B58202EA for ; Fri, 28 Feb 2014 23:47:36 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 18B35202A7 for ; Fri, 28 Feb 2014 23:47:35 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 1BF01265DE9; Sat, 1 Mar 2014 00:47:34 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 706212659B1; Sat, 1 Mar 2014 00:43:14 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 135C7265A63; Sat, 1 Mar 2014 00:43:13 +0100 (CET) Received: from mail-qc0-f201.google.com (mail-qc0-f201.google.com [209.85.216.201]) by alsa0.perex.cz (Postfix) with ESMTP id 9A2922659B2 for ; Sat, 1 Mar 2014 00:42:52 +0100 (CET) Received: by mail-qc0-f201.google.com with SMTP id i17so173137qcy.2 for ; Fri, 28 Feb 2014 15:42:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bSLm0ST4sRsbfgEFtqNK/zPIQ1KgW9XgJfjRLa7pghw=; b=Oz4b8DBGQUxXfZkVci2NWUqc+kD//+GaMlwh0bf+VDhfmYKmSeB/snWWDEQH1X+fiS RbjeKFyo26oSJvgkiqFnxeMfsdyMOH0wQJgULtxvPwrnV1QydBJGhfRUuKoP+lyBiPiD DDHeZ49b+O04NXyBuSKIsAUXSJrojZlP5O5dZA356gt8ClfXTViIA9E3kaJCOHMMDf4F NtvCedG1hDjlFpj8rZF2o6oJntsqhXjE6D8Sat6tCzE3T9d9IldE7JW0aloPHlK8uzk2 EhVMDCrQ8rTP4YKyoJdVoebTaJ2qEwUwZodH1N4Ck6S+ru1gZHUP89lC1kRm4EaMrI/8 VIfw== X-Gm-Message-State: ALoCoQnqjVCbqIKJp+QO42o8aIpdrNqaLyWL8yPYHosJQ3ACQmsH+AvugTNoukJ1O6cXfhQaoPazcJkxtLh3TlpkwcdfUr7KZfOzGHEwSaOSFngyDueSEWqTFw+UokMVf8AGwSud9PLOv1k4U2/bjRQaZ/vSh3gyJCDLhSVWnIa4MurlmtTWfPGZt6CvY8qXWAdd4zcgBEeec+W6U0WLoMB583yh8ikyf1q1qtyUJui5drx4vzyfl58= X-Received: by 10.236.126.170 with SMTP id b30mr2181907yhi.49.1393630971381; Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id x29si545908yha.0.2014.02.28.15.42.51 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: from hojo20.mtv.corp.google.com (hojo20.mtv.corp.google.com [172.22.72.28]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 299EC5A41D9; Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: by hojo20.mtv.corp.google.com (Postfix, from userid 123195) id D12EB181DE7; Fri, 28 Feb 2014 15:42:50 -0800 (PST) From: Dylan Reid To: alsa-devel@alsa-project.org Date: Fri, 28 Feb 2014 15:41:20 -0800 Message-Id: <1393630893-29010-10-git-send-email-dgreid@chromium.org> X-Mailer: git-send-email 1.8.1.3.605.g02339dd In-Reply-To: <1393630893-29010-1-git-send-email-dgreid@chromium.org> References: <1393630893-29010-1-git-send-email-dgreid@chromium.org> Cc: tiwai@suse.de, Dylan Reid , swarren@wwwdotorg.org Subject: [alsa-devel] [RFCv2 09/22] ALSA: hda - Move snd page allocation to ops X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Break out the allocation of pages for DMA and PCM buffers to ops in the chip structure. This is done to allow for architecture specific work-arounds to be added. Currently mark_pages_wc is used by hda_intel. This avoids needing to move that x86-specific code to a common area shared with hda platform drivers. Signed-off-by: Dylan Reid --- sound/pci/hda/hda_intel.c | 141 ++++++++++++++++++++++++++++------------------ sound/pci/hda/hda_priv.h | 11 ++++ 2 files changed, 98 insertions(+), 54 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ebbeefe..fa3a04c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -297,7 +297,10 @@ static char *driver_short_names[] = { }; /* for pcm support */ -#define get_azx_dev(substream) (substream->runtime->private_data) +static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream) +{ + return substream->runtime->private_data; +} #ifdef CONFIG_X86 static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) @@ -366,15 +369,11 @@ static int azx_alloc_cmd_io(struct azx *chip) int err; /* single page (at least 4096 bytes) must suffice for both ringbuffes */ - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - chip->card->dev, - PAGE_SIZE, &chip->rb); - if (err < 0) { + err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, + PAGE_SIZE, &chip->rb); + if (err < 0) dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); - return err; - } - mark_pages_wc(chip, &chip->rb, true); - return 0; + return err; } static void azx_init_cmd_io(struct azx *chip) @@ -1716,26 +1715,18 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, { struct azx_pcm *apcm = snd_pcm_substream_chip(substream); struct azx *chip = apcm->chip; - struct azx_dev *azx_dev = get_azx_dev(substream); int ret; - dsp_lock(azx_dev); - if (dsp_is_locked(azx_dev)) { + dsp_lock(get_azx_dev(substream)); + if (dsp_is_locked(get_azx_dev(substream))) { ret = -EBUSY; goto unlock; } - mark_runtime_wc(chip, azx_dev, substream, false); - azx_dev->bufsize = 0; - azx_dev->period_bytes = 0; - azx_dev->format_val = 0; - ret = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (ret < 0) - goto unlock; - mark_runtime_wc(chip, azx_dev, substream, true); - unlock: - dsp_unlock(azx_dev); + ret = chip->ops->substream_alloc_pages(chip, substream, + params_buffer_bytes(hw_params)); +unlock: + dsp_unlock(get_azx_dev(substream)); return ret; } @@ -1745,6 +1736,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) struct azx_dev *azx_dev = get_azx_dev(substream); struct azx *chip = apcm->chip; struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; + int err; /* reset BDL address */ dsp_lock(azx_dev); @@ -1759,10 +1751,10 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) snd_hda_codec_cleanup(apcm->codec, hinfo, substream); - mark_runtime_wc(chip, azx_dev, substream, false); + err = chip->ops->substream_free_pages(chip, substream); azx_dev->prepared = 0; dsp_unlock(azx_dev); - return snd_pcm_lib_free_pages(substream); + return err; } static int azx_pcm_prepare(struct snd_pcm_substream *substream) @@ -2398,13 +2390,11 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, azx_dev->locked = 1; spin_unlock_irq(&chip->reg_lock); - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, - chip->card->dev, - byte_size, bufp); + err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV_SG, + byte_size, bufp); if (err < 0) goto err_alloc; - mark_pages_wc(chip, bufp, true); azx_dev->bufsize = byte_size; azx_dev->period_bytes = byte_size; azx_dev->format_val = format; @@ -2426,8 +2416,7 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, return azx_dev->stream_tag; error: - mark_pages_wc(chip, bufp, false); - snd_dma_free_pages(bufp); + chip->ops->dma_free_pages(chip, bufp); err_alloc: spin_lock_irq(&chip->reg_lock); if (azx_dev->opened) @@ -2469,8 +2458,7 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus, azx_dev->period_bytes = 0; azx_dev->format_val = 0; - mark_pages_wc(chip, dmab, false); - snd_dma_free_pages(dmab); + chip->ops->dma_free_pages(chip, dmab); dmab->area = NULL; spin_lock_irq(&chip->reg_lock); @@ -2879,19 +2867,14 @@ static int azx_free(struct azx *chip) if (chip->azx_dev) { for (i = 0; i < chip->num_streams; i++) - if (chip->azx_dev[i].bdl.area) { - mark_pages_wc(chip, &chip->azx_dev[i].bdl, false); - snd_dma_free_pages(&chip->azx_dev[i].bdl); - } - } - if (chip->rb.area) { - mark_pages_wc(chip, &chip->rb, false); - snd_dma_free_pages(&chip->rb); - } - if (chip->posbuf.area) { - mark_pages_wc(chip, &chip->posbuf, false); - snd_dma_free_pages(&chip->posbuf); - } + if (chip->azx_dev[i].bdl.area) + chip->ops->dma_free_pages( + chip, &chip->azx_dev[i].bdl); + } + if (chip->rb.area) + chip->ops->dma_free_pages(chip, &chip->rb); + if (chip->posbuf.area) + chip->ops->dma_free_pages(chip, &chip->posbuf); if (chip->region_requested) pci_release_regions(chip->pci); pci_disable_device(chip->pci); @@ -3343,24 +3326,21 @@ static int azx_first_init(struct azx *chip) for (i = 0; i < chip->num_streams; i++) { dsp_lock_init(&chip->azx_dev[i]); /* allocate memory for the BDL for each stream */ - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - chip->card->dev, - BDL_SIZE, &chip->azx_dev[i].bdl); + err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, + BDL_SIZE, + &chip->azx_dev[i].bdl); if (err < 0) { dev_err(card->dev, "cannot allocate BDL\n"); return -ENOMEM; } - mark_pages_wc(chip, &chip->azx_dev[i].bdl, true); } /* allocate memory for the position buffer */ - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - chip->card->dev, - chip->num_streams * 8, &chip->posbuf); + err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, + chip->num_streams * 8, &chip->posbuf); if (err < 0) { dev_err(card->dev, "cannot allocate posbuf\n"); return -ENOMEM; } - mark_pages_wc(chip, &chip->posbuf, true); /* allocate CORB/RIRB */ err = azx_alloc_cmd_io(chip); if (err < 0) @@ -3479,6 +3459,55 @@ static int disable_msi_reset_irq(struct azx *chip) return 0; } +/* DMA page allocation helpers. */ +static int dma_alloc_pages(struct azx *chip, + int type, + size_t size, + struct snd_dma_buffer *buf) +{ + int err; + + err = snd_dma_alloc_pages(type, + chip->card->dev, + size, buf); + if (err < 0) + return err; + mark_pages_wc(chip, buf, true); + return 0; +} + +static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf) +{ + mark_pages_wc(chip, buf, false); + snd_dma_free_pages(buf); +} + +static int substream_alloc_pages(struct azx *chip, + struct snd_pcm_substream *substream, + size_t size) +{ + struct azx_dev *azx_dev = get_azx_dev(substream); + int ret; + + mark_runtime_wc(chip, azx_dev, substream, false); + azx_dev->bufsize = 0; + azx_dev->period_bytes = 0; + azx_dev->format_val = 0; + ret = snd_pcm_lib_malloc_pages(substream, size); + if (ret < 0) + return ret; + mark_runtime_wc(chip, azx_dev, substream, true); + return 0; +} + +static int substream_free_pages(struct azx *chip, + struct snd_pcm_substream *substream) +{ + struct azx_dev *azx_dev = get_azx_dev(substream); + mark_runtime_wc(chip, azx_dev, substream, false); + return snd_pcm_lib_free_pages(substream); +} + static const struct hda_controller_ops pci_hda_ops = { .writel = pci_azx_writel, .readl = pci_azx_readl, @@ -3487,6 +3516,10 @@ static const struct hda_controller_ops pci_hda_ops = { .writeb = pci_azx_writeb, .readb = pci_azx_readb, .disable_msi_reset_irq = disable_msi_reset_irq, + .dma_alloc_pages = dma_alloc_pages, + .dma_free_pages = dma_free_pages, + .substream_alloc_pages = substream_alloc_pages, + .substream_free_pages = substream_free_pages, }; static int azx_probe(struct pci_dev *pci, diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index 0a56e8e..10bcec1 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h @@ -298,6 +298,17 @@ struct hda_controller_ops { u8 (*readb)(u8 *addr); /* Disable msi if supported, PCI only */ int (*disable_msi_reset_irq)(struct azx *); + /* Allocation ops */ + int (*dma_alloc_pages)(struct azx *chip, + int type, + size_t size, + struct snd_dma_buffer *buf); + void (*dma_free_pages)(struct azx *chip, struct snd_dma_buffer *buf); + int (*substream_alloc_pages)(struct azx *chip, + struct snd_pcm_substream *substream, + size_t size); + int (*substream_free_pages)(struct azx *chip, + struct snd_pcm_substream *substream); }; struct azx_pcm {