cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hdac_controller.c (17383B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * HD-audio controller helpers
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/delay.h>
      8#include <linux/export.h>
      9#include <sound/core.h>
     10#include <sound/hdaudio.h>
     11#include <sound/hda_register.h>
     12#include "local.h"
     13
     14/* clear CORB read pointer properly */
     15static void azx_clear_corbrp(struct hdac_bus *bus)
     16{
     17	int timeout;
     18
     19	for (timeout = 1000; timeout > 0; timeout--) {
     20		if (snd_hdac_chip_readw(bus, CORBRP) & AZX_CORBRP_RST)
     21			break;
     22		udelay(1);
     23	}
     24	if (timeout <= 0)
     25		dev_err(bus->dev, "CORB reset timeout#1, CORBRP = %d\n",
     26			snd_hdac_chip_readw(bus, CORBRP));
     27
     28	snd_hdac_chip_writew(bus, CORBRP, 0);
     29	for (timeout = 1000; timeout > 0; timeout--) {
     30		if (snd_hdac_chip_readw(bus, CORBRP) == 0)
     31			break;
     32		udelay(1);
     33	}
     34	if (timeout <= 0)
     35		dev_err(bus->dev, "CORB reset timeout#2, CORBRP = %d\n",
     36			snd_hdac_chip_readw(bus, CORBRP));
     37}
     38
     39/**
     40 * snd_hdac_bus_init_cmd_io - set up CORB/RIRB buffers
     41 * @bus: HD-audio core bus
     42 */
     43void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
     44{
     45	WARN_ON_ONCE(!bus->rb.area);
     46
     47	spin_lock_irq(&bus->reg_lock);
     48	/* CORB set up */
     49	bus->corb.addr = bus->rb.addr;
     50	bus->corb.buf = (__le32 *)bus->rb.area;
     51	snd_hdac_chip_writel(bus, CORBLBASE, (u32)bus->corb.addr);
     52	snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr));
     53
     54	/* set the corb size to 256 entries (ULI requires explicitly) */
     55	snd_hdac_chip_writeb(bus, CORBSIZE, 0x02);
     56	/* set the corb write pointer to 0 */
     57	snd_hdac_chip_writew(bus, CORBWP, 0);
     58
     59	/* reset the corb hw read pointer */
     60	snd_hdac_chip_writew(bus, CORBRP, AZX_CORBRP_RST);
     61	if (!bus->corbrp_self_clear)
     62		azx_clear_corbrp(bus);
     63
     64	/* enable corb dma */
     65	snd_hdac_chip_writeb(bus, CORBCTL, AZX_CORBCTL_RUN);
     66
     67	/* RIRB set up */
     68	bus->rirb.addr = bus->rb.addr + 2048;
     69	bus->rirb.buf = (__le32 *)(bus->rb.area + 2048);
     70	bus->rirb.wp = bus->rirb.rp = 0;
     71	memset(bus->rirb.cmds, 0, sizeof(bus->rirb.cmds));
     72	snd_hdac_chip_writel(bus, RIRBLBASE, (u32)bus->rirb.addr);
     73	snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr));
     74
     75	/* set the rirb size to 256 entries (ULI requires explicitly) */
     76	snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02);
     77	/* reset the rirb hw write pointer */
     78	snd_hdac_chip_writew(bus, RIRBWP, AZX_RIRBWP_RST);
     79	/* set N=1, get RIRB response interrupt for new entry */
     80	snd_hdac_chip_writew(bus, RINTCNT, 1);
     81	/* enable rirb dma and response irq */
     82	snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
     83	/* Accept unsolicited responses */
     84	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
     85	spin_unlock_irq(&bus->reg_lock);
     86}
     87EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
     88
     89/* wait for cmd dmas till they are stopped */
     90static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus)
     91{
     92	unsigned long timeout;
     93
     94	timeout = jiffies + msecs_to_jiffies(100);
     95	while ((snd_hdac_chip_readb(bus, RIRBCTL) & AZX_RBCTL_DMA_EN)
     96		&& time_before(jiffies, timeout))
     97		udelay(10);
     98
     99	timeout = jiffies + msecs_to_jiffies(100);
    100	while ((snd_hdac_chip_readb(bus, CORBCTL) & AZX_CORBCTL_RUN)
    101		&& time_before(jiffies, timeout))
    102		udelay(10);
    103}
    104
    105/**
    106 * snd_hdac_bus_stop_cmd_io - clean up CORB/RIRB buffers
    107 * @bus: HD-audio core bus
    108 */
    109void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus)
    110{
    111	spin_lock_irq(&bus->reg_lock);
    112	/* disable ringbuffer DMAs */
    113	snd_hdac_chip_writeb(bus, RIRBCTL, 0);
    114	snd_hdac_chip_writeb(bus, CORBCTL, 0);
    115	spin_unlock_irq(&bus->reg_lock);
    116
    117	hdac_wait_for_cmd_dmas(bus);
    118
    119	spin_lock_irq(&bus->reg_lock);
    120	/* disable unsolicited responses */
    121	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0);
    122	spin_unlock_irq(&bus->reg_lock);
    123}
    124EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_cmd_io);
    125
    126static unsigned int azx_command_addr(u32 cmd)
    127{
    128	unsigned int addr = cmd >> 28;
    129
    130	if (snd_BUG_ON(addr >= HDA_MAX_CODECS))
    131		addr = 0;
    132	return addr;
    133}
    134
    135/**
    136 * snd_hdac_bus_send_cmd - send a command verb via CORB
    137 * @bus: HD-audio core bus
    138 * @val: encoded verb value to send
    139 *
    140 * Returns zero for success or a negative error code.
    141 */
    142int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
    143{
    144	unsigned int addr = azx_command_addr(val);
    145	unsigned int wp, rp;
    146
    147	spin_lock_irq(&bus->reg_lock);
    148
    149	bus->last_cmd[azx_command_addr(val)] = val;
    150
    151	/* add command to corb */
    152	wp = snd_hdac_chip_readw(bus, CORBWP);
    153	if (wp == 0xffff) {
    154		/* something wrong, controller likely turned to D3 */
    155		spin_unlock_irq(&bus->reg_lock);
    156		return -EIO;
    157	}
    158	wp++;
    159	wp %= AZX_MAX_CORB_ENTRIES;
    160
    161	rp = snd_hdac_chip_readw(bus, CORBRP);
    162	if (wp == rp) {
    163		/* oops, it's full */
    164		spin_unlock_irq(&bus->reg_lock);
    165		return -EAGAIN;
    166	}
    167
    168	bus->rirb.cmds[addr]++;
    169	bus->corb.buf[wp] = cpu_to_le32(val);
    170	snd_hdac_chip_writew(bus, CORBWP, wp);
    171
    172	spin_unlock_irq(&bus->reg_lock);
    173
    174	return 0;
    175}
    176EXPORT_SYMBOL_GPL(snd_hdac_bus_send_cmd);
    177
    178#define AZX_RIRB_EX_UNSOL_EV	(1<<4)
    179
    180/**
    181 * snd_hdac_bus_update_rirb - retrieve RIRB entries
    182 * @bus: HD-audio core bus
    183 *
    184 * Usually called from interrupt handler.
    185 * The caller needs bus->reg_lock spinlock before calling this.
    186 */
    187void snd_hdac_bus_update_rirb(struct hdac_bus *bus)
    188{
    189	unsigned int rp, wp;
    190	unsigned int addr;
    191	u32 res, res_ex;
    192
    193	wp = snd_hdac_chip_readw(bus, RIRBWP);
    194	if (wp == 0xffff) {
    195		/* something wrong, controller likely turned to D3 */
    196		return;
    197	}
    198
    199	if (wp == bus->rirb.wp)
    200		return;
    201	bus->rirb.wp = wp;
    202
    203	while (bus->rirb.rp != wp) {
    204		bus->rirb.rp++;
    205		bus->rirb.rp %= AZX_MAX_RIRB_ENTRIES;
    206
    207		rp = bus->rirb.rp << 1; /* an RIRB entry is 8-bytes */
    208		res_ex = le32_to_cpu(bus->rirb.buf[rp + 1]);
    209		res = le32_to_cpu(bus->rirb.buf[rp]);
    210		addr = res_ex & 0xf;
    211		if (addr >= HDA_MAX_CODECS) {
    212			dev_err(bus->dev,
    213				"spurious response %#x:%#x, rp = %d, wp = %d",
    214				res, res_ex, bus->rirb.rp, wp);
    215			snd_BUG();
    216		} else if (res_ex & AZX_RIRB_EX_UNSOL_EV)
    217			snd_hdac_bus_queue_event(bus, res, res_ex);
    218		else if (bus->rirb.cmds[addr]) {
    219			bus->rirb.res[addr] = res;
    220			bus->rirb.cmds[addr]--;
    221			if (!bus->rirb.cmds[addr] &&
    222			    waitqueue_active(&bus->rirb_wq))
    223				wake_up(&bus->rirb_wq);
    224		} else {
    225			dev_err_ratelimited(bus->dev,
    226				"spurious response %#x:%#x, last cmd=%#08x\n",
    227				res, res_ex, bus->last_cmd[addr]);
    228		}
    229	}
    230}
    231EXPORT_SYMBOL_GPL(snd_hdac_bus_update_rirb);
    232
    233/**
    234 * snd_hdac_bus_get_response - receive a response via RIRB
    235 * @bus: HD-audio core bus
    236 * @addr: codec address
    237 * @res: pointer to store the value, NULL when not needed
    238 *
    239 * Returns zero if a value is read, or a negative error code.
    240 */
    241int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
    242			      unsigned int *res)
    243{
    244	unsigned long timeout;
    245	unsigned long loopcounter;
    246	wait_queue_entry_t wait;
    247	bool warned = false;
    248
    249	init_wait_entry(&wait, 0);
    250	timeout = jiffies + msecs_to_jiffies(1000);
    251
    252	for (loopcounter = 0;; loopcounter++) {
    253		spin_lock_irq(&bus->reg_lock);
    254		if (!bus->polling_mode)
    255			prepare_to_wait(&bus->rirb_wq, &wait,
    256					TASK_UNINTERRUPTIBLE);
    257		if (bus->polling_mode)
    258			snd_hdac_bus_update_rirb(bus);
    259		if (!bus->rirb.cmds[addr]) {
    260			if (res)
    261				*res = bus->rirb.res[addr]; /* the last value */
    262			if (!bus->polling_mode)
    263				finish_wait(&bus->rirb_wq, &wait);
    264			spin_unlock_irq(&bus->reg_lock);
    265			return 0;
    266		}
    267		spin_unlock_irq(&bus->reg_lock);
    268		if (time_after(jiffies, timeout))
    269			break;
    270#define LOOP_COUNT_MAX	3000
    271		if (!bus->polling_mode) {
    272			schedule_timeout(msecs_to_jiffies(2));
    273		} else if (bus->needs_damn_long_delay ||
    274			   loopcounter > LOOP_COUNT_MAX) {
    275			if (loopcounter > LOOP_COUNT_MAX && !warned) {
    276				dev_dbg_ratelimited(bus->dev,
    277						    "too slow response, last cmd=%#08x\n",
    278						    bus->last_cmd[addr]);
    279				warned = true;
    280			}
    281			msleep(2); /* temporary workaround */
    282		} else {
    283			udelay(10);
    284			cond_resched();
    285		}
    286	}
    287
    288	if (!bus->polling_mode)
    289		finish_wait(&bus->rirb_wq, &wait);
    290
    291	return -EIO;
    292}
    293EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
    294
    295#define HDAC_MAX_CAPS 10
    296/**
    297 * snd_hdac_bus_parse_capabilities - parse capability structure
    298 * @bus: the pointer to bus object
    299 *
    300 * Returns 0 if successful, or a negative error code.
    301 */
    302int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
    303{
    304	unsigned int cur_cap;
    305	unsigned int offset;
    306	unsigned int counter = 0;
    307
    308	offset = snd_hdac_chip_readw(bus, LLCH);
    309
    310	/* Lets walk the linked capabilities list */
    311	do {
    312		cur_cap = _snd_hdac_chip_readl(bus, offset);
    313
    314		dev_dbg(bus->dev, "Capability version: 0x%x\n",
    315			(cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
    316
    317		dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
    318			(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
    319
    320		if (cur_cap == -1) {
    321			dev_dbg(bus->dev, "Invalid capability reg read\n");
    322			break;
    323		}
    324
    325		switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
    326		case AZX_ML_CAP_ID:
    327			dev_dbg(bus->dev, "Found ML capability\n");
    328			bus->mlcap = bus->remap_addr + offset;
    329			break;
    330
    331		case AZX_GTS_CAP_ID:
    332			dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
    333			bus->gtscap = bus->remap_addr + offset;
    334			break;
    335
    336		case AZX_PP_CAP_ID:
    337			/* PP capability found, the Audio DSP is present */
    338			dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
    339			bus->ppcap = bus->remap_addr + offset;
    340			break;
    341
    342		case AZX_SPB_CAP_ID:
    343			/* SPIB capability found, handler function */
    344			dev_dbg(bus->dev, "Found SPB capability\n");
    345			bus->spbcap = bus->remap_addr + offset;
    346			break;
    347
    348		case AZX_DRSM_CAP_ID:
    349			/* DMA resume  capability found, handler function */
    350			dev_dbg(bus->dev, "Found DRSM capability\n");
    351			bus->drsmcap = bus->remap_addr + offset;
    352			break;
    353
    354		default:
    355			dev_err(bus->dev, "Unknown capability %d\n", cur_cap);
    356			cur_cap = 0;
    357			break;
    358		}
    359
    360		counter++;
    361
    362		if (counter > HDAC_MAX_CAPS) {
    363			dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
    364			break;
    365		}
    366
    367		/* read the offset of next capability */
    368		offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
    369
    370	} while (offset);
    371
    372	return 0;
    373}
    374EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
    375
    376/*
    377 * Lowlevel interface
    378 */
    379
    380/**
    381 * snd_hdac_bus_enter_link_reset - enter link reset
    382 * @bus: HD-audio core bus
    383 *
    384 * Enter to the link reset state.
    385 */
    386void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus)
    387{
    388	unsigned long timeout;
    389
    390	/* reset controller */
    391	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, 0);
    392
    393	timeout = jiffies + msecs_to_jiffies(100);
    394	while ((snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET) &&
    395	       time_before(jiffies, timeout))
    396		usleep_range(500, 1000);
    397}
    398EXPORT_SYMBOL_GPL(snd_hdac_bus_enter_link_reset);
    399
    400/**
    401 * snd_hdac_bus_exit_link_reset - exit link reset
    402 * @bus: HD-audio core bus
    403 *
    404 * Exit from the link reset state.
    405 */
    406void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
    407{
    408	unsigned long timeout;
    409
    410	snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
    411
    412	timeout = jiffies + msecs_to_jiffies(100);
    413	while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout))
    414		usleep_range(500, 1000);
    415}
    416EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);
    417
    418/* reset codec link */
    419int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
    420{
    421	if (!full_reset)
    422		goto skip_reset;
    423
    424	/* clear STATESTS if not in reset */
    425	if (snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET)
    426		snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
    427
    428	/* reset controller */
    429	snd_hdac_bus_enter_link_reset(bus);
    430
    431	/* delay for >= 100us for codec PLL to settle per spec
    432	 * Rev 0.9 section 5.5.1
    433	 */
    434	usleep_range(500, 1000);
    435
    436	/* Bring controller out of reset */
    437	snd_hdac_bus_exit_link_reset(bus);
    438
    439	/* Brent Chartrand said to wait >= 540us for codecs to initialize */
    440	usleep_range(1000, 1200);
    441
    442 skip_reset:
    443	/* check to see if controller is ready */
    444	if (!snd_hdac_chip_readb(bus, GCTL)) {
    445		dev_dbg(bus->dev, "controller not ready!\n");
    446		return -EBUSY;
    447	}
    448
    449	/* detect codecs */
    450	if (!bus->codec_mask) {
    451		bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
    452		dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
    453	}
    454
    455	return 0;
    456}
    457EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link);
    458
    459/* enable interrupts */
    460static void azx_int_enable(struct hdac_bus *bus)
    461{
    462	/* enable controller CIE and GIE */
    463	snd_hdac_chip_updatel(bus, INTCTL,
    464			      AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN,
    465			      AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
    466}
    467
    468/* disable interrupts */
    469static void azx_int_disable(struct hdac_bus *bus)
    470{
    471	struct hdac_stream *azx_dev;
    472
    473	/* disable interrupts in stream descriptor */
    474	list_for_each_entry(azx_dev, &bus->stream_list, list)
    475		snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
    476
    477	/* disable SIE for all streams */
    478	snd_hdac_chip_writeb(bus, INTCTL, 0);
    479
    480	/* disable controller CIE and GIE */
    481	snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN, 0);
    482}
    483
    484/* clear interrupts */
    485static void azx_int_clear(struct hdac_bus *bus)
    486{
    487	struct hdac_stream *azx_dev;
    488
    489	/* clear stream status */
    490	list_for_each_entry(azx_dev, &bus->stream_list, list)
    491		snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
    492
    493	/* clear STATESTS */
    494	snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
    495
    496	/* clear rirb status */
    497	snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
    498
    499	/* clear int status */
    500	snd_hdac_chip_writel(bus, INTSTS, AZX_INT_CTRL_EN | AZX_INT_ALL_STREAM);
    501}
    502
    503/**
    504 * snd_hdac_bus_init_chip - reset and start the controller registers
    505 * @bus: HD-audio core bus
    506 * @full_reset: Do full reset
    507 */
    508bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
    509{
    510	if (bus->chip_init)
    511		return false;
    512
    513	/* reset controller */
    514	snd_hdac_bus_reset_link(bus, full_reset);
    515
    516	/* clear interrupts */
    517	azx_int_clear(bus);
    518
    519	/* initialize the codec command I/O */
    520	snd_hdac_bus_init_cmd_io(bus);
    521
    522	/* enable interrupts after CORB/RIRB buffers are initialized above */
    523	azx_int_enable(bus);
    524
    525	/* program the position buffer */
    526	if (bus->use_posbuf && bus->posbuf.addr) {
    527		snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr);
    528		snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr));
    529	}
    530
    531	bus->chip_init = true;
    532
    533	return true;
    534}
    535EXPORT_SYMBOL_GPL(snd_hdac_bus_init_chip);
    536
    537/**
    538 * snd_hdac_bus_stop_chip - disable the whole IRQ and I/Os
    539 * @bus: HD-audio core bus
    540 */
    541void snd_hdac_bus_stop_chip(struct hdac_bus *bus)
    542{
    543	if (!bus->chip_init)
    544		return;
    545
    546	/* disable interrupts */
    547	azx_int_disable(bus);
    548	azx_int_clear(bus);
    549
    550	/* disable CORB/RIRB */
    551	snd_hdac_bus_stop_cmd_io(bus);
    552
    553	/* disable position buffer */
    554	if (bus->posbuf.addr) {
    555		snd_hdac_chip_writel(bus, DPLBASE, 0);
    556		snd_hdac_chip_writel(bus, DPUBASE, 0);
    557	}
    558
    559	bus->chip_init = false;
    560}
    561EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_chip);
    562
    563/**
    564 * snd_hdac_bus_handle_stream_irq - interrupt handler for streams
    565 * @bus: HD-audio core bus
    566 * @status: INTSTS register value
    567 * @ack: callback to be called for woken streams
    568 *
    569 * Returns the bits of handled streams, or zero if no stream is handled.
    570 */
    571int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
    572				    void (*ack)(struct hdac_bus *,
    573						struct hdac_stream *))
    574{
    575	struct hdac_stream *azx_dev;
    576	u8 sd_status;
    577	int handled = 0;
    578
    579	list_for_each_entry(azx_dev, &bus->stream_list, list) {
    580		if (status & azx_dev->sd_int_sta_mask) {
    581			sd_status = snd_hdac_stream_readb(azx_dev, SD_STS);
    582			snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
    583			handled |= 1 << azx_dev->index;
    584			if (!azx_dev->substream || !azx_dev->running ||
    585			    !(sd_status & SD_INT_COMPLETE))
    586				continue;
    587			if (ack)
    588				ack(bus, azx_dev);
    589		}
    590	}
    591	return handled;
    592}
    593EXPORT_SYMBOL_GPL(snd_hdac_bus_handle_stream_irq);
    594
    595/**
    596 * snd_hdac_bus_alloc_stream_pages - allocate BDL and other buffers
    597 * @bus: HD-audio core bus
    598 *
    599 * Call this after assigning the all streams.
    600 * Returns zero for success, or a negative error code.
    601 */
    602int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
    603{
    604	struct hdac_stream *s;
    605	int num_streams = 0;
    606	int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV;
    607	int err;
    608
    609	list_for_each_entry(s, &bus->stream_list, list) {
    610		/* allocate memory for the BDL for each stream */
    611		err = snd_dma_alloc_pages(dma_type, bus->dev,
    612					  BDL_SIZE, &s->bdl);
    613		num_streams++;
    614		if (err < 0)
    615			return -ENOMEM;
    616	}
    617
    618	if (WARN_ON(!num_streams))
    619		return -EINVAL;
    620	/* allocate memory for the position buffer */
    621	err = snd_dma_alloc_pages(dma_type, bus->dev,
    622				  num_streams * 8, &bus->posbuf);
    623	if (err < 0)
    624		return -ENOMEM;
    625	list_for_each_entry(s, &bus->stream_list, list)
    626		s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
    627
    628	/* single page (at least 4096 bytes) must suffice for both ringbuffes */
    629	return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb);
    630}
    631EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
    632
    633/**
    634 * snd_hdac_bus_free_stream_pages - release BDL and other buffers
    635 * @bus: HD-audio core bus
    636 */
    637void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
    638{
    639	struct hdac_stream *s;
    640
    641	list_for_each_entry(s, &bus->stream_list, list) {
    642		if (s->bdl.area)
    643			snd_dma_free_pages(&s->bdl);
    644	}
    645
    646	if (bus->rb.area)
    647		snd_dma_free_pages(&bus->rb);
    648	if (bus->posbuf.area)
    649		snd_dma_free_pages(&bus->posbuf);
    650}
    651EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);
    652
    653/**
    654 * snd_hdac_bus_link_power - power up/down codec link
    655 * @codec: HD-audio device
    656 * @enable: whether to power-up the link
    657 */
    658void snd_hdac_bus_link_power(struct hdac_device *codec, bool enable)
    659{
    660	if (enable)
    661		set_bit(codec->addr, &codec->bus->codec_powered);
    662	else
    663		clear_bit(codec->addr, &codec->bus->codec_powered);
    664}
    665EXPORT_SYMBOL_GPL(snd_hdac_bus_link_power);