/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 */
/*
 * SMD Packet Driver -- Provides userspace interface to SMD packet ports.
 */

#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/poll.h>

#include <mach/msm_smd.h>

#define NUM_SMD_PKT_PORTS 9
#define DEVICE_NAME "smdpkt"
#define MAX_BUF_SIZE 2048

struct smd_pkt_dev {
	struct cdev cdev;
	struct device *devicep;

	struct smd_channel *ch;
	int open_count;
	struct mutex ch_lock;
	struct mutex rx_lock;
	struct mutex tx_lock;
	wait_queue_head_t ch_read_wait_queue;
	wait_queue_head_t ch_opened_wait_queue;

	int i;

	unsigned char tx_buf[MAX_BUF_SIZE];
	unsigned char rx_buf[MAX_BUF_SIZE];
	int remote_open;

} *smd_pkt_devp[NUM_SMD_PKT_PORTS];

struct class *smd_pkt_classp;
static dev_t smd_pkt_number;

static int msm_smd_pkt_debug_enable;
module_param_named(debug_enable, msm_smd_pkt_debug_enable,
		   int, S_IRUGO | S_IWUSR | S_IWGRP);

#ifdef DEBUG
#define D_DUMP_BUFFER(prestr, cnt, buf) do {			\
		int i;						\
		if (msm_smd_pkt_debug_enable) {			\
			pr_debug("%s", prestr);			\
			for (i = 0; i < cnt; i++)		\
				pr_debug("%.2x", buf[i]);	\
			pr_debug("\n");				\
		}						\
	} while (0)
#else
#define D_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
#endif

#ifdef DEBUG
#define DBG(x...) do {			\
	if (msm_smd_pkt_debug_enable)	\
		pr_debug(x);		\
	} while (0)
#else
#define DBG(x...) do {} while (0)
#endif

static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp)
{
	int sz;

	if (!smd_pkt_devp || !smd_pkt_devp->ch)
		return;

	sz = smd_cur_packet_size(smd_pkt_devp->ch);
	if (sz == 0) {
		DBG("no packet\n");
		return;
	}
	if (sz > smd_read_avail(smd_pkt_devp->ch)) {
		DBG("incomplete packet\n");
		return;
	}

	DBG("waking up reader\n");
	wake_up_interruptible(&smd_pkt_devp->ch_read_wait_queue);
}

static int smd_pkt_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	int r, bytes_read;
	struct smd_pkt_dev *smd_pkt_devp;
	struct smd_channel *chl;

	DBG("read %d bytes\n", count);
	if (count > MAX_BUF_SIZE)
		return -EINVAL;

	smd_pkt_devp = file->private_data;
	if (!smd_pkt_devp || !smd_pkt_devp->ch)
		return -EINVAL;

	chl = smd_pkt_devp->ch;
wait_for_packet:
	r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue,
				     (smd_cur_packet_size(chl) > 0 &&
				      smd_read_avail(chl) >=
				      smd_cur_packet_size(chl)));

	if (r < 0) {
		if (r != -ERESTARTSYS)
			pr_err("wait returned %d\n", r);
		return r;
	}

	mutex_lock(&smd_pkt_devp->rx_lock);

	bytes_read = smd_cur_packet_size(smd_pkt_devp->ch);
	if (bytes_read == 0 ||
	    bytes_read < smd_read_avail(smd_pkt_devp->ch)) {
		mutex_unlock(&smd_pkt_devp->rx_lock);
		DBG("Nothing to read\n");
		goto wait_for_packet;
	}

	if (bytes_read > count) {
		mutex_unlock(&smd_pkt_devp->rx_lock);
		pr_info("packet size %d > buffer size %d", bytes_read, count);
		return -EINVAL;
	}

	r = smd_read(smd_pkt_devp->ch, smd_pkt_devp->rx_buf, bytes_read);
	if (r != bytes_read) {
		mutex_unlock(&smd_pkt_devp->rx_lock);
		pr_err("smd_read failed to read %d bytes: %d\n", bytes_read, r);
		return -EIO;
	}

	D_DUMP_BUFFER("read: ", bytes_read, smd_pkt_devp->rx_buf);
	r = copy_to_user(buf, smd_pkt_devp->rx_buf, bytes_read);
	mutex_unlock(&smd_pkt_devp->rx_lock);
	if (r) {
		pr_err("copy_to_user failed %d\n", r);
		return -EFAULT;
	}

	DBG("read complete %d bytes\n", bytes_read);
	check_and_wakeup_reader(smd_pkt_devp);

	return bytes_read;
}

static int smd_pkt_write(struct file *file, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	int r;
	struct smd_pkt_dev *smd_pkt_devp;

	if (count > MAX_BUF_SIZE)
		return -EINVAL;

	DBG("writing %d bytes\n", count);

	smd_pkt_devp = file->private_data;
	if (!smd_pkt_devp || !smd_pkt_devp->ch)
		return -EINVAL;

	mutex_lock(&smd_pkt_devp->tx_lock);
	if (smd_write_avail(smd_pkt_devp->ch) < count) {
		mutex_unlock(&smd_pkt_devp->tx_lock);
		DBG("Not enough space to write\n");
		return -ENOMEM;
	}

	D_DUMP_BUFFER("write: ", count, buf);
	r = copy_from_user(smd_pkt_devp->tx_buf, buf, count);
	if (r) {
		mutex_unlock(&smd_pkt_devp->tx_lock);
		pr_err("copy_from_user failed %d\n", r);
		return -EFAULT;
	}

	r = smd_write(smd_pkt_devp->ch, smd_pkt_devp->tx_buf, count);
	if (r != count) {
		mutex_unlock(&smd_pkt_devp->tx_lock);
		pr_err("smd_write failed to write %d bytes: %d.\n", count, r);
		return -EIO;
	}
	mutex_unlock(&smd_pkt_devp->tx_lock);

	DBG("wrote %d bytes\n", count);
	return count;
}

static unsigned int smd_pkt_poll(struct file *file, poll_table *wait)
{
	struct smd_pkt_dev *smd_pkt_devp;
	unsigned int mask = 0;

	smd_pkt_devp = file->private_data;
	if (!smd_pkt_devp)
		return POLLERR;

	DBG("poll waiting\n");
	poll_wait(file, &smd_pkt_devp->ch_read_wait_queue, wait);
	if (smd_read_avail(smd_pkt_devp->ch))
		mask |= POLLIN | POLLRDNORM;

	DBG("poll return\n");
	return mask;
}

static void smd_pkt_ch_notify(void *priv, unsigned event)
{
	struct smd_pkt_dev *smd_pkt_devp = priv;

	if (smd_pkt_devp->ch == 0)
		return;

	switch (event) {
	case SMD_EVENT_DATA:
		DBG("data\n");
		check_and_wakeup_reader(smd_pkt_devp);
		break;

	case SMD_EVENT_OPEN:
		DBG("remote open\n");
		smd_pkt_devp->remote_open = 1;
		wake_up_interruptible(&smd_pkt_devp->ch_opened_wait_queue);
		break;

	case SMD_EVENT_CLOSE:
		smd_pkt_devp->remote_open = 0;
		pr_info("remote closed\n");
		break;

	default:
		pr_err("unknown event %d\n", event);
		break;
	}
}

static char *smd_pkt_dev_name[] = {
	"smdcntl0",
	"smdcntl1",
	"smdcntl2",
	"smdcntl3",
	"smdcntl4",
	"smdcntl5",
	"smdcntl6",
	"smdcntl7",
	"smd22",
};

static char *smd_ch_name[] = {
	"DATA5_CNTL",
	"DATA6_CNTL",
	"DATA7_CNTL",
	"DATA8_CNTL",
	"DATA9_CNTL",
	"DATA12_CNTL",
	"DATA13_CNTL",
	"DATA14_CNTL",
	"DATA22",
};

static int smd_pkt_open(struct inode *inode, struct file *file)
{
	int r = 0;
	struct smd_pkt_dev *smd_pkt_devp;

	smd_pkt_devp = container_of(inode->i_cdev, struct smd_pkt_dev, cdev);
	if (!smd_pkt_devp)
		return -EINVAL;

	file->private_data = smd_pkt_devp;

	mutex_lock(&smd_pkt_devp->ch_lock);
	if (smd_pkt_devp->open_count == 0) {
		r = smd_open(smd_ch_name[smd_pkt_devp->i],
			     &smd_pkt_devp->ch, smd_pkt_devp,
			     smd_pkt_ch_notify);
		if (r < 0) {
			pr_err("smd_open failed for %s, %d\n",
			       smd_ch_name[smd_pkt_devp->i], r);
			goto out;
		}

		r = wait_event_interruptible_timeout(
				smd_pkt_devp->ch_opened_wait_queue,
				smd_pkt_devp->remote_open,
				msecs_to_jiffies(2 * HZ));
		if (r == 0)
			r = -ETIMEDOUT;

		if (r < 0) {
			pr_err("wait returned %d\n", r);
			smd_close(smd_pkt_devp->ch);
			smd_pkt_devp->ch = 0;
		} else {
			smd_pkt_devp->open_count++;
			r = 0;
		}
	}
out:
	mutex_unlock(&smd_pkt_devp->ch_lock);
	return r;
}

static int smd_pkt_release(struct inode *inode, struct file *file)
{
	int r = 0;
	struct smd_pkt_dev *smd_pkt_devp = file->private_data;

	if (!smd_pkt_devp)
		return -EINVAL;

	mutex_lock(&smd_pkt_devp->ch_lock);
	if (--smd_pkt_devp->open_count == 0) {
		r = smd_close(smd_pkt_devp->ch);
		smd_pkt_devp->ch = 0;
	}
	mutex_unlock(&smd_pkt_devp->ch_lock);

	return r;
}

static const struct file_operations smd_pkt_fops = {
	.owner = THIS_MODULE,
	.open = smd_pkt_open,
	.release = smd_pkt_release,
	.read = smd_pkt_read,
	.write = smd_pkt_write,
	.poll = smd_pkt_poll,
};

static int __init smd_pkt_init(void)
{
	int i;
	int r;

	r = alloc_chrdev_region(&smd_pkt_number, 0,
				NUM_SMD_PKT_PORTS, DEVICE_NAME);
	if (r) {
		pr_err("alloc_chrdev_region() failed %d\n", r);
		return r;
	}

	smd_pkt_classp = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(smd_pkt_classp)) {
		r = PTR_ERR(smd_pkt_classp);
		pr_err("class_create() failed %d\n", r);
		goto unreg_chardev;
	}

	for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
		smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev),
					  GFP_KERNEL);
		if (!smd_pkt_devp[i]) {
			pr_err("kmalloc() failed\n");
			goto clean_cdevs;
		}

		smd_pkt_devp[i]->i = i;

		init_waitqueue_head(&smd_pkt_devp[i]->ch_read_wait_queue);
		smd_pkt_devp[i]->remote_open = 0;
		init_waitqueue_head(&smd_pkt_devp[i]->ch_opened_wait_queue);

		mutex_init(&smd_pkt_devp[i]->ch_lock);
		mutex_init(&smd_pkt_devp[i]->rx_lock);
		mutex_init(&smd_pkt_devp[i]->tx_lock);

		cdev_init(&smd_pkt_devp[i]->cdev, &smd_pkt_fops);
		smd_pkt_devp[i]->cdev.owner = THIS_MODULE;

		r = cdev_add(&smd_pkt_devp[i]->cdev,
			     (smd_pkt_number + i), 1);
		if (r) {
			pr_err("cdev_add() failed %d\n", r);
			kfree(smd_pkt_devp[i]);
			goto clean_cdevs;
		}

		smd_pkt_devp[i]->devicep =
			device_create(smd_pkt_classp, NULL,
				      (smd_pkt_number + i), NULL,
				      smd_pkt_dev_name[i]);
		if (IS_ERR(smd_pkt_devp[i]->devicep)) {
			r = PTR_ERR(smd_pkt_devp[i]->devicep);
			pr_err("device_create() failed %d\n", r);
			cdev_del(&smd_pkt_devp[i]->cdev);
			kfree(smd_pkt_devp[i]);
			goto clean_cdevs;
		}

	}

	pr_info("SMD Packet Port Driver Initialized.\n");
	return 0;

clean_cdevs:
	if (i > 0) {
		while (--i >= 0) {
			mutex_destroy(&smd_pkt_devp[i]->ch_lock);
			mutex_destroy(&smd_pkt_devp[i]->rx_lock);
			mutex_destroy(&smd_pkt_devp[i]->tx_lock);
			cdev_del(&smd_pkt_devp[i]->cdev);
			kfree(smd_pkt_devp[i]);
			device_destroy(smd_pkt_classp,
				       MKDEV(MAJOR(smd_pkt_number), i));
		}
	}

	class_destroy(smd_pkt_classp);
unreg_chardev:
	unregister_chrdev_region(MAJOR(smd_pkt_number), NUM_SMD_PKT_PORTS);
	return r;
}
module_init(smd_pkt_init);

static void __exit smd_pkt_cleanup(void)
{
	int i;

	for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
		mutex_destroy(&smd_pkt_devp[i]->ch_lock);
		mutex_destroy(&smd_pkt_devp[i]->rx_lock);
		mutex_destroy(&smd_pkt_devp[i]->tx_lock);
		cdev_del(&smd_pkt_devp[i]->cdev);
		kfree(smd_pkt_devp[i]);
		device_destroy(smd_pkt_classp,
			       MKDEV(MAJOR(smd_pkt_number), i));
	}

	class_destroy(smd_pkt_classp);
	unregister_chrdev_region(MAJOR(smd_pkt_number), NUM_SMD_PKT_PORTS);
}
module_exit(smd_pkt_cleanup);

MODULE_DESCRIPTION("MSM Shared Memory Packet Port");
MODULE_LICENSE("GPL v2");
