/*
 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
 * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
 * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
 * Copyright (C) 2004 IBM Corporation
 *
 * Additional Author(s):
 *  Ryan S. Arnold <rsa@us.ibm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/console.h>
#include <linux/cpumask.h>
#include <linux/init.h>
#include <linux/kbd_kern.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/major.h>
#include <linux/sysrq.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/freezer.h>

#include <asm/uaccess.h>

#include "hvc_console.h"

#define HVC_MAJOR	229
#define HVC_MINOR	0

/*
 * Wait this long per iteration while trying to push buffered data to the
 * hypervisor before allowing the tty to complete a close operation.
 */
#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */

/*
 * These sizes are most efficient for vio, because they are the
 * native transfer size. We could make them selectable in the
 * future to better deal with backends that want other buffer sizes.
 */
#define N_OUTBUF	16
#define N_INBUF		16

#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))

static struct tty_driver *hvc_driver;
static struct task_struct *hvc_task;

/* Picks up late kicks after list walk but before schedule() */
static int hvc_kicked;

#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif

struct hvc_struct {
	spinlock_t lock;
	int index;
	struct tty_struct *tty;
	unsigned int count;
	int do_wakeup;
	char *outbuf;
	int outbuf_size;
	int n_outbuf;
	uint32_t vtermno;
	struct hv_ops *ops;
	int irq_requested;
	int irq;
	struct list_head next;
	struct kobject kobj; /* ref count & hvc_struct lifetime */
};

/* dynamic list of hvc_struct instances */
static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);

/*
 * Protect the list of hvc_struct instances from inserts and removals during
 * list traversal.
 */
static DEFINE_SPINLOCK(hvc_structs_lock);

/*
 * This value is used to assign a tty->index value to a hvc_struct based
 * upon order of exposure via hvc_probe(), when we can not match it to
 * a console candidate registered with hvc_instantiate().
 */
static int last_hvc = -1;

/*
 * Do not call this function with either the hvc_structs_lock or the hvc_struct
 * lock held.  If successful, this function increments the kobject reference
 * count against the target hvc_struct so it should be released when finished.
 */
static struct hvc_struct *hvc_get_by_index(int index)
{
	struct hvc_struct *hp;
	unsigned long flags;

	spin_lock(&hvc_structs_lock);

	list_for_each_entry(hp, &hvc_structs, next) {
		spin_lock_irqsave(&hp->lock, flags);
		if (hp->index == index) {
			kobject_get(&hp->kobj);
			spin_unlock_irqrestore(&hp->lock, flags);
			spin_unlock(&hvc_structs_lock);
			return hp;
		}
		spin_unlock_irqrestore(&hp->lock, flags);
	}
	hp = NULL;

	spin_unlock(&hvc_structs_lock);
	return hp;
}


/*
 * Initial console vtermnos for console API usage prior to full console
 * initialization.  Any vty adapter outside this range will not have usable
 * console interfaces but can still be used as a tty device.  This has to be
 * static because kmalloc will not work during early console init.
 */
static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
	{[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};

/*
 * Console APIs, NOT TTY.  These APIs are available immediately when
 * hvc_console_setup() finds adapters.
 */

static void hvc_console_print(struct console *co, const char *b,
			      unsigned count)
{
	char c[N_OUTBUF] __ALIGNED__;
	unsigned i = 0, n = 0;
	int r, donecr = 0, index = co->index;

	/* Console access attempt outside of acceptable console range. */
	if (index >= MAX_NR_HVC_CONSOLES)
		return;

	/* This console adapter was removed so it is not usable. */
	if (vtermnos[index] < 0)
		return;

	while (count > 0 || i > 0) {
		if (count > 0 && i < sizeof(c)) {
			if (b[n] == '\n' && !donecr) {
				c[i++] = '\r';
				donecr = 1;
			} else {
				c[i++] = b[n++];
				donecr = 0;
				--count;
			}
		} else {
			r = cons_ops[index]->put_chars(vtermnos[index], c, i);
			if (r < 0) {
				/* throw away chars on error */
				i = 0;
			} else if (r > 0) {
				i -= r;
				if (i > 0)
					memmove(c, c+r, i);
			}
		}
	}
}

static struct tty_driver *hvc_console_device(struct console *c, int *index)
{
	if (vtermnos[c->index] == -1)
		return NULL;

	*index = c->index;
	return hvc_driver;
}

static int __init hvc_console_setup(struct console *co, char *options)
{
	if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
		return -ENODEV;

	if (vtermnos[co->index] == -1)
		return -ENODEV;

	return 0;
}

static struct console hvc_con_driver = {
	.name		= "hvc",
	.write		= hvc_console_print,
	.device		= hvc_console_device,
	.setup		= hvc_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
};

/*
 * Early console initialization.  Precedes driver initialization.
 *
 * (1) we are first, and the user specified another driver
 * -- index will remain -1
 * (2) we are first and the user specified no driver
 * -- index will be set to 0, then we will fail setup.
 * (3)  we are first and the user specified our driver
 * -- index will be set to user specified driver, and we will fail
 * (4) we are after driver, and this initcall will register us
 * -- if the user didn't specify a driver then the console will match
 *
 * Note that for cases 2 and 3, we will match later when the io driver
 * calls hvc_instantiate() and call register again.
 */
static int __init hvc_console_init(void)
{
	register_console(&hvc_con_driver);
	return 0;
}
console_initcall(hvc_console_init);

/*
 * hvc_instantiate() is an early console discovery method which locates
 * consoles * prior to the vio subsystem discovering them.  Hotplugged
 * vty adapters do NOT get an hvc_instantiate() callback since they
 * appear after early console init.
 */
int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
{
	struct hvc_struct *hp;

	if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
		return -1;

	if (vtermnos[index] != -1)
		return -1;

	/* make sure no no tty has been registered in this index */
	hp = hvc_get_by_index(index);
	if (hp) {
		kobject_put(&hp->kobj);
		return -1;
	}

	vtermnos[index] = vtermno;
	cons_ops[index] = ops;

	/* reserve all indices up to and including this index */
	if (last_hvc < index)
		last_hvc = index;

	/* if this index is what the user requested, then register
	 * now (setup won't fail at this point).  It's ok to just
	 * call register again if previously .setup failed.
	 */
	if (index == hvc_con_driver.index)
		register_console(&hvc_con_driver);

	return 0;
}

/* Wake the sleeping khvcd */
static void hvc_kick(void)
{
	hvc_kicked = 1;
	wake_up_process(hvc_task);
}

static int hvc_poll(struct hvc_struct *hp);

/*
 * NOTE: This API isn't used if the console adapter doesn't support interrupts.
 * In this case the console is poll driven.
 */
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
{
	/* if hvc_poll request a repoll, then kick the hvcd thread */
	if (hvc_poll(dev_instance))
		hvc_kick();
	return IRQ_HANDLED;
}

static void hvc_unthrottle(struct tty_struct *tty)
{
	hvc_kick();
}

/*
 * The TTY interface won't be used until after the vio layer has exposed the vty
 * adapter to the kernel.
 */
static int hvc_open(struct tty_struct *tty, struct file * filp)
{
	struct hvc_struct *hp;
	unsigned long flags;
	int irq = 0;
	int rc = 0;
	struct kobject *kobjp;

	/* Auto increments kobject reference if found. */
	if (!(hp = hvc_get_by_index(tty->index)))
		return -ENODEV;

	spin_lock_irqsave(&hp->lock, flags);
	/* Check and then increment for fast path open. */
	if (hp->count++ > 0) {
		spin_unlock_irqrestore(&hp->lock, flags);
		hvc_kick();
		return 0;
	} /* else count == 0 */

	tty->driver_data = hp;
	tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */

	hp->tty = tty;
	/* Save for request_irq outside of spin_lock. */
	irq = hp->irq;
	if (irq)
		hp->irq_requested = 1;

	kobjp = &hp->kobj;

	spin_unlock_irqrestore(&hp->lock, flags);
	/* check error, fallback to non-irq */
	if (irq)
		rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp);

	/*
	 * If the request_irq() fails and we return an error.  The tty layer
	 * will call hvc_close() after a failed open but we don't want to clean
	 * up there so we'll clean up here and clear out the previously set
	 * tty fields and return the kobject reference.
	 */
	if (rc) {
		spin_lock_irqsave(&hp->lock, flags);
		hp->tty = NULL;
		hp->irq_requested = 0;
		spin_unlock_irqrestore(&hp->lock, flags);
		tty->driver_data = NULL;
		kobject_put(kobjp);
		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
	}
	/* Force wakeup of the polling thread */
	hvc_kick();

	return rc;
}

static void hvc_close(struct tty_struct *tty, struct file * filp)
{
	struct hvc_struct *hp;
	struct kobject *kobjp;
	int irq = 0;
	unsigned long flags;

	if (tty_hung_up_p(filp))
		return;

	/*
	 * No driver_data means that this close was issued after a failed
	 * hvc_open by the tty layer's release_dev() function and we can just
	 * exit cleanly because the kobject reference wasn't made.
	 */
	if (!tty->driver_data)
		return;

	hp = tty->driver_data;
	spin_lock_irqsave(&hp->lock, flags);

	kobjp = &hp->kobj;
	if (--hp->count == 0) {
		if (hp->irq_requested)
			irq = hp->irq;
		hp->irq_requested = 0;

		/* We are done with the tty pointer now. */
		hp->tty = NULL;
		spin_unlock_irqrestore(&hp->lock, flags);

		/*
		 * Chain calls chars_in_buffer() and returns immediately if
		 * there is no buffered data otherwise sleeps on a wait queue
		 * waking periodically to check chars_in_buffer().
		 */
		tty_wait_until_sent(tty, HVC_CLOSE_WAIT);

		if (irq)
			free_irq(irq, hp);

	} else {
		if (hp->count < 0)
			printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
				hp->vtermno, hp->count);
		spin_unlock_irqrestore(&hp->lock, flags);
	}

	kobject_put(kobjp);
}

static void hvc_hangup(struct tty_struct *tty)
{
	struct hvc_struct *hp = tty->driver_data;
	unsigned long flags;
	int irq = 0;
	int temp_open_count;
	struct kobject *kobjp;

	if (!hp)
		return;

	spin_lock_irqsave(&hp->lock, flags);

	/*
	 * The N_TTY line discipline has problems such that in a close vs
	 * open->hangup case this can be called after the final close so prevent
	 * that from happening for now.
	 */
	if (hp->count <= 0) {
		spin_unlock_irqrestore(&hp->lock, flags);
		return;
	}

	kobjp = &hp->kobj;
	temp_open_count = hp->count;
	hp->count = 0;
	hp->n_outbuf = 0;
	hp->tty = NULL;
	if (hp->irq_requested)
		/* Saved for use outside of spin_lock. */
		irq = hp->irq;
	hp->irq_requested = 0;
	spin_unlock_irqrestore(&hp->lock, flags);
	if (irq)
		free_irq(irq, hp);
	while(temp_open_count) {
		--temp_open_count;
		kobject_put(kobjp);
	}
}

/*
 * Push buffered characters whether they were just recently buffered or waiting
 * on a blocked hypervisor.  Call this function with hp->lock held.
 */
static void hvc_push(struct hvc_struct *hp)
{
	int n;

	n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
	if (n <= 0) {
		if (n == 0) {
			hp->do_wakeup = 1;
			return;
		}
		/* throw away output on error; this happens when
		   there is no session connected to the vterm. */
		hp->n_outbuf = 0;
	} else
		hp->n_outbuf -= n;
	if (hp->n_outbuf > 0)
		memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
	else
		hp->do_wakeup = 1;
}

static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
	struct hvc_struct *hp = tty->driver_data;
	unsigned long flags;
	int rsize, written = 0;

	/* This write was probably executed during a tty close. */
	if (!hp)
		return -EPIPE;

	if (hp->count <= 0)
		return -EIO;

	spin_lock_irqsave(&hp->lock, flags);

	/* Push pending writes */
	if (hp->n_outbuf > 0)
		hvc_push(hp);

	while (count > 0 && (rsize = hp->outbuf_size - hp->n_outbuf) > 0) {
		if (rsize > count)
			rsize = count;
		memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
		count -= rsize;
		buf += rsize;
		hp->n_outbuf += rsize;
		written += rsize;
		hvc_push(hp);
	}
	spin_unlock_irqrestore(&hp->lock, flags);

	/*
	 * Racy, but harmless, kick thread if there is still pending data.
	 */
	if (hp->n_outbuf)
		hvc_kick();

	return written;
}

/*
 * This is actually a contract between the driver and the tty layer outlining
 * how much write room the driver can guarantee will be sent OR BUFFERED.  This
 * driver MUST honor the return value.
 */
static int hvc_write_room(struct tty_struct *tty)
{
	struct hvc_struct *hp = tty->driver_data;

	if (!hp)
		return -1;

	return hp->outbuf_size - hp->n_outbuf;
}

static int hvc_chars_in_buffer(struct tty_struct *tty)
{
	struct hvc_struct *hp = tty->driver_data;

	if (!hp)
		return -1;
	return hp->n_outbuf;
}

/*
 * timeout will vary between the MIN and MAX values defined here.  By default
 * and during console activity we will use a default MIN_TIMEOUT of 10.  When
 * the console is idle, we increase the timeout value on each pass through
 * msleep until we reach the max.  This may be noticeable as a brief (average
 * one second) delay on the console before the console responds to input when
 * there has been no input for some time.
 */
#define MIN_TIMEOUT		(10)
#define MAX_TIMEOUT		(2000)
static u32 timeout = MIN_TIMEOUT;

#define HVC_POLL_READ	0x00000001
#define HVC_POLL_WRITE	0x00000002

static int hvc_poll(struct hvc_struct *hp)
{
	struct tty_struct *tty;
	int i, n, poll_mask = 0;
	char buf[N_INBUF] __ALIGNED__;
	unsigned long flags;
	int read_total = 0;

	spin_lock_irqsave(&hp->lock, flags);

	/* Push pending writes */
	if (hp->n_outbuf > 0)
		hvc_push(hp);

	/* Reschedule us if still some write pending */
	if (hp->n_outbuf > 0)
		poll_mask |= HVC_POLL_WRITE;

	/* No tty attached, just skip */
	tty = hp->tty;
	if (tty == NULL)
		goto bail;

	/* Now check if we can get data (are we throttled ?) */
	if (test_bit(TTY_THROTTLED, &tty->flags))
		goto throttled;

	/* If we aren't interrupt driven and aren't throttled, we always
	 * request a reschedule
	 */
	if (hp->irq == 0)
		poll_mask |= HVC_POLL_READ;

	/* Read data if any */
	for (;;) {
		int count = tty_buffer_request_room(tty, N_INBUF);

		/* If flip is full, just reschedule a later read */
		if (count == 0) {
			poll_mask |= HVC_POLL_READ;
			break;
		}

		n = hp->ops->get_chars(hp->vtermno, buf, count);
		if (n <= 0) {
			/* Hangup the tty when disconnected from host */
			if (n == -EPIPE) {
				spin_unlock_irqrestore(&hp->lock, flags);
				tty_hangup(tty);
				spin_lock_irqsave(&hp->lock, flags);
			} else if ( n == -EAGAIN ) {
				/*
				 * Some back-ends can only ensure a certain min
				 * num of bytes read, which may be > 'count'.
				 * Let the tty clear the flip buff to make room.
				 */
				poll_mask |= HVC_POLL_READ;
			}
			break;
		}
		for (i = 0; i < n; ++i) {
#ifdef CONFIG_MAGIC_SYSRQ
			if (hp->index == hvc_con_driver.index) {
				/* Handle the SysRq Hack */
				/* XXX should support a sequence */
				if (buf[i] == '\x0f') {	/* ^O */
					sysrq_pressed = 1;
					continue;
				} else if (sysrq_pressed) {
					handle_sysrq(buf[i], tty);
					sysrq_pressed = 0;
					continue;
				}
			}
#endif /* CONFIG_MAGIC_SYSRQ */
			tty_insert_flip_char(tty, buf[i], 0);
		}

		read_total += n;
	}
 throttled:
	/* Wakeup write queue if necessary */
	if (hp->do_wakeup) {
		hp->do_wakeup = 0;
		tty_wakeup(tty);
	}
 bail:
	spin_unlock_irqrestore(&hp->lock, flags);

	if (read_total) {
		/* Activity is occurring, so reset the polling backoff value to
		   a minimum for performance. */
		timeout = MIN_TIMEOUT;

		tty_flip_buffer_push(tty);
	}

	return poll_mask;
}

#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
extern cpumask_t cpus_in_xmon;
#else
static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
#endif

/*
 * This kthread is either polling or interrupt driven.  This is determined by
 * calling hvc_poll() who determines whether a console adapter support
 * interrupts.
 */
int khvcd(void *unused)
{
	int poll_mask;
	struct hvc_struct *hp;

	__set_current_state(TASK_RUNNING);
	do {
		poll_mask = 0;
		hvc_kicked = 0;
		try_to_freeze();
		wmb();
		if (cpus_empty(cpus_in_xmon)) {
			spin_lock(&hvc_structs_lock);
			list_for_each_entry(hp, &hvc_structs, next) {
				poll_mask |= hvc_poll(hp);
			}
			spin_unlock(&hvc_structs_lock);
		} else
			poll_mask |= HVC_POLL_READ;
		if (hvc_kicked)
			continue;
		if (poll_mask & HVC_POLL_WRITE) {
			yield();
			continue;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		if (!hvc_kicked) {
			if (poll_mask == 0)
				schedule();
			else {
				if (timeout < MAX_TIMEOUT)
					timeout += (timeout >> 6) + 1;

				msleep_interruptible(timeout);
			}
		}
		__set_current_state(TASK_RUNNING);
	} while (!kthread_should_stop());

	return 0;
}

static const struct tty_operations hvc_ops = {
	.open = hvc_open,
	.close = hvc_close,
	.write = hvc_write,
	.hangup = hvc_hangup,
	.unthrottle = hvc_unthrottle,
	.write_room = hvc_write_room,
	.chars_in_buffer = hvc_chars_in_buffer,
};

/* callback when the kboject ref count reaches zero. */
static void destroy_hvc_struct(struct kobject *kobj)
{
	struct hvc_struct *hp = container_of(kobj, struct hvc_struct, kobj);
	unsigned long flags;

	spin_lock(&hvc_structs_lock);

	spin_lock_irqsave(&hp->lock, flags);
	list_del(&(hp->next));
	spin_unlock_irqrestore(&hp->lock, flags);

	spin_unlock(&hvc_structs_lock);

	kfree(hp);
}

static struct kobj_type hvc_kobj_type = {
	.release = destroy_hvc_struct,
};

struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
					struct hv_ops *ops, int outbuf_size)
{
	struct hvc_struct *hp;
	int i;

	hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
			GFP_KERNEL);
	if (!hp)
		return ERR_PTR(-ENOMEM);

	memset(hp, 0x00, sizeof(*hp));

	hp->vtermno = vtermno;
	hp->irq = irq;
	hp->ops = ops;
	hp->outbuf_size = outbuf_size;
	hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];

	kobject_init(&hp->kobj);
	hp->kobj.ktype = &hvc_kobj_type;

	spin_lock_init(&hp->lock);
	spin_lock(&hvc_structs_lock);

	/*
	 * find index to use:
	 * see if this vterm id matches one registered for console.
	 */
	for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
		if (vtermnos[i] == hp->vtermno &&
		    cons_ops[i] == hp->ops)
			break;

	/* no matching slot, just use a counter */
	if (i >= MAX_NR_HVC_CONSOLES)
		i = ++last_hvc;

	hp->index = i;

	list_add_tail(&(hp->next), &hvc_structs);
	spin_unlock(&hvc_structs_lock);

	return hp;
}

int __devexit hvc_remove(struct hvc_struct *hp)
{
	unsigned long flags;
	struct kobject *kobjp;
	struct tty_struct *tty;

	spin_lock_irqsave(&hp->lock, flags);
	tty = hp->tty;
	kobjp = &hp->kobj;

	if (hp->index < MAX_NR_HVC_CONSOLES)
		vtermnos[hp->index] = -1;

	/* Don't whack hp->irq because tty_hangup() will need to free the irq. */

	spin_unlock_irqrestore(&hp->lock, flags);

	/*
	 * We 'put' the instance that was grabbed when the kobject instance
	 * was initialized using kobject_init().  Let the last holder of this
	 * kobject cause it to be removed, which will probably be the tty_hangup
	 * below.
	 */
	kobject_put(kobjp);

	/*
	 * This function call will auto chain call hvc_hangup.  The tty should
	 * always be valid at this time unless a simultaneous tty close already
	 * cleaned up the hvc_struct.
	 */
	if (tty)
		tty_hangup(tty);
	return 0;
}

/* Driver initialization.  Follow console initialization.  This is where the TTY
 * interfaces start to become available. */
static int __init hvc_init(void)
{
	struct tty_driver *drv;

	/* We need more than hvc_count adapters due to hotplug additions. */
	drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
	if (!drv)
		return -ENOMEM;

	drv->owner = THIS_MODULE;
	drv->driver_name = "hvc";
	drv->name = "hvc";
	drv->major = HVC_MAJOR;
	drv->minor_start = HVC_MINOR;
	drv->type = TTY_DRIVER_TYPE_SYSTEM;
	drv->init_termios = tty_std_termios;
	drv->flags = TTY_DRIVER_REAL_RAW;
	tty_set_operations(drv, &hvc_ops);

	/* Always start the kthread because there can be hotplug vty adapters
	 * added later. */
	hvc_task = kthread_run(khvcd, NULL, "khvcd");
	if (IS_ERR(hvc_task)) {
		panic("Couldn't create kthread for console.\n");
		put_tty_driver(drv);
		return -EIO;
	}

	if (tty_register_driver(drv))
		panic("Couldn't register hvc console driver\n");

	mb();
	hvc_driver = drv;
	return 0;
}
module_init(hvc_init);

/* This isn't particularly necessary due to this being a console driver
 * but it is nice to be thorough.
 */
static void __exit hvc_exit(void)
{
	kthread_stop(hvc_task);

	tty_unregister_driver(hvc_driver);
	/* return tty_struct instances allocated in hvc_init(). */
	put_tty_driver(hvc_driver);
	unregister_console(&hvc_con_driver);
}
module_exit(hvc_exit);
