drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c

Source file repositories/reference/linux-study-clean/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
Extension
.c
Size
5338 bytes
Lines
211
Domain
Driver Families
Bucket
drivers/misc
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2022-2023 Intel Corporation
 */

/**
 * DOC: MEI_GSC_PROXY Client Driver
 *
 * The mei_gsc_proxy driver acts as a translation layer between
 * proxy user (I915) and ME FW by proxying messages to ME FW
 */

#include <linux/component.h>
#include <linux/mei_cl_bus.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uuid.h>
#include <drm/drm_connector.h>
#include <drm/intel/i915_component.h>
#include <drm/intel/i915_gsc_proxy_mei_interface.h>

/**
 * mei_gsc_proxy_send - Sends a proxy message to ME FW.
 * @dev: device corresponding to the mei_cl_device
 * @buf: a message buffer to send
 * @size: size of the message
 * Return: bytes sent on Success, <0 on Failure
 */
static int mei_gsc_proxy_send(struct device *dev, const void *buf, size_t size)
{
	ssize_t ret;

	if (!dev || !buf)
		return -EINVAL;

	ret = mei_cldev_send(to_mei_cl_device(dev), buf, size);
	if (ret < 0)
		dev_dbg(dev, "mei_cldev_send failed. %zd\n", ret);

	return ret;
}

/**
 * mei_gsc_proxy_recv - Receives a proxy message from ME FW.
 * @dev: device corresponding to the mei_cl_device
 * @buf: a message buffer to contain the received message
 * @size: size of the buffer
 * Return: bytes received on Success, <0 on Failure
 */
static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
{
	ssize_t ret;

	if (!dev || !buf)
		return -EINVAL;

	ret = mei_cldev_recv(to_mei_cl_device(dev), buf, size);
	if (ret < 0)
		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", ret);

	return ret;
}

static const struct i915_gsc_proxy_component_ops mei_gsc_proxy_ops = {
	.owner = THIS_MODULE,
	.send = mei_gsc_proxy_send,
	.recv = mei_gsc_proxy_recv,
};

static int mei_component_master_bind(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);

	comp_master->ops = &mei_gsc_proxy_ops;
	comp_master->mei_dev = dev;
	return component_bind_all(dev, comp_master);
}

static void mei_component_master_unbind(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);

	component_unbind_all(dev, comp_master);
}

static const struct component_master_ops mei_component_master_ops = {
	.bind = mei_component_master_bind,

Annotation

Implementation Notes