drivers/media/platform/chips-media/wave5/wave5-vpuapi.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
Extension
.c
Size
25096 bytes
Lines
1015
Domain
Driver Families
Bucket
drivers/media
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 (ret < 0 && ret != -EBUSY) {
			dev_warn(inst->dev->dev, "Flush of %s instance with id: %d fail: %d\n",
				 inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id,
				 ret);
			mutex_unlock(&inst->dev->hw_lock);
			return ret;
		}
		if (ret == -EBUSY && retry++ >= MAX_FIRMWARE_CALL_RETRY) {
			dev_warn(inst->dev->dev, "Flush of %s instance with id: %d timed out!\n",
				 inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id);
			mutex_unlock(&inst->dev->hw_lock);
			return -ETIMEDOUT;
		} else if (ret == -EBUSY) {
			struct dec_output_info dec_info;

			mutex_unlock(&inst->dev->hw_lock);
			wave5_vpu_dec_get_output_info(inst, &dec_info);
			mutex_ret = mutex_lock_interruptible(&inst->dev->hw_lock);
			if (mutex_ret)
				return mutex_ret;
			if (dec_info.index_frame_display >= 0) {
				mutex_unlock(&inst->dev->hw_lock);
				wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
				mutex_ret = mutex_lock_interruptible(&inst->dev->hw_lock);
				if (mutex_ret)
					return mutex_ret;
			}
		}
	} while (ret != 0);
	mutex_unlock(&inst->dev->hw_lock);

	return ret;
}

int wave5_vpu_get_version_info(struct device *dev, u32 *revision, unsigned int *product_id)
{
	int ret;
	struct vpu_device *vpu_dev = dev_get_drvdata(dev);

	ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
	if (ret)
		return ret;

	if (!wave5_vpu_is_init(vpu_dev)) {
		ret = -EINVAL;
		goto err_out;
	}

	if (product_id)
		*product_id = vpu_dev->product;
	ret = wave5_vpu_get_version(vpu_dev, revision);

err_out:
	mutex_unlock(&vpu_dev->hw_lock);
	return ret;
}

static int wave5_check_dec_open_param(struct vpu_instance *inst, struct dec_open_param *param)
{
	if (inst->id >= MAX_NUM_INSTANCE) {
		dev_err(inst->dev->dev, "Too many simultaneous instances: %d (max: %u)\n",
			inst->id, MAX_NUM_INSTANCE);
		return -EOPNOTSUPP;
	}

	if (param->bitstream_buffer % 8) {
		dev_err(inst->dev->dev,
			"Bitstream buffer must be aligned to a multiple of 8\n");
		return -EINVAL;
	}

	if (param->bitstream_buffer_size % 1024 ||
	    param->bitstream_buffer_size < MIN_BITSTREAM_BUFFER_SIZE) {
		dev_err(inst->dev->dev,
			"Bitstream buffer size must be aligned to a multiple of 1024 and have a minimum size of %d\n",
			MIN_BITSTREAM_BUFFER_SIZE);
		return -EINVAL;
	}

	return 0;
}

int wave5_vpu_dec_open(struct vpu_instance *inst, struct dec_open_param *open_param)
{
	struct dec_info *p_dec_info;
	int ret;
	struct vpu_device *vpu_dev = inst->dev;
	dma_addr_t buffer_addr;
	size_t buffer_size;

Annotation

Implementation Notes