/*
 * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
 * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org)
 *
 *  This program is free software; you can distribute 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 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.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/seq_file.h>
#include <linux/syscalls.h>
#include <linux/moduleloader.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <asm/mipsmtregs.h>
#include <asm/cacheflush.h>
#include <asm/atomic.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/vpe.h>
#include <asm/rtlx.h>

#define RTLX_TARG_VPE 1

static struct rtlx_info *rtlx;
static int major;
static char module_name[] = "rtlx";

static struct chan_waitqueues {
	wait_queue_head_t rt_queue;
	wait_queue_head_t lx_queue;
	int in_open;
} channel_wqs[RTLX_CHANNELS];

static struct irqaction irq;
static int irq_num;
static struct vpe_notifications notify;
static int sp_stopping = 0;

extern void *vpe_get_shared(int index);

static void rtlx_dispatch(void)
{
	do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ);
}


/* Interrupt handler may be called before rtlx_init has otherwise had
   a chance to run.
*/
static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
{
	int i;

	for (i = 0; i < RTLX_CHANNELS; i++) {
			wake_up(&channel_wqs[i].lx_queue);
			wake_up(&channel_wqs[i].rt_queue);
	}

	return IRQ_HANDLED;
}

static __attribute_used__ void dump_rtlx(void)
{
	int i;

	printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);

	for (i = 0; i < RTLX_CHANNELS; i++) {
		struct rtlx_channel *chan = &rtlx->channel[i];

		printk(" rt_state %d lx_state %d buffer_size %d\n",
		       chan->rt_state, chan->lx_state, chan->buffer_size);

		printk(" rt_read %d rt_write %d\n",
		       chan->rt_read, chan->rt_write);

		printk(" lx_read %d lx_write %d\n",
		       chan->lx_read, chan->lx_write);

		printk(" rt_buffer <%s>\n", chan->rt_buffer);
		printk(" lx_buffer <%s>\n", chan->lx_buffer);
	}
}

/* call when we have the address of the shared structure from the SP side. */
static int rtlx_init(struct rtlx_info *rtlxi)
{
	if (rtlxi->id != RTLX_ID) {
		printk(KERN_ERR "no valid RTLX id at 0x%p 0x%x\n", rtlxi, rtlxi->id);
		return -ENOEXEC;
	}

	rtlx = rtlxi;

	return 0;
}

/* notifications */
static void starting(int vpe)
{
	int i;
	sp_stopping = 0;

	/* force a reload of rtlx */
	rtlx=NULL;

	/* wake up any sleeping rtlx_open's */
	for (i = 0; i < RTLX_CHANNELS; i++)
		wake_up_interruptible(&channel_wqs[i].lx_queue);
}

static void stopping(int vpe)
{
	int i;

	sp_stopping = 1;
	for (i = 0; i < RTLX_CHANNELS; i++)
		wake_up_interruptible(&channel_wqs[i].lx_queue);
}


int rtlx_open(int index, int can_sleep)
{
	int ret;
	struct rtlx_channel *chan;
	volatile struct rtlx_info **p;

	if (index >= RTLX_CHANNELS) {
		printk(KERN_DEBUG "rtlx_open index out of range\n");
		return -ENOSYS;
	}

	if (channel_wqs[index].in_open) {
		printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index);
		return -EBUSY;
	}

	channel_wqs[index].in_open++;

	if (rtlx == NULL) {
		if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
			if (can_sleep) {
				DECLARE_WAITQUEUE(wait, current);

				/* go to sleep */
				add_wait_queue(&channel_wqs[index].lx_queue, &wait);

				set_current_state(TASK_INTERRUPTIBLE);
				while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
					schedule();
					set_current_state(TASK_INTERRUPTIBLE);
				}

				set_current_state(TASK_RUNNING);
				remove_wait_queue(&channel_wqs[index].lx_queue, &wait);

				/* back running */
			} else {
				printk( KERN_DEBUG "No SP program loaded, and device "
					"opened with O_NONBLOCK\n");
				channel_wqs[index].in_open = 0;
				return -ENOSYS;
			}
		}

		if (*p == NULL) {
			if (can_sleep) {
				DECLARE_WAITQUEUE(wait, current);

				/* go to sleep */
				add_wait_queue(&channel_wqs[index].lx_queue, &wait);

				set_current_state(TASK_INTERRUPTIBLE);
				while (*p == NULL) {
					schedule();

					/* reset task state to interruptable otherwise
					   we'll whizz round here like a very fast loopy
					   thing. schedule() appears to return with state
					   set to TASK_RUNNING.

					   If the loaded SP program, for whatever reason,
					   doesn't set up the shared structure *p will never
					   become true. So whoever connected to either /dev/rt?
					   or if it was kspd, will then take up rather a lot of
					   processor cycles.
					*/

					set_current_state(TASK_INTERRUPTIBLE);
				}

				set_current_state(TASK_RUNNING);
				remove_wait_queue(&channel_wqs[index].lx_queue, &wait);

				/* back running */
			}
			else {
				printk(" *vpe_get_shared is NULL. "
				       "Has an SP program been loaded?\n");
				channel_wqs[index].in_open = 0;
				return -ENOSYS;
			}
		}

		if ((unsigned int)*p < KSEG0) {
			printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
			       "maybe an error code %d\n", (int)*p);
 			channel_wqs[index].in_open = 0;
			return -ENOSYS;
		}

 		if ((ret = rtlx_init(*p)) < 0) {
 			channel_wqs[index].in_open = 0;
  			return ret;
 		}
	}

	chan = &rtlx->channel[index];

 	if (chan->lx_state == RTLX_STATE_OPENED) {
 		channel_wqs[index].in_open = 0;
  		return -EBUSY;
 	}

  	chan->lx_state = RTLX_STATE_OPENED;
 	channel_wqs[index].in_open = 0;
	return 0;
}

int rtlx_release(int index)
{
	rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
	return 0;
}

unsigned int rtlx_read_poll(int index, int can_sleep)
{
 	struct rtlx_channel *chan;

 	if (rtlx == NULL)
 		return 0;

 	chan = &rtlx->channel[index];

	/* data available to read? */
	if (chan->lx_read == chan->lx_write) {
		if (can_sleep) {
			DECLARE_WAITQUEUE(wait, current);

			/* go to sleep */
			add_wait_queue(&channel_wqs[index].lx_queue, &wait);

			set_current_state(TASK_INTERRUPTIBLE);
			while (chan->lx_read == chan->lx_write) {
				schedule();

				set_current_state(TASK_INTERRUPTIBLE);

				if (sp_stopping) {
					set_current_state(TASK_RUNNING);
					remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
					return 0;
				}
			}

			set_current_state(TASK_RUNNING);
			remove_wait_queue(&channel_wqs[index].lx_queue, &wait);

			/* back running */
		}
		else
			return 0;
	}

	return (chan->lx_write + chan->buffer_size - chan->lx_read)
	       % chan->buffer_size;
}

static inline int write_spacefree(int read, int write, int size)
{
	if (read == write) {
		/*
		 * Never fill the buffer completely, so indexes are always
		 * equal if empty and only empty, or !equal if data available
		 */
		return size - 1;
	}

	return ((read + size - write) % size) - 1;
}

unsigned int rtlx_write_poll(int index)
{
	struct rtlx_channel *chan = &rtlx->channel[index];
	return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
}

static inline void copy_to(void *dst, void *src, size_t count, int user)
{
	if (user)
		copy_to_user(dst, src, count);
	else
		memcpy(dst, src, count);
}

static inline void copy_from(void *dst, void *src, size_t count, int user)
{
	if (user)
		copy_from_user(dst, src, count);
	else
		memcpy(dst, src, count);
}

ssize_t rtlx_read(int index, void *buff, size_t count, int user)
{
	size_t fl = 0L;
	struct rtlx_channel *lx;

	if (rtlx == NULL)
		return -ENOSYS;

	lx = &rtlx->channel[index];

	/* find out how much in total */
	count = min(count,
		     (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read)
		     % lx->buffer_size);

	/* then how much from the read pointer onwards */
	fl = min( count, (size_t)lx->buffer_size - lx->lx_read);

	copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user);

	/* and if there is anything left at the beginning of the buffer */
	if ( count - fl )
		copy_to (buff + fl, lx->lx_buffer, count - fl, user);

	/* update the index */
	lx->lx_read += count;
	lx->lx_read %= lx->buffer_size;

	return count;
}

ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
{
	struct rtlx_channel *rt;
	size_t fl;

	if (rtlx == NULL)
		return(-ENOSYS);

	rt = &rtlx->channel[index];

	/* total number of bytes to copy */
	count = min(count,
		    (size_t)write_spacefree(rt->rt_read, rt->rt_write,
					    rt->buffer_size));

	/* first bit from write pointer to the end of the buffer, or count */
	fl = min(count, (size_t) rt->buffer_size - rt->rt_write);

	copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user);

	/* if there's any left copy to the beginning of the buffer */
	if( count - fl )
		copy_from (rt->rt_buffer, buffer + fl, count - fl, user);

	rt->rt_write += count;
	rt->rt_write %= rt->buffer_size;

	return(count);
}


static int file_open(struct inode *inode, struct file *filp)
{
	int minor = iminor(inode);

	return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
}

static int file_release(struct inode *inode, struct file *filp)
{
	int minor = iminor(inode);

	return rtlx_release(minor);
}

static unsigned int file_poll(struct file *file, poll_table * wait)
{
	int minor;
	unsigned int mask = 0;

	minor = iminor(file->f_dentry->d_inode);

	poll_wait(file, &channel_wqs[minor].rt_queue, wait);
	poll_wait(file, &channel_wqs[minor].lx_queue, wait);

	if (rtlx == NULL)
		return 0;

	/* data available to read? */
	if (rtlx_read_poll(minor, 0))
		mask |= POLLIN | POLLRDNORM;

	/* space to write */
	if (rtlx_write_poll(minor))
		mask |= POLLOUT | POLLWRNORM;

	return mask;
}

static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
			 loff_t * ppos)
{
	int minor = iminor(file->f_dentry->d_inode);

	/* data available? */
	if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) {
		return 0;	// -EAGAIN makes cat whinge
	}

	return rtlx_read(minor, buffer, count, 1);
}

static ssize_t file_write(struct file *file, const char __user * buffer,
			  size_t count, loff_t * ppos)
{
	int minor;
	struct rtlx_channel *rt;
	DECLARE_WAITQUEUE(wait, current);

	minor = iminor(file->f_dentry->d_inode);
	rt = &rtlx->channel[minor];

	/* any space left... */
	if (!rtlx_write_poll(minor)) {

		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;

		add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
		set_current_state(TASK_INTERRUPTIBLE);

		while (!rtlx_write_poll(minor))
			schedule();

		set_current_state(TASK_RUNNING);
		remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
	}

	return rtlx_write(minor, (void *)buffer, count, 1);
}

static struct file_operations rtlx_fops = {
	.owner =   THIS_MODULE,
	.open =    file_open,
	.release = file_release,
	.write =   file_write,
	.read =    file_read,
	.poll =    file_poll
};

static struct irqaction rtlx_irq = {
	.handler	= rtlx_interrupt,
	.flags		= IRQF_DISABLED,
	.name		= "RTLX",
};

static int rtlx_irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;

static char register_chrdev_failed[] __initdata =
	KERN_ERR "rtlx_module_init: unable to register device\n";

static int rtlx_module_init(void)
{
	int i;

	major = register_chrdev(0, module_name, &rtlx_fops);
	if (major < 0) {
		printk(register_chrdev_failed);
		return major;
	}

	/* initialise the wait queues */
	for (i = 0; i < RTLX_CHANNELS; i++) {
		init_waitqueue_head(&channel_wqs[i].rt_queue);
		init_waitqueue_head(&channel_wqs[i].lx_queue);
		channel_wqs[i].in_open = 0;
	}

	/* set up notifiers */
	notify.start = starting;
	notify.stop = stopping;
	vpe_notify(RTLX_TARG_VPE, &notify);

	if (cpu_has_vint)
		set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);

	rtlx_irq.dev_id = rtlx;
	setup_irq(rtlx_irq_num, &rtlx_irq);

	return 0;
}

static void __exit rtlx_module_exit(void)
{
	unregister_chrdev(major, module_name);
}

module_init(rtlx_module_init);
module_exit(rtlx_module_exit);

MODULE_DESCRIPTION("MIPS RTLX");
MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
MODULE_LICENSE("GPL");
