/*
 * INTEL MID Remote Processor Core driver
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/remoteproc.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
#include <linux/virtio_ring.h>
#include <linux/virtio_ids.h>
#include <linux/platform_data/intel_mid_remoteproc.h>

#include "intel_mid_rproc_core.h"
#include "remoteproc_internal.h"

#define RPMSG_NS_ADDR	53

/**
 * rpmsg_ns_alloc() - allocate a name service annoucement structure
 * @name: name of remote service
 * @id: rproc type
 * @addr: address of remote service
 */
struct rpmsg_ns_info *rpmsg_ns_alloc(const char *name, int id, u32 addr)
{
	struct rpmsg_ns_info *ns_info;

	ns_info = kzalloc(sizeof(struct rpmsg_ns_info), GFP_KERNEL);
	if (ns_info) {
		strncpy(ns_info->name, name, RPMSG_NAME_SIZE);
		ns_info->type = id;
		ns_info->addr = addr;
		ns_info->flags = RPMSG_NS_CREATE;
	}

	return ns_info;
};
EXPORT_SYMBOL_GPL(rpmsg_ns_alloc);

/**
 * rpmsg_ns_add_to_list() -- add a name service node to the global list
 * @info: name service node
 */
void rpmsg_ns_add_to_list(struct rpmsg_ns_info *info,
				struct rpmsg_ns_list *nslist)
{
	mutex_lock(&nslist->lock);
	list_add_tail(&info->node, &nslist->list);
	mutex_unlock(&nslist->lock);
}
EXPORT_SYMBOL_GPL(rpmsg_ns_add_to_list);

/**
 * free_rpmsg_ns() -- free rpmsg name service node
 * @info: name service node
 */
void free_rpmsg_ns(struct rpmsg_ns_info *info)
{
	kfree(info);
}

/**
 * rpmsg_ns_del_list() -- free rpmsg name service list
 */
void rpmsg_ns_del_list(struct rpmsg_ns_list *nslist)
{
	struct rpmsg_ns_info *info, *next;
	mutex_lock(&nslist->lock);
	list_for_each_entry_safe(info, next, &nslist->list, node) {
		list_del(&info->node);
		free_rpmsg_ns(info);
	}
	mutex_unlock(&nslist->lock);
}
EXPORT_SYMBOL_GPL(rpmsg_ns_del_list);

/**
 * find_rvdev() - find the rproc state of a supported virtio device
 * @rproc: rproc handle
 * @id: virtio device id
 */
struct rproc_vdev *find_rvdev(struct rproc *rproc, int id)
{
	struct rproc_vdev *rvdev;

	list_for_each_entry(rvdev, &rproc->rvdevs, node)
		if (rvdev->vdev.id.device == id)
			return rvdev;

	return NULL;
}

/*
 * Since we could not get vring structure directly from rproc_vring
 * structure, we have to create two local vrings and identify them
 * by matching with rproc_vrings.
 * @id: virtio device id.
 * Currently one rproc_vdev is supported by firmware, and the id is
 * VIRTIO_ID_RPMSG (declared in linux/virtio_ids.h).
 */
int find_vring_index(struct rproc *rproc, int vqid, int id)
{
	struct rproc_vdev *rvdev;
	struct device *dev = rproc->dev.parent;
	int vring_idx = 0;

	rvdev = find_rvdev(rproc, id);
	if (rvdev == NULL) {
		dev_err(dev, "virtio device not found\n");
		return -EINVAL;
	}

	while (vring_idx < RVDEV_NUM_VRINGS) {
		if (rvdev->vring[vring_idx].notifyid == vqid)
			break;
		vring_idx++;
	}

	/* no match found? there's a problem */
	if (vring_idx == RVDEV_NUM_VRINGS) {
		dev_err(dev, "Can not find vring\n");
		return -EINVAL;
	}

	return vring_idx;
}

void intel_mid_rproc_vring_init(struct rproc *rproc,
			struct vring *vring, enum local_vring_idx id)
{
	int align, len;
	void *addr;
	struct rproc_vdev *rvdev;
	struct device *dev = rproc->dev.parent;

	rvdev = find_rvdev(rproc, VIRTIO_ID_RPMSG);
	if (rvdev == NULL) {
		dev_err(dev, "virtio device not found\n");
		return;
	}

	addr = rvdev->vring[id].va;
	align = rvdev->vring[id].align;
	len = rvdev->vring[id].len;
	vring_init(vring, len, addr, align);
}

/**
 * intel_mid_rproc_vq_interrupt() - inform a vq interrupt to rproc
 *				    after vq buffers are handled
 * @rproc: rproc handle
 * @msg: vq notify id
 */
void intel_mid_rproc_vq_interrupt(struct rproc *rproc, int msg)
{
	struct device *dev = rproc->dev.parent;

	if (rproc_vq_interrupt(rproc, msg) == IRQ_NONE)
		dev_err(dev, "no message was found in vqid %d\n", msg);
}

/**
 * intel_mid_rproc_msg_handle() - generic interface as a vq buffer handle
 *				  during rpmsg transaction
 * @iproc: intel mid rproc data
 */
int intel_mid_rproc_msg_handle(struct intel_mid_rproc *iproc)
{
	int ret;
	struct vring *r_vring, *s_vring;
	void *r_virt_addr, *s_virt_addr;
	u16 r_idx, s_idx;
	u64 r_dma_addr, s_dma_addr;
	u32 r_len, s_len;

	r_vring = &iproc->rx_vring;
	s_vring = &iproc->tx_vring;

	r_idx = iproc->r_vring_last_used & (r_vring->num - 1);
	s_idx = iproc->s_vring_last_used & (s_vring->num - 1);

	r_dma_addr = r_vring->desc[r_idx].addr;
	s_dma_addr = s_vring->desc[s_idx].addr;

	r_virt_addr = phys_to_virt(r_dma_addr);
	s_virt_addr = phys_to_virt(s_dma_addr);

	ret = iproc->rproc_rpmsg_handle(r_virt_addr, s_virt_addr,
						&r_len, &s_len);

	r_vring->used->ring[r_idx].id = r_idx;
	r_vring->used->ring[r_idx].len = r_len;
	r_vring->used->idx++;

	s_vring->used->ring[s_idx].id = s_idx;
	s_vring->used->ring[s_idx].len = s_len;
	s_vring->used->idx++;

	iproc->r_vring_last_used++;
	iproc->s_vring_last_used++;

	return ret;
}

/**
 * Remoteproc side rx buffer handler during name service creation.
 * @iproc: intel mid rproc data
 * @ns_info: name service info
 *
 * After remote processor receives name service messages, it needs to
 * update the elements of its virtio device's rx virtqueue buffer
 * before next rpmsg transaction.
 * Here we have this function simulating the above effect.
 */
int intel_mid_rproc_ns_handle(struct intel_mid_rproc *iproc,
				struct rpmsg_ns_info *ns_info)
{
	u16 index;
	u32 len;
	u64 dma_addr;
	void *virt_addr;

	struct vring *r_vring;
	struct rpmsg_hdr *msg;
	struct rpmsg_ns_msg *nsm;

	if (ns_info == NULL) {
		pr_err("ns_info = NULL\n");
		return -ENODEV;
	}

	r_vring = &iproc->rx_vring;

	index = iproc->r_vring_last_used & (r_vring->num - 1);

	len = sizeof(*msg) + sizeof(*nsm);

	dma_addr = r_vring->desc[index].addr;
	virt_addr = phys_to_virt(dma_addr);

	msg = (struct rpmsg_hdr *)virt_addr;
	nsm = (struct rpmsg_ns_msg *)(virt_addr + sizeof(*msg));

	nsm->addr = ns_info->addr;
	nsm->flags = ns_info->flags;
	strncpy(nsm->name, ns_info->name, RPMSG_NAME_SIZE);

	msg->len = sizeof(*nsm);
	msg->src = nsm->addr;
	msg->dst = RPMSG_NS_ADDR;

	r_vring->used->ring[index].id = index;
	r_vring->used->ring[index].len = len;
	r_vring->used->idx++;

	iproc->r_vring_last_used++;

	return 0;
}
