// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Virtio I2C Bus Driver
 *
 * The Virtio I2C Specification:
 * https://raw.githubusercontent.com/oasis-tcs/virtio-spec/master/virtio-i2c.tex
 *
 * Copyright (c) 2021 Intel Corporation. All rights reserved.
 */

#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/virtio.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
#include <linux/virtio_i2c.h>

/**
 * struct virtio_i2c - virtio I2C data
 * @vdev: virtio device for this controller
 * @completion: completion of virtio I2C message
 * @adap: I2C adapter for this controller
 * @vq: the virtio virtqueue for communication
 */
struct virtio_i2c {
	struct virtio_device *vdev;
	struct completion completion;
	struct i2c_adapter adap;
	struct virtqueue *vq;
};

/**
 * struct virtio_i2c_req - the virtio I2C request structure
 * @out_hdr: the OUT header of the virtio I2C message
 * @buf: the buffer into which data is read, or from which it's written
 * @in_hdr: the IN header of the virtio I2C message
 */
struct virtio_i2c_req {
	struct virtio_i2c_out_hdr out_hdr	____cacheline_aligned;
	uint8_t *buf				____cacheline_aligned;
	struct virtio_i2c_in_hdr in_hdr		____cacheline_aligned;
};

static void virtio_i2c_msg_done(struct virtqueue *vq)
{
	struct virtio_i2c *vi = vq->vdev->priv;

	complete(&vi->completion);
}

static int virtio_i2c_prepare_reqs(struct virtqueue *vq,
				   struct virtio_i2c_req *reqs,
				   struct i2c_msg *msgs, int num)
{
	struct scatterlist *sgs[3], out_hdr, msg_buf, in_hdr;
	int i;

	for (i = 0; i < num; i++) {
		int outcnt = 0, incnt = 0;

		/*
		 * Only 7-bit mode supported for this moment. For the address
		 * format, Please check the Virtio I2C Specification.
		 */
		reqs[i].out_hdr.addr = cpu_to_le16(msgs[i].addr << 1);

		if (msgs[i].flags & I2C_M_RD)
			reqs[i].out_hdr.flags |= cpu_to_le32(VIRTIO_I2C_FLAGS_M_RD);

		if (i != num - 1)
			reqs[i].out_hdr.flags |= cpu_to_le32(VIRTIO_I2C_FLAGS_FAIL_NEXT);

		sg_init_one(&out_hdr, &reqs[i].out_hdr, sizeof(reqs[i].out_hdr));
		sgs[outcnt++] = &out_hdr;

		if (msgs[i].len) {
			reqs[i].buf = i2c_get_dma_safe_msg_buf(&msgs[i], 1);
			if (!reqs[i].buf)
				break;

			sg_init_one(&msg_buf, reqs[i].buf, msgs[i].len);

			if (msgs[i].flags & I2C_M_RD)
				sgs[outcnt + incnt++] = &msg_buf;
			else
				sgs[outcnt++] = &msg_buf;
		}

		sg_init_one(&in_hdr, &reqs[i].in_hdr, sizeof(reqs[i].in_hdr));
		sgs[outcnt + incnt++] = &in_hdr;

		if (virtqueue_add_sgs(vq, sgs, outcnt, incnt, &reqs[i], GFP_KERNEL)) {
			i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], false);
			break;
		}
	}

	return i;
}

static int virtio_i2c_complete_reqs(struct virtqueue *vq,
				    struct virtio_i2c_req *reqs,
				    struct i2c_msg *msgs, int num)
{
	struct virtio_i2c_req *req;
	bool failed = false;
	unsigned int len;
	int i, j = 0;

	for (i = 0; i < num; i++) {
		/* Detach the ith request from the vq */
		req = virtqueue_get_buf(vq, &len);

		/*
		 * Condition req == &reqs[i] should always meet since we have
		 * total num requests in the vq. reqs[i] can never be NULL here.
		 */
		if (!failed && (WARN_ON(req != &reqs[i]) ||
				req->in_hdr.status != VIRTIO_I2C_MSG_OK))
			failed = true;

		i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed);

		if (!failed)
			j++;
	}

	return j;
}

static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num)
{
	struct virtio_i2c *vi = i2c_get_adapdata(adap);
	struct virtqueue *vq = vi->vq;
	struct virtio_i2c_req *reqs;
	int count;

	reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
	if (!reqs)
		return -ENOMEM;

	count = virtio_i2c_prepare_reqs(vq, reqs, msgs, num);
	if (!count)
		goto err_free;

	/*
	 * For the case where count < num, i.e. we weren't able to queue all the
	 * msgs, ideally we should abort right away and return early, but some
	 * of the messages are already sent to the remote I2C controller and the
	 * virtqueue will be left in undefined state in that case. We kick the
	 * remote here to clear the virtqueue, so we can try another set of
	 * messages later on.
	 */

	reinit_completion(&vi->completion);
	virtqueue_kick(vq);

	wait_for_completion(&vi->completion);

	count = virtio_i2c_complete_reqs(vq, reqs, msgs, count);

err_free:
	kfree(reqs);
	return count;
}

static void virtio_i2c_del_vqs(struct virtio_device *vdev)
{
	vdev->config->reset(vdev);
	vdev->config->del_vqs(vdev);
}

static int virtio_i2c_setup_vqs(struct virtio_i2c *vi)
{
	struct virtio_device *vdev = vi->vdev;

	vi->vq = virtio_find_single_vq(vdev, virtio_i2c_msg_done, "msg");
	return PTR_ERR_OR_ZERO(vi->vq);
}

static u32 virtio_i2c_func(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static struct i2c_algorithm virtio_algorithm = {
	.master_xfer = virtio_i2c_xfer,
	.functionality = virtio_i2c_func,
};

static int virtio_i2c_probe(struct virtio_device *vdev)
{
	struct virtio_i2c *vi;
	int ret;

	if (!virtio_has_feature(vdev, VIRTIO_I2C_F_ZERO_LENGTH_REQUEST)) {
		dev_err(&vdev->dev, "Zero-length request feature is mandatory\n");
		return -EINVAL;
	}

	vi = devm_kzalloc(&vdev->dev, sizeof(*vi), GFP_KERNEL);
	if (!vi)
		return -ENOMEM;

	vdev->priv = vi;
	vi->vdev = vdev;

	init_completion(&vi->completion);

	ret = virtio_i2c_setup_vqs(vi);
	if (ret)
		return ret;

	vi->adap.owner = THIS_MODULE;
	snprintf(vi->adap.name, sizeof(vi->adap.name),
		 "i2c_virtio at virtio bus %d", vdev->index);
	vi->adap.algo = &virtio_algorithm;
	vi->adap.dev.parent = &vdev->dev;
	vi->adap.dev.of_node = vdev->dev.of_node;
	i2c_set_adapdata(&vi->adap, vi);

	/*
	 * Setup ACPI node for controlled devices which will be probed through
	 * ACPI.
	 */
	ACPI_COMPANION_SET(&vi->adap.dev, ACPI_COMPANION(vdev->dev.parent));

	ret = i2c_add_adapter(&vi->adap);
	if (ret)
		virtio_i2c_del_vqs(vdev);

	return ret;
}

static void virtio_i2c_remove(struct virtio_device *vdev)
{
	struct virtio_i2c *vi = vdev->priv;

	i2c_del_adapter(&vi->adap);
	virtio_i2c_del_vqs(vdev);
}

static struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_I2C_ADAPTER, VIRTIO_DEV_ANY_ID },
	{}
};
MODULE_DEVICE_TABLE(virtio, id_table);

#ifdef CONFIG_PM_SLEEP
static int virtio_i2c_freeze(struct virtio_device *vdev)
{
	virtio_i2c_del_vqs(vdev);
	return 0;
}

static int virtio_i2c_restore(struct virtio_device *vdev)
{
	return virtio_i2c_setup_vqs(vdev->priv);
}
#endif

static const unsigned int features[] = {
	VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
};

static struct virtio_driver virtio_i2c_driver = {
	.feature_table		= features,
	.feature_table_size	= ARRAY_SIZE(features),
	.id_table		= id_table,
	.probe			= virtio_i2c_probe,
	.remove			= virtio_i2c_remove,
	.driver			= {
		.name	= "i2c_virtio",
	},
#ifdef CONFIG_PM_SLEEP
	.freeze = virtio_i2c_freeze,
	.restore = virtio_i2c_restore,
#endif
};
module_virtio_driver(virtio_i2c_driver);

MODULE_AUTHOR("Jie Deng <jie.deng@intel.com>");
MODULE_AUTHOR("Conghui Chen <conghui.chen@intel.com>");
MODULE_DESCRIPTION("Virtio i2c bus driver");
MODULE_LICENSE("GPL");
