Merge tag 'hda-codec-h-move' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ALSA: Move hda_codec.h to include/sound
For easier sharing with ASoC.
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 67561b9..af3fa57 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -47,10 +47,13 @@ struct snd_dma_device {
#define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */
#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
+#define SNDRV_DMA_TYPE_DEV_UC 5 /* continuous non-cahced */
#ifdef CONFIG_SND_DMA_SGBUF
#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
+#define SNDRV_DMA_TYPE_DEV_UC_SG 6 /* SG non-cached */
#else
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
+#define SNDRV_DMA_TYPE_DEV_UC_SG SNDRV_DMA_TYPE_DEV_UC
#endif
#ifdef CONFIG_GENERIC_ALLOCATOR
#define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 753d5fc..aa266907 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -25,6 +25,9 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/genalloc.h>
+#ifdef CONFIG_X86
+#include <asm/set_memory.h>
+#endif
#include <sound/memalloc.h>
/*
@@ -82,31 +85,32 @@ EXPORT_SYMBOL(snd_free_pages);
#ifdef CONFIG_HAS_DMA
/* allocate the coherent DMA pages */
-static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma)
+static void snd_malloc_dev_pages(struct snd_dma_buffer *dmab, size_t size)
{
- int pg;
gfp_t gfp_flags;
- if (WARN_ON(!dma))
- return NULL;
- pg = get_order(size);
gfp_flags = GFP_KERNEL
| __GFP_COMP /* compound page lets parts be mapped */
| __GFP_NORETRY /* don't trigger OOM-killer */
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
- return dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
+ dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr,
+ gfp_flags);
+#ifdef CONFIG_X86
+ if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
+ set_memory_wc((unsigned long)dmab->area,
+ PAGE_ALIGN(size) >> PAGE_SHIFT);
+#endif
}
/* free the coherent DMA pages */
-static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
- dma_addr_t dma)
+static void snd_free_dev_pages(struct snd_dma_buffer *dmab)
{
- int pg;
-
- if (ptr == NULL)
- return;
- pg = get_order(size);
- dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
+#ifdef CONFIG_X86
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
+ set_memory_wb((unsigned long)dmab->area,
+ PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT);
+#endif
+ dma_free_coherent(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
}
#ifdef CONFIG_GENERIC_ALLOCATOR
@@ -200,11 +204,13 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
dmab->dev.type = SNDRV_DMA_TYPE_DEV;
#endif /* CONFIG_GENERIC_ALLOCATOR */
case SNDRV_DMA_TYPE_DEV:
- dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
+ case SNDRV_DMA_TYPE_DEV_UC:
+ snd_malloc_dev_pages(dmab, size);
break;
#endif
#ifdef CONFIG_SND_DMA_SGBUF
case SNDRV_DMA_TYPE_DEV_SG:
+ case SNDRV_DMA_TYPE_DEV_UC_SG:
snd_malloc_sgbuf_pages(device, size, dmab, NULL);
break;
#endif
@@ -275,11 +281,13 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
break;
#endif /* CONFIG_GENERIC_ALLOCATOR */
case SNDRV_DMA_TYPE_DEV:
- snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
+ case SNDRV_DMA_TYPE_DEV_UC:
+ snd_free_dev_pages(dmab);
break;
#endif
#ifdef CONFIG_SND_DMA_SGBUF
case SNDRV_DMA_TYPE_DEV_SG:
+ case SNDRV_DMA_TYPE_DEV_UC_SG:
snd_free_sgbuf_pages(dmab);
break;
#endif
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 0391cb1..141c5f3 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -111,7 +111,7 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
while (plugin->next) {
if (plugin->dst_frames)
frames = plugin->dst_frames(plugin, frames);
- if (snd_BUG_ON(frames <= 0))
+ if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0))
return -ENXIO;
plugin = plugin->next;
err = snd_pcm_plugin_alloc(plugin, frames);
@@ -123,7 +123,7 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
while (plugin->prev) {
if (plugin->src_frames)
frames = plugin->src_frames(plugin, frames);
- if (snd_BUG_ON(frames <= 0))
+ if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0))
return -ENXIO;
plugin = plugin->prev;
err = snd_pcm_plugin_alloc(plugin, frames);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 4e6110d..7f71c24 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -2173,11 +2173,16 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
goto _end_unlock;
if (!is_playback &&
- runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
- size >= runtime->start_threshold) {
- err = snd_pcm_start(substream);
- if (err < 0)
+ runtime->status->state == SNDRV_PCM_STATE_PREPARED) {
+ if (size >= runtime->start_threshold) {
+ err = snd_pcm_start(substream);
+ if (err < 0)
+ goto _end_unlock;
+ } else {
+ /* nothing to do */
+ err = 0;
goto _end_unlock;
+ }
}
runtime->twake = runtime->control->avail_min ? : 1;
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index 8ce1d0b..0dc5d5a 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -123,6 +123,7 @@ int __init snd_seq_system_client_init(void)
{
struct snd_seq_port_callback pcallbacks;
struct snd_seq_port_info *port;
+ int err;
port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
@@ -134,6 +135,10 @@ int __init snd_seq_system_client_init(void)
/* register client */
sysclient = snd_seq_create_kernel_client(NULL, 0, "System");
+ if (sysclient < 0) {
+ kfree(port);
+ return sysclient;
+ }
/* register timer */
strcpy(port->name, "Timer");
@@ -144,7 +149,10 @@ int __init snd_seq_system_client_init(void)
port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
port->addr.client = sysclient;
port->addr.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
- snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+ err = snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT,
+ port);
+ if (err < 0)
+ goto error_port;
/* register announcement port */
strcpy(port->name, "Announce");
@@ -154,16 +162,24 @@ int __init snd_seq_system_client_init(void)
port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
port->addr.client = sysclient;
port->addr.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
- snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+ err = snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT,
+ port);
+ if (err < 0)
+ goto error_port;
announce_port = port->addr.port;
kfree(port);
return 0;
+
+ error_port:
+ snd_seq_system_client_done();
+ kfree(port);
+ return err;
}
/* unregister our internal client */
-void __exit snd_seq_system_client_done(void)
+void snd_seq_system_client_done(void)
{
int oldsysclient = sysclient;
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index 84fffab..c1cfaa0 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -23,6 +23,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
+#include <asm/pgtable.h>
#include <sound/memalloc.h>
@@ -43,6 +44,8 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
dmab->area = NULL;
tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG)
+ tmpb.dev.type = SNDRV_DMA_TYPE_DEV_UC;
tmpb.dev.dev = sgbuf->dev;
for (i = 0; i < sgbuf->pages; i++) {
if (!(sgbuf->table[i].addr & ~PAGE_MASK))
@@ -72,12 +75,20 @@ void *snd_malloc_sgbuf_pages(struct device *device,
struct snd_dma_buffer tmpb;
struct snd_sg_page *table;
struct page **pgtable;
+ int type = SNDRV_DMA_TYPE_DEV;
+ pgprot_t prot = PAGE_KERNEL;
dmab->area = NULL;
dmab->addr = 0;
dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
if (! sgbuf)
return NULL;
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG) {
+ type = SNDRV_DMA_TYPE_DEV_UC;
+#ifdef pgprot_noncached
+ prot = pgprot_noncached(PAGE_KERNEL);
+#endif
+ }
sgbuf->dev = device;
pages = snd_sgbuf_aligned_pages(size);
sgbuf->tblsize = sgbuf_align_table(pages);
@@ -98,7 +109,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
if (chunk > maxpages)
chunk = maxpages;
chunk <<= PAGE_SHIFT;
- if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
+ if (snd_dma_alloc_pages_fallback(type, device,
chunk, &tmpb) < 0) {
if (!sgbuf->pages)
goto _failed;
@@ -125,7 +136,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
}
sgbuf->size = size;
- dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
+ dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
if (! dmab->area)
goto _failed;
if (res_size)
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index a12e594..fe25066 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -130,8 +130,9 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
azx_dev->core.bufsize = 0;
azx_dev->core.period_bytes = 0;
azx_dev->core.format_val = 0;
- ret = chip->ops->substream_alloc_pages(chip, substream,
- params_buffer_bytes(hw_params));
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+
unlock:
dsp_unlock(azx_dev);
return ret;
@@ -141,7 +142,6 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
struct azx_dev *azx_dev = get_azx_dev(substream);
- struct azx *chip = apcm->chip;
struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
int err;
@@ -152,7 +152,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
- err = chip->ops->substream_free_pages(chip, substream);
+ err = snd_pcm_lib_free_pages(substream);
azx_stream(azx_dev)->prepared = 0;
dsp_unlock(azx_dev);
return err;
@@ -732,6 +732,7 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
int pcm_dev = cpcm->device;
unsigned int size;
int s, err;
+ int type = SNDRV_DMA_TYPE_DEV_SG;
list_for_each_entry(apcm, &chip->pcm_list, list) {
if (apcm->pcm->device == pcm_dev) {
@@ -770,7 +771,9 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
if (size > MAX_PREALLOC_SIZE)
size = MAX_PREALLOC_SIZE;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ if (chip->uc_buffer)
+ type = SNDRV_DMA_TYPE_DEV_UC_SG;
+ snd_pcm_lib_preallocate_pages_for_all(pcm, type,
chip->card->dev,
size, MAX_PREALLOC_SIZE);
return 0;
@@ -1220,27 +1223,6 @@ void snd_hda_bus_reset(struct hda_bus *bus)
bus->in_reset = 0;
}
-static int get_jackpoll_interval(struct azx *chip)
-{
- int i;
- unsigned int j;
-
- if (!chip->jackpoll_ms)
- return 0;
-
- i = chip->jackpoll_ms[chip->dev_index];
- if (i == 0)
- return 0;
- if (i < 50 || i > 60000)
- j = 0;
- else
- j = msecs_to_jiffies(i);
- if (j == 0)
- dev_warn(chip->card->dev,
- "jackpoll_ms value out of range: %d\n", i);
- return j;
-}
-
/* HD-audio bus initialization */
int azx_bus_init(struct azx *chip, const char *model,
const struct hdac_io_ops *io_ops)
@@ -1323,7 +1305,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
err = snd_hda_codec_new(&chip->bus, chip->card, c, &codec);
if (err < 0)
continue;
- codec->jackpoll_interval = get_jackpoll_interval(chip);
+ codec->jackpoll_interval = chip->jackpoll_interval;
codec->beep_mode = chip->beep_mode;
codecs++;
}
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index 55760e5..0053b70 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -76,7 +76,6 @@ struct azx_dev {
* when link position is not greater than FIFO size
*/
unsigned int insufficient:1;
- unsigned int wc_marked:1;
};
#define azx_stream(dev) (&(dev)->core)
@@ -88,11 +87,6 @@ struct azx;
struct hda_controller_ops {
/* Disable msi if supported, PCI only */
int (*disable_msi_reset_irq)(struct azx *);
- 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);
void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream,
struct vm_area_struct *area);
/* Check if current position is acceptable */
@@ -127,7 +121,7 @@ struct azx {
int capture_streams;
int capture_index_offset;
int num_streams;
- const int *jackpoll_ms; /* per-card jack poll interval */
+ int jackpoll_interval; /* jack poll interval in jiffies */
/* Register interaction. */
const struct hda_controller_ops *ops;
@@ -160,6 +154,7 @@ struct azx {
unsigned int msi:1;
unsigned int probing:1; /* codec probing phase */
unsigned int snoop:1;
+ unsigned int uc_buffer:1; /* non-cached pages for stream buffers */
unsigned int align_buffer_size:1;
unsigned int region_requested:1;
unsigned int disabled:1; /* disabled by vga_switcheroo */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c8fde95..4e64595 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -397,61 +397,6 @@ static char *driver_short_names[] = {
[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
};
-#ifdef CONFIG_X86
-static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
-{
- int pages;
-
- if (azx_snoop(chip))
- return;
- if (!dmab || !dmab->area || !dmab->bytes)
- return;
-
-#ifdef CONFIG_SND_DMA_SGBUF
- if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
- struct snd_sg_buf *sgbuf = dmab->private_data;
- if (chip->driver_type == AZX_DRIVER_CMEDIA)
- return; /* deal with only CORB/RIRB buffers */
- if (on)
- set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
- else
- set_pages_array_wb(sgbuf->page_table, sgbuf->pages);
- return;
- }
-#endif
-
- pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (on)
- set_memory_wc((unsigned long)dmab->area, pages);
- else
- set_memory_wb((unsigned long)dmab->area, pages);
-}
-
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
- bool on)
-{
- __mark_pages_wc(chip, buf, on);
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
- struct snd_pcm_substream *substream, bool on)
-{
- if (azx_dev->wc_marked != on) {
- __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on);
- azx_dev->wc_marked = on;
- }
-}
-#else
-/* NOP for other archs */
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
- bool on)
-{
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
- struct snd_pcm_substream *substream, bool on)
-{
-}
-#endif
-
static int azx_acquire_irq(struct azx *chip, int do_disconnect);
/*
@@ -1637,6 +1582,7 @@ static void azx_check_snoop_available(struct azx *chip)
dev_info(chip->card->dev, "Force to %s mode by module option\n",
snoop ? "snoop" : "non-snoop");
chip->snoop = snoop;
+ chip->uc_buffer = !snoop;
return;
}
@@ -1657,8 +1603,12 @@ static void azx_check_snoop_available(struct azx *chip)
snoop = false;
chip->snoop = snoop;
- if (!snoop)
+ if (!snoop) {
dev_info(chip->card->dev, "Force to non-snoop mode\n");
+ /* C-Media requires non-cached pages only for CORB/RIRB */
+ if (chip->driver_type != AZX_DRIVER_CMEDIA)
+ chip->uc_buffer = true;
+ }
}
static void azx_probe_work(struct work_struct *work)
@@ -1726,7 +1676,8 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
chip->driver_type = driver_caps & 0xff;
check_msi(chip);
chip->dev_index = dev;
- chip->jackpoll_ms = jackpoll_ms;
+ if (jackpoll_ms[dev] >= 50 && jackpoll_ms[dev] <= 60000)
+ chip->jackpoll_interval = msecs_to_jiffies(jackpoll_ms[dev]);
INIT_LIST_HEAD(&chip->pcm_list);
INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
INIT_LIST_HEAD(&hda->list);
@@ -2049,55 +2000,24 @@ static int dma_alloc_pages(struct hdac_bus *bus,
struct snd_dma_buffer *buf)
{
struct azx *chip = bus_to_azx(bus);
- int err;
- err = snd_dma_alloc_pages(type,
- bus->dev,
- size, buf);
- if (err < 0)
- return err;
- mark_pages_wc(chip, buf, true);
- return 0;
+ if (!azx_snoop(chip) && type == SNDRV_DMA_TYPE_DEV)
+ type = SNDRV_DMA_TYPE_DEV_UC;
+ return snd_dma_alloc_pages(type, bus->dev, size, buf);
}
static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
{
- struct azx *chip = bus_to_azx(bus);
-
- 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);
- 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 void pcm_mmap_prepare(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
#ifdef CONFIG_X86
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
struct azx *chip = apcm->chip;
- if (!azx_snoop(chip) && chip->driver_type != AZX_DRIVER_CMEDIA)
+ if (chip->uc_buffer)
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
#endif
}
@@ -2115,8 +2035,6 @@ static const struct hdac_io_ops pci_hda_io_ops = {
static const struct hda_controller_ops pci_hda_ops = {
.disable_msi_reset_irq = disable_msi_reset_irq,
- .substream_alloc_pages = substream_alloc_pages,
- .substream_free_pages = substream_free_pages,
.pcm_mmap_prepare = pcm_mmap_prepare,
.position_check = azx_position_check,
.link_power = azx_intel_link_power,
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 4bc5232..dd7d424 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -99,19 +99,6 @@ static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
snd_dma_free_pages(buf);
}
-static int substream_alloc_pages(struct azx *chip,
- struct snd_pcm_substream *substream,
- size_t size)
-{
- return snd_pcm_lib_malloc_pages(substream, size);
-}
-
-static int substream_free_pages(struct azx *chip,
- struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
/*
* Register access ops. Tegra HDA register access is DWORD only.
*/
@@ -180,10 +167,7 @@ static const struct hdac_io_ops hda_tegra_io_ops = {
.dma_free_pages = dma_free_pages,
};
-static const struct hda_controller_ops hda_tegra_ops = {
- .substream_alloc_pages = substream_alloc_pages,
- .substream_free_pages = substream_free_pages,
-};
+static const struct hda_controller_ops hda_tegra_ops; /* nothing special */
static void hda_tegra_init(struct hda_tegra *hda)
{
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 5ee468d..9517f9b 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -38,11 +38,6 @@
#include <sound/ac97_codec.h>
#include <sound/info.h>
#include <sound/initval.h>
-/* for 440MX workaround */
-#include <asm/pgtable.h>
-#ifdef CONFIG_X86
-#include <asm/set_memory.h>
-#endif
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
@@ -374,7 +369,6 @@ struct ichdev {
unsigned int ali_slot; /* ALI DMA slot */
struct ac97_pcm *pcm;
int pcm_open_flag;
- unsigned int page_attr_changed: 1;
unsigned int suspended: 1;
};
@@ -724,25 +718,6 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich
iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
}
-#ifdef __i386__
-/*
- * Intel 82443MX running a 100MHz processor system bus has a hardware bug,
- * which aborts PCI busmaster for audio transfer. A workaround is to set
- * the pages as non-cached. For details, see the errata in
- * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
- */
-static void fill_nocache(void *buf, int size, int nocache)
-{
- size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (nocache)
- set_pages_uc(virt_to_page(buf), size);
- else
- set_pages_wb(virt_to_page(buf), size);
-}
-#else
-#define fill_nocache(buf, size, nocache) do { ; } while (0)
-#endif
-
/*
* Interrupt handler
*/
@@ -938,23 +913,12 @@ static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
{
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
struct ichdev *ichdev = get_ichdev(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
int dbl = params_rate(hw_params) > 48000;
int err;
- if (chip->fix_nocache && ichdev->page_attr_changed) {
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
- ichdev->page_attr_changed = 0;
- }
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
if (err < 0)
return err;
- if (chip->fix_nocache) {
- if (runtime->dma_area && ! ichdev->page_attr_changed) {
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
- ichdev->page_attr_changed = 1;
- }
- }
if (ichdev->pcm_open_flag) {
snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0;
@@ -974,17 +938,12 @@ static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream)
{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
struct ichdev *ichdev = get_ichdev(substream);
if (ichdev->pcm_open_flag) {
snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0;
}
- if (chip->fix_nocache && ichdev->page_attr_changed) {
- fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
- ichdev->page_attr_changed = 0;
- }
return snd_pcm_lib_free_pages(substream);
}
@@ -1510,6 +1469,9 @@ struct ich_pcm_table {
int ac97_idx;
};
+#define intel8x0_dma_type(chip) \
+ ((chip)->fix_nocache ? SNDRV_DMA_TYPE_DEV_UC : SNDRV_DMA_TYPE_DEV)
+
static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
struct ich_pcm_table *rec)
{
@@ -1540,7 +1502,7 @@ static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
strcpy(pcm->name, chip->card->shortname);
chip->pcm[device] = pcm;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_pcm_lib_preallocate_pages_for_all(pcm, intel8x0_dma_type(chip),
snd_dma_pci_data(chip->pci),
rec->prealloc_size, rec->prealloc_max_size);
@@ -2629,11 +2591,8 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
__hw_end:
if (chip->irq >= 0)
free_irq(chip->irq, chip);
- if (chip->bdbars.area) {
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
+ if (chip->bdbars.area)
snd_dma_free_pages(&chip->bdbars);
- }
if (chip->addr)
pci_iounmap(chip->pci, chip->addr);
if (chip->bmaddr)
@@ -2657,17 +2616,6 @@ static int intel8x0_suspend(struct device *dev)
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
for (i = 0; i < chip->pcm_devs; i++)
snd_pcm_suspend_all(chip->pcm[i]);
- /* clear nocache */
- if (chip->fix_nocache) {
- for (i = 0; i < chip->bdbars_count; i++) {
- struct ichdev *ichdev = &chip->ichd[i];
- if (ichdev->substream && ichdev->page_attr_changed) {
- struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
- if (runtime->dma_area)
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
- }
- }
- }
for (i = 0; i < chip->ncodecs; i++)
snd_ac97_suspend(chip->ac97[i]);
if (chip->device_type == DEVICE_INTEL_ICH4)
@@ -2708,25 +2656,9 @@ static int intel8x0_resume(struct device *dev)
ICH_PCM_SPDIF_1011);
}
- /* refill nocache */
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
-
for (i = 0; i < chip->ncodecs; i++)
snd_ac97_resume(chip->ac97[i]);
- /* refill nocache */
- if (chip->fix_nocache) {
- for (i = 0; i < chip->bdbars_count; i++) {
- struct ichdev *ichdev = &chip->ichd[i];
- if (ichdev->substream && ichdev->page_attr_changed) {
- struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
- if (runtime->dma_area)
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
- }
- }
- }
-
/* resume status */
for (i = 0; i < chip->bdbars_count; i++) {
struct ichdev *ichdev = &chip->ichd[i];
@@ -3057,6 +2989,12 @@ static int snd_intel8x0_create(struct snd_card *card,
chip->inside_vm = snd_intel8x0_inside_vm(pci);
+ /*
+ * Intel 82443MX running a 100MHz processor system bus has a hardware
+ * bug, which aborts PCI busmaster for audio transfer. A workaround
+ * is to set the pages as non-cached. For details, see the errata in
+ * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
+ */
if (pci->vendor == PCI_VENDOR_ID_INTEL &&
pci->device == PCI_DEVICE_ID_INTEL_440MX)
chip->fix_nocache = 1; /* enable workaround */
@@ -3128,7 +3066,7 @@ static int snd_intel8x0_create(struct snd_card *card,
/* allocate buffer descriptor lists */
/* the start of each lists must be aligned to 8 bytes */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+ if (snd_dma_alloc_pages(intel8x0_dma_type(chip), snd_dma_pci_data(pci),
chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
&chip->bdbars) < 0) {
snd_intel8x0_free(chip);
@@ -3137,9 +3075,6 @@ static int snd_intel8x0_create(struct snd_card *card,
}
/* tables must be aligned to 8 bytes here, but the kernel pages
are much bigger, so we don't care (on i386) */
- /* workaround for 440MX */
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
int_sta_masks = 0;
for (i = 0; i < chip->bdbars_count; i++) {
ichdev = &chip->ichd[i];
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 11b5b5e0..679ad04 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6534,7 +6534,7 @@ static int snd_hdspm_create_alsa_devices(struct snd_card *card,
dev_dbg(card->dev, "Update mixer controls...\n");
hdspm_update_simple_mixer_controls(hdspm);
- dev_dbg(card->dev, "Initializeing complete ???\n");
+ dev_dbg(card->dev, "Initializing complete?\n");
err = snd_card_register(card);
if (err < 0) {
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index fa7dca5..83d76c3 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -30,7 +30,6 @@
#include <linux/pm_runtime.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <asm/set_memory.h>
#include <sound/core.h>
#include <sound/asoundef.h>
#include <sound/pcm.h>
@@ -1141,8 +1140,7 @@ static int had_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_intelhad *intelhaddata;
- unsigned long addr;
- int pages, buf_size, retval;
+ int buf_size, retval;
intelhaddata = snd_pcm_substream_chip(substream);
buf_size = params_buffer_bytes(hw_params);
@@ -1151,17 +1149,6 @@ static int had_pcm_hw_params(struct snd_pcm_substream *substream,
return retval;
dev_dbg(intelhaddata->dev, "%s:allocated memory = %d\n",
__func__, buf_size);
- /* mark the pages as uncached region */
- addr = (unsigned long) substream->runtime->dma_area;
- pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
- retval = set_memory_uc(addr, pages);
- if (retval) {
- dev_err(intelhaddata->dev, "set_memory_uc failed.Error:%d\n",
- retval);
- return retval;
- }
- memset(substream->runtime->dma_area, 0, buf_size);
-
return retval;
}
@@ -1171,21 +1158,11 @@ static int had_pcm_hw_params(struct snd_pcm_substream *substream,
static int had_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_intelhad *intelhaddata;
- unsigned long addr;
- u32 pages;
intelhaddata = snd_pcm_substream_chip(substream);
had_do_reset(intelhaddata);
- /* mark back the pages as cached/writeback region before the free */
- if (substream->runtime->dma_area != NULL) {
- addr = (unsigned long) substream->runtime->dma_area;
- pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) /
- PAGE_SIZE;
- set_memory_wb(addr, pages);
- return snd_pcm_lib_free_pages(substream);
- }
- return 0;
+ return snd_pcm_lib_free_pages(substream);
}
/*
@@ -1860,7 +1837,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
* try to allocate 600k buffer as default which is large enough
*/
snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV, NULL,
+ SNDRV_DMA_TYPE_DEV_UC, NULL,
HAD_DEFAULT_BUFFER, HAD_MAX_BUFFER);
/* create controls */