/*
 * cec-api.c - HDMI Consumer Electronics Control framework - API
 *
 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/ktime.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/version.h>

#include "cec-priv.h"

static inline struct cec_devnode *cec_devnode_data(struct file *filp)
{
	struct cec_fh *fh = filp->private_data;

	return &fh->adap->devnode;
}

/* CEC file operations */

static unsigned int cec_poll(struct file *filp,
			     struct poll_table_struct *poll)
{
	struct cec_devnode *devnode = cec_devnode_data(filp);
	struct cec_fh *fh = filp->private_data;
	struct cec_adapter *adap = fh->adap;
	unsigned int res = 0;

	if (!devnode->registered)
		return POLLERR | POLLHUP;
	mutex_lock(&adap->lock);
	if (adap->is_configured &&
	    adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ)
		res |= POLLOUT | POLLWRNORM;
	if (fh->queued_msgs)
		res |= POLLIN | POLLRDNORM;
	if (fh->pending_events)
		res |= POLLPRI;
	poll_wait(filp, &fh->wait, poll);
	mutex_unlock(&adap->lock);
	return res;
}

static bool cec_is_busy(const struct cec_adapter *adap,
			const struct cec_fh *fh)
{
	bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh;
	bool valid_follower = adap->cec_follower && adap->cec_follower == fh;

	/*
	 * Exclusive initiators and followers can always access the CEC adapter
	 */
	if (valid_initiator || valid_follower)
		return false;
	/*
	 * All others can only access the CEC adapter if there is no
	 * exclusive initiator and they are in INITIATOR mode.
	 */
	return adap->cec_initiator ||
	       fh->mode_initiator == CEC_MODE_NO_INITIATOR;
}

static long cec_adap_g_caps(struct cec_adapter *adap,
			    struct cec_caps __user *parg)
{
	struct cec_caps caps = {};

	strlcpy(caps.driver, adap->devnode.dev.parent->driver->name,
		sizeof(caps.driver));
	strlcpy(caps.name, adap->name, sizeof(caps.name));
	caps.available_log_addrs = adap->available_log_addrs;
	caps.capabilities = adap->capabilities;
	caps.version = LINUX_VERSION_CODE;
	if (copy_to_user(parg, &caps, sizeof(caps)))
		return -EFAULT;
	return 0;
}

static long cec_adap_g_phys_addr(struct cec_adapter *adap,
				 __u16 __user *parg)
{
	u16 phys_addr;

	mutex_lock(&adap->lock);
	phys_addr = adap->phys_addr;
	mutex_unlock(&adap->lock);
	if (copy_to_user(parg, &phys_addr, sizeof(phys_addr)))
		return -EFAULT;
	return 0;
}

static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
				 bool block, __u16 __user *parg)
{
	u16 phys_addr;
	long err;

	if (!(adap->capabilities & CEC_CAP_PHYS_ADDR))
		return -ENOTTY;
	if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
		return -EFAULT;

	err = cec_phys_addr_validate(phys_addr, NULL, NULL);
	if (err)
		return err;
	mutex_lock(&adap->lock);
	if (cec_is_busy(adap, fh))
		err = -EBUSY;
	else
		__cec_s_phys_addr(adap, phys_addr, block);
	mutex_unlock(&adap->lock);
	return err;
}

static long cec_adap_g_log_addrs(struct cec_adapter *adap,
				 struct cec_log_addrs __user *parg)
{
	struct cec_log_addrs log_addrs;

	mutex_lock(&adap->lock);
	log_addrs = adap->log_addrs;
	if (!adap->is_configured)
		memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,
		       sizeof(log_addrs.log_addr));
	mutex_unlock(&adap->lock);

	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
		return -EFAULT;
	return 0;
}

static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,
				 bool block, struct cec_log_addrs __user *parg)
{
	struct cec_log_addrs log_addrs;
	long err = -EBUSY;

	if (!(adap->capabilities & CEC_CAP_LOG_ADDRS))
		return -ENOTTY;
	if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
		return -EFAULT;
	log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK |
			   CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU |
			   CEC_LOG_ADDRS_FL_CDC_ONLY;
	mutex_lock(&adap->lock);
	if (!adap->is_configuring &&
	    (!log_addrs.num_log_addrs || !adap->is_configured) &&
	    !cec_is_busy(adap, fh)) {
		err = __cec_s_log_addrs(adap, &log_addrs, block);
		if (!err)
			log_addrs = adap->log_addrs;
	}
	mutex_unlock(&adap->lock);
	if (err)
		return err;
	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
		return -EFAULT;
	return 0;
}

static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
			 bool block, struct cec_msg __user *parg)
{
	struct cec_msg msg = {};
	long err = 0;

	if (!(adap->capabilities & CEC_CAP_TRANSMIT))
		return -ENOTTY;
	if (copy_from_user(&msg, parg, sizeof(msg)))
		return -EFAULT;

	/* A CDC-Only device can only send CDC messages */
	if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
	    (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE))
		return -EINVAL;

	mutex_lock(&adap->lock);
	if (!adap->is_configured)
		err = -ENONET;
	else if (cec_is_busy(adap, fh))
		err = -EBUSY;
	else
		err = cec_transmit_msg_fh(adap, &msg, fh, block);
	mutex_unlock(&adap->lock);
	if (err)
		return err;
	if (copy_to_user(parg, &msg, sizeof(msg)))
		return -EFAULT;
	return 0;
}

/* Called by CEC_RECEIVE: wait for a message to arrive */
static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block)
{
	u32 timeout = msg->timeout;
	int res;

	do {
		mutex_lock(&fh->lock);
		/* Are there received messages queued up? */
		if (fh->queued_msgs) {
			/* Yes, return the first one */
			struct cec_msg_entry *entry =
				list_first_entry(&fh->msgs,
						 struct cec_msg_entry, list);

			list_del(&entry->list);
			*msg = entry->msg;
			kfree(entry);
			fh->queued_msgs--;
			mutex_unlock(&fh->lock);
			/* restore original timeout value */
			msg->timeout = timeout;
			return 0;
		}

		/* No, return EAGAIN in non-blocking mode or wait */
		mutex_unlock(&fh->lock);

		/* Return when in non-blocking mode */
		if (!block)
			return -EAGAIN;

		if (msg->timeout) {
			/* The user specified a timeout */
			res = wait_event_interruptible_timeout(fh->wait,
							       fh->queued_msgs,
				msecs_to_jiffies(msg->timeout));
			if (res == 0)
				res = -ETIMEDOUT;
			else if (res > 0)
				res = 0;
		} else {
			/* Wait indefinitely */
			res = wait_event_interruptible(fh->wait,
						       fh->queued_msgs);
		}
		/* Exit on error, otherwise loop to get the new message */
	} while (!res);
	return res;
}

static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,
			bool block, struct cec_msg __user *parg)
{
	struct cec_msg msg = {};
	long err = 0;

	if (copy_from_user(&msg, parg, sizeof(msg)))
		return -EFAULT;
	mutex_lock(&adap->lock);
	if (!adap->is_configured && fh->mode_follower < CEC_MODE_MONITOR)
		err = -ENONET;
	mutex_unlock(&adap->lock);
	if (err)
		return err;

	err = cec_receive_msg(fh, &msg, block);
	if (err)
		return err;
	msg.flags = 0;
	if (copy_to_user(parg, &msg, sizeof(msg)))
		return -EFAULT;
	return 0;
}

static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
			bool block, struct cec_event __user *parg)
{
	struct cec_event *ev = NULL;
	u64 ts = ~0ULL;
	unsigned int i;
	long err = 0;

	mutex_lock(&fh->lock);
	while (!fh->pending_events && block) {
		mutex_unlock(&fh->lock);
		err = wait_event_interruptible(fh->wait, fh->pending_events);
		if (err)
			return err;
		mutex_lock(&fh->lock);
	}

	/* Find the oldest event */
	for (i = 0; i < CEC_NUM_EVENTS; i++) {
		if (fh->pending_events & (1 << (i + 1)) &&
		    fh->events[i].ts <= ts) {
			ev = &fh->events[i];
			ts = ev->ts;
		}
	}
	if (!ev) {
		err = -EAGAIN;
		goto unlock;
	}

	if (copy_to_user(parg, ev, sizeof(*ev))) {
		err = -EFAULT;
		goto unlock;
	}

	fh->pending_events &= ~(1 << ev->event);

unlock:
	mutex_unlock(&fh->lock);
	return err;
}

static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh,
		       u32 __user *parg)
{
	u32 mode = fh->mode_initiator | fh->mode_follower;

	if (copy_to_user(parg, &mode, sizeof(mode)))
		return -EFAULT;
	return 0;
}

static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
		       u32 __user *parg)
{
	u32 mode;
	u8 mode_initiator;
	u8 mode_follower;
	long err = 0;

	if (copy_from_user(&mode, parg, sizeof(mode)))
		return -EFAULT;
	if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK))
		return -EINVAL;

	mode_initiator = mode & CEC_MODE_INITIATOR_MSK;
	mode_follower = mode & CEC_MODE_FOLLOWER_MSK;

	if (mode_initiator > CEC_MODE_EXCL_INITIATOR ||
	    mode_follower > CEC_MODE_MONITOR_ALL)
		return -EINVAL;

	if (mode_follower == CEC_MODE_MONITOR_ALL &&
	    !(adap->capabilities & CEC_CAP_MONITOR_ALL))
		return -EINVAL;

	/* Follower modes should always be able to send CEC messages */
	if ((mode_initiator == CEC_MODE_NO_INITIATOR ||
	     !(adap->capabilities & CEC_CAP_TRANSMIT)) &&
	    mode_follower >= CEC_MODE_FOLLOWER &&
	    mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU)
		return -EINVAL;

	/* Monitor modes require CEC_MODE_NO_INITIATOR */
	if (mode_initiator && mode_follower >= CEC_MODE_MONITOR)
		return -EINVAL;

	/* Monitor modes require CAP_NET_ADMIN */
	if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN))
		return -EPERM;

	mutex_lock(&adap->lock);
	/*
	 * You can't become exclusive follower if someone else already
	 * has that job.
	 */
	if ((mode_follower == CEC_MODE_EXCL_FOLLOWER ||
	     mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) &&
	    adap->cec_follower && adap->cec_follower != fh)
		err = -EBUSY;
	/*
	 * You can't become exclusive initiator if someone else already
	 * has that job.
	 */
	if (mode_initiator == CEC_MODE_EXCL_INITIATOR &&
	    adap->cec_initiator && adap->cec_initiator != fh)
		err = -EBUSY;

	if (!err) {
		bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL;
		bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL;

		if (old_mon_all != new_mon_all) {
			if (new_mon_all)
				err = cec_monitor_all_cnt_inc(adap);
			else
				cec_monitor_all_cnt_dec(adap);
		}
	}

	if (err) {
		mutex_unlock(&adap->lock);
		return err;
	}

	if (fh->mode_follower == CEC_MODE_FOLLOWER)
		adap->follower_cnt--;
	if (mode_follower == CEC_MODE_FOLLOWER)
		adap->follower_cnt++;
	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
	    mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
		adap->passthrough =
			mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
		adap->cec_follower = fh;
	} else if (adap->cec_follower == fh) {
		adap->passthrough = false;
		adap->cec_follower = NULL;
	}
	if (mode_initiator == CEC_MODE_EXCL_INITIATOR)
		adap->cec_initiator = fh;
	else if (adap->cec_initiator == fh)
		adap->cec_initiator = NULL;
	fh->mode_initiator = mode_initiator;
	fh->mode_follower = mode_follower;
	mutex_unlock(&adap->lock);
	return 0;
}

static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct cec_devnode *devnode = cec_devnode_data(filp);
	struct cec_fh *fh = filp->private_data;
	struct cec_adapter *adap = fh->adap;
	bool block = !(filp->f_flags & O_NONBLOCK);
	void __user *parg = (void __user *)arg;

	if (!devnode->registered)
		return -ENODEV;

	switch (cmd) {
	case CEC_ADAP_G_CAPS:
		return cec_adap_g_caps(adap, parg);

	case CEC_ADAP_G_PHYS_ADDR:
		return cec_adap_g_phys_addr(adap, parg);

	case CEC_ADAP_S_PHYS_ADDR:
		return cec_adap_s_phys_addr(adap, fh, block, parg);

	case CEC_ADAP_G_LOG_ADDRS:
		return cec_adap_g_log_addrs(adap, parg);

	case CEC_ADAP_S_LOG_ADDRS:
		return cec_adap_s_log_addrs(adap, fh, block, parg);

	case CEC_TRANSMIT:
		return cec_transmit(adap, fh, block, parg);

	case CEC_RECEIVE:
		return cec_receive(adap, fh, block, parg);

	case CEC_DQEVENT:
		return cec_dqevent(adap, fh, block, parg);

	case CEC_G_MODE:
		return cec_g_mode(adap, fh, parg);

	case CEC_S_MODE:
		return cec_s_mode(adap, fh, parg);

	default:
		return -ENOTTY;
	}
}

static int cec_open(struct inode *inode, struct file *filp)
{
	struct cec_devnode *devnode =
		container_of(inode->i_cdev, struct cec_devnode, cdev);
	struct cec_adapter *adap = to_cec_adapter(devnode);
	struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
	/*
	 * Initial events that are automatically sent when the cec device is
	 * opened.
	 */
	struct cec_event ev_state = {
		.event = CEC_EVENT_STATE_CHANGE,
		.flags = CEC_EVENT_FL_INITIAL_STATE,
	};
	int err;

	if (!fh)
		return -ENOMEM;

	INIT_LIST_HEAD(&fh->msgs);
	INIT_LIST_HEAD(&fh->xfer_list);
	mutex_init(&fh->lock);
	init_waitqueue_head(&fh->wait);

	fh->mode_initiator = CEC_MODE_INITIATOR;
	fh->adap = adap;

	err = cec_get_device(devnode);
	if (err) {
		kfree(fh);
		return err;
	}

	filp->private_data = fh;

	mutex_lock(&devnode->lock);
	/* Queue up initial state events */
	ev_state.state_change.phys_addr = adap->phys_addr;
	ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
	cec_queue_event_fh(fh, &ev_state, 0);

	list_add(&fh->list, &devnode->fhs);
	mutex_unlock(&devnode->lock);

	return 0;
}

/* Override for the release function */
static int cec_release(struct inode *inode, struct file *filp)
{
	struct cec_devnode *devnode = cec_devnode_data(filp);
	struct cec_adapter *adap = to_cec_adapter(devnode);
	struct cec_fh *fh = filp->private_data;

	mutex_lock(&adap->lock);
	if (adap->cec_initiator == fh)
		adap->cec_initiator = NULL;
	if (adap->cec_follower == fh) {
		adap->cec_follower = NULL;
		adap->passthrough = false;
	}
	if (fh->mode_follower == CEC_MODE_FOLLOWER)
		adap->follower_cnt--;
	if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
		cec_monitor_all_cnt_dec(adap);
	mutex_unlock(&adap->lock);

	mutex_lock(&devnode->lock);
	list_del(&fh->list);
	mutex_unlock(&devnode->lock);

	/* Unhook pending transmits from this filehandle. */
	mutex_lock(&adap->lock);
	while (!list_empty(&fh->xfer_list)) {
		struct cec_data *data =
			list_first_entry(&fh->xfer_list, struct cec_data, xfer_list);

		data->blocking = false;
		data->fh = NULL;
		list_del(&data->xfer_list);
	}
	mutex_unlock(&adap->lock);
	while (!list_empty(&fh->msgs)) {
		struct cec_msg_entry *entry =
			list_first_entry(&fh->msgs, struct cec_msg_entry, list);

		list_del(&entry->list);
		kfree(entry);
	}
	kfree(fh);

	cec_put_device(devnode);
	filp->private_data = NULL;
	return 0;
}

const struct file_operations cec_devnode_fops = {
	.owner = THIS_MODULE,
	.open = cec_open,
	.unlocked_ioctl = cec_ioctl,
	.release = cec_release,
	.poll = cec_poll,
	.llseek = no_llseek,
};
