// 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/i915_component.h>
#include <drm/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,
	.unbind = mei_component_master_unbind,
};

/**
 * mei_gsc_proxy_component_match - compare function for matching mei.
 *
 *    The function checks if the device is pci device and
 *    Intel VGA adapter, the subcomponent is SW Proxy
 *    and the parent of MEI PCI and the parent of VGA are the same PCH device.
 *
 * @dev: master device
 * @subcomponent: subcomponent to match (I915_COMPONENT_SWPROXY)
 * @data: compare data (mei pci parent)
 *
 * Return:
 * * 1 - if components match
 * * 0 - otherwise
 */
static int mei_gsc_proxy_component_match(struct device *dev, int subcomponent,
					 void *data)
{
	struct pci_dev *pdev;

	if (!dev_is_pci(dev))
		return 0;

	pdev = to_pci_dev(dev);

	if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
	    pdev->vendor != PCI_VENDOR_ID_INTEL)
		return 0;

	if (subcomponent != I915_COMPONENT_GSC_PROXY)
		return 0;

	return component_compare_dev(dev->parent, ((struct device *)data)->parent);
}

static int mei_gsc_proxy_probe(struct mei_cl_device *cldev,
			       const struct mei_cl_device_id *id)
{
	struct i915_gsc_proxy_component *comp_master;
	struct component_match *master_match = NULL;
	int ret;

	ret = mei_cldev_enable(cldev);
	if (ret < 0) {
		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
		goto enable_err_exit;
	}

	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
	if (!comp_master) {
		ret = -ENOMEM;
		goto err_exit;
	}

	component_match_add_typed(&cldev->dev, &master_match,
				  mei_gsc_proxy_component_match, cldev->dev.parent);
	if (IS_ERR_OR_NULL(master_match)) {
		ret = -ENOMEM;
		goto err_exit;
	}

	mei_cldev_set_drvdata(cldev, comp_master);
	ret = component_master_add_with_match(&cldev->dev,
					      &mei_component_master_ops,
					      master_match);
	if (ret < 0) {
		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
		goto err_exit;
	}

	return 0;

err_exit:
	mei_cldev_set_drvdata(cldev, NULL);
	kfree(comp_master);
	mei_cldev_disable(cldev);
enable_err_exit:
	return ret;
}

static void mei_gsc_proxy_remove(struct mei_cl_device *cldev)
{
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
	int ret;

	component_master_del(&cldev->dev, &mei_component_master_ops);
	kfree(comp_master);
	mei_cldev_set_drvdata(cldev, NULL);

	ret = mei_cldev_disable(cldev);
	if (ret)
		dev_warn(&cldev->dev, "mei_cldev_disable() failed %d\n", ret);
}

#define MEI_UUID_GSC_PROXY UUID_LE(0xf73db04, 0x97ab, 0x4125, \
				   0xb8, 0x93, 0xe9, 0x4, 0xad, 0xd, 0x54, 0x64)

static struct mei_cl_device_id mei_gsc_proxy_tbl[] = {
	{ .uuid = MEI_UUID_GSC_PROXY, .version = MEI_CL_VERSION_ANY },
	{ }
};
MODULE_DEVICE_TABLE(mei, mei_gsc_proxy_tbl);

static struct mei_cl_driver mei_gsc_proxy_driver = {
	.id_table = mei_gsc_proxy_tbl,
	.name = KBUILD_MODNAME,
	.probe = mei_gsc_proxy_probe,
	.remove	= mei_gsc_proxy_remove,
};

module_mei_cl_driver(mei_gsc_proxy_driver);

MODULE_AUTHOR("Intel Corporation");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MEI GSC PROXY");
