sound/soc/tegra/tegra_isomgr_bw.c

Source file repositories/reference/linux-study-clean/sound/soc/tegra/tegra_isomgr_bw.c

File Facts

System
Linux kernel
Corpus path
sound/soc/tegra/tegra_isomgr_bw.c
Extension
.c
Size
3806 bytes
Lines
131
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (is_running) {
			if (bandwidth + adma_isomgr->current_bandwidth > adma_isomgr->max_bw)
				bandwidth = adma_isomgr->max_bw - adma_isomgr->current_bandwidth;

			adma_isomgr->current_bandwidth += bandwidth;
		} else {
			adma_isomgr->current_bandwidth -=
				adma_isomgr->bw_per_dev[type][pcm->device];
		}
	}

	adma_isomgr->bw_per_dev[type][pcm->device] = bandwidth;

	dev_dbg(dev, "Setting up bandwidth to %d KBps\n", adma_isomgr->current_bandwidth);

	return icc_set_bw(adma_isomgr->icc_path_handle,
			  adma_isomgr->current_bandwidth, adma_isomgr->max_bw);
}

int tegra_isomgr_adma_register(struct device *dev)
{
	struct tegra_admaif *admaif = dev_get_drvdata(dev);
	struct tegra_adma_isomgr *adma_isomgr;
	int i;

	adma_isomgr = devm_kzalloc(dev, sizeof(struct tegra_adma_isomgr), GFP_KERNEL);
	if (!adma_isomgr)
		return -ENOMEM;

	adma_isomgr->icc_path_handle = devm_of_icc_get(dev, "write");
	if (IS_ERR(adma_isomgr->icc_path_handle))
		return dev_err_probe(dev, PTR_ERR(adma_isomgr->icc_path_handle),
				"failed to acquire interconnect path\n");

	/* Either INTERCONNECT config OR interconnect property is not defined */
	if (!adma_isomgr->icc_path_handle) {
		devm_kfree(dev, adma_isomgr);
		return 0;
	}

	adma_isomgr->max_pcm_device = admaif->soc_data->num_ch;
	adma_isomgr->max_bw = STREAM_TYPE * MAX_SAMPLE_RATE * MAX_BYTES_PER_SAMPLE *
			      admaif->soc_data->max_stream_ch * adma_isomgr->max_pcm_device;

	for (i = 0; i < STREAM_TYPE; i++) {
		adma_isomgr->bw_per_dev[i] = devm_kzalloc(dev, adma_isomgr->max_pcm_device *
							  sizeof(u32), GFP_KERNEL);
		if (!adma_isomgr->bw_per_dev[i])
			return -ENOMEM;
	}

	adma_isomgr->current_bandwidth = 0;
	mutex_init(&adma_isomgr->mutex);
	admaif->adma_isomgr = adma_isomgr;

	return 0;
}

void tegra_isomgr_adma_unregister(struct device *dev)
{
	struct tegra_admaif *admaif = dev_get_drvdata(dev);

	if (!admaif->adma_isomgr)
		return;

	mutex_destroy(&admaif->adma_isomgr->mutex);
}

MODULE_AUTHOR("Mohan Kumar <mkumard@nvidia.com>");
MODULE_DESCRIPTION("Tegra ADMA Bandwidth Request driver");
MODULE_LICENSE("GPL");

Annotation

Implementation Notes