// SPDX-License-Identifier: GPL-2.0+
/*
 * 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>
 */

#include <linux/console.h>
#include <linux/cpumask.h>
#include <linux/init.h>
#include <linux/kbd_kern.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/major.h>
#include <linux/atomic.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 <linux/slab.h>
#include <linux/serial_core.h>

#include <linux/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;

/* hvc_init is triggered from hvc_alloc, i.e. only when actually used */
static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1);

static int hvc_init(void);

#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif

/* dynamic list of hvc_struct instances */
static LIST_HEAD(hvc_structs);

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

/* Mutex to serialize hvc_open */
static DEFINE_MUTEX(hvc_open_mutex);
/*
 * 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_mutex or the hvc_struct
 * lock held.  If successful, this function increments the kref 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;

	mutex_lock(&hvc_structs_mutex);

	list_for_each_entry(hp, &hvc_structs, next) {
		spin_lock_irqsave(&hp->lock, flags);
		if (hp->index == index) {
			tty_port_get(&hp->port);
			spin_unlock_irqrestore(&hp->lock, flags);
			mutex_unlock(&hvc_structs_mutex);
			return hp;
		}
		spin_unlock_irqrestore(&hp->lock, flags);
	}
	hp = NULL;
	mutex_unlock(&hvc_structs_mutex);

	return hp;
}

static int __hvc_flush(const struct hv_ops *ops, uint32_t vtermno, bool wait)
{
	if (wait)
		might_sleep();

	if (ops->flush)
		return ops->flush(vtermno, wait);
	return 0;
}

static int hvc_console_flush(const struct hv_ops *ops, uint32_t vtermno)
{
	return __hvc_flush(ops, vtermno, false);
}

/*
 * Wait for the console to flush before writing more to it. This sleeps.
 */
static int hvc_flush(struct hvc_struct *hp)
{
	return __hvc_flush(hp->ops, hp->vtermno, true);
}

/*
 * 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 const 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] == -1)
		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 characters on error
				 * but spin in case of -EAGAIN */
				if (r != -EAGAIN) {
					i = 0;
				} else {
					hvc_console_flush(cons_ops[index],
						      vtermnos[index]);
				}
			} else if (r > 0) {
				i -= r;
				if (i > 0)
					memmove(c, c+r, i);
			}
		}
	}
	hvc_console_flush(cons_ops[index], vtermnos[index]);
}

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 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_console = {
	.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_console);
	return 0;
}
console_initcall(hvc_console_init);

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

	mutex_lock(&hvc_structs_mutex);

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

	mutex_unlock(&hvc_structs_mutex);

	kfree(hp);
}

static void hvc_check_console(int index)
{
	/* Already enabled, bail out */
	if (hvc_console.flags & CON_ENABLED)
		return;

 	/* 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_console.index)
		register_console(&hvc_console);
}

/*
 * 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, const 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) {
		tty_port_put(&hp->port);
		return -1;
	}

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

	/* check if we need to re-register the kernel console */
	hvc_check_console(index);

	return 0;
}
EXPORT_SYMBOL_GPL(hvc_instantiate);

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

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

static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct hvc_struct *hp;
	int rc;

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

	tty->driver_data = hp;

	rc = tty_port_install(&hp->port, driver, tty);
	if (rc)
		tty_port_put(&hp->port);
	return rc;
}

/*
 * 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 rc = 0;

	mutex_lock(&hvc_open_mutex);

	hp = tty->driver_data;
	if (!hp) {
		rc = -EIO;
		goto out;
	}

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

	tty_port_tty_set(&hp->port, tty);

	if (hp->ops->notifier_add)
		rc = hp->ops->notifier_add(hp, hp->data);

	/*
	 * If the notifier fails 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 kref reference.
	 */
	if (rc) {
		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
	} else {
		/* We are ready... raise DTR/RTS */
		if (C_BAUD(tty))
			if (hp->ops->dtr_rts)
				hp->ops->dtr_rts(hp, 1);
		tty_port_set_initialized(&hp->port, true);
	}

	/* Force wakeup of the polling thread */
	hvc_kick();

out:
	mutex_unlock(&hvc_open_mutex);
	return rc;
}

static void hvc_close(struct tty_struct *tty, struct file * filp)
{
	struct hvc_struct *hp = tty->driver_data;
	unsigned long flags;

	if (tty_hung_up_p(filp))
		return;

	spin_lock_irqsave(&hp->port.lock, flags);

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

		if (!tty_port_initialized(&hp->port))
			return;

		if (C_HUPCL(tty))
			if (hp->ops->dtr_rts)
				hp->ops->dtr_rts(hp, 0);

		if (hp->ops->notifier_del)
			hp->ops->notifier_del(hp, hp->data);

		/* cancel pending tty resize work */
		cancel_work_sync(&hp->tty_resize);

		/*
		 * 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);
		tty_port_set_initialized(&hp->port, false);
	} else {
		if (hp->port.count < 0)
			printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
				hp->vtermno, hp->port.count);
		spin_unlock_irqrestore(&hp->port.lock, flags);
	}
}

static void hvc_cleanup(struct tty_struct *tty)
{
	struct hvc_struct *hp = tty->driver_data;

	tty_port_put(&hp->port);
}

static void hvc_hangup(struct tty_struct *tty)
{
	struct hvc_struct *hp = tty->driver_data;
	unsigned long flags;

	if (!hp)
		return;

	/* cancel pending tty resize work */
	cancel_work_sync(&hp->tty_resize);

	spin_lock_irqsave(&hp->port.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->port.count <= 0) {
		spin_unlock_irqrestore(&hp->port.lock, flags);
		return;
	}

	hp->port.count = 0;
	spin_unlock_irqrestore(&hp->port.lock, flags);
	tty_port_tty_set(&hp->port, NULL);

	hp->n_outbuf = 0;

	if (hp->ops->notifier_hangup)
		hp->ops->notifier_hangup(hp, hp->data);
}

/*
 * Push buffered characters whether they were just recently buffered or waiting
 * on a blocked hypervisor.  Call this function with hp->lock held.
 */
static int 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 || n == -EAGAIN) {
			hp->do_wakeup = 1;
			return 0;
		}
		/* 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;

	return n;
}

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;

	/* FIXME what's this (unprotected) check for? */
	if (hp->port.count <= 0)
		return -EIO;

	while (count > 0) {
		int ret = 0;

		spin_lock_irqsave(&hp->lock, flags);

		rsize = hp->outbuf_size - hp->n_outbuf;

		if (rsize) {
			if (rsize > count)
				rsize = count;
			memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
			count -= rsize;
			buf += rsize;
			hp->n_outbuf += rsize;
			written += rsize;
		}

		if (hp->n_outbuf > 0)
			ret = hvc_push(hp);

		spin_unlock_irqrestore(&hp->lock, flags);

		if (!ret)
			break;

		if (count) {
			if (hp->n_outbuf > 0)
				hvc_flush(hp);
			cond_resched();
		}
	}

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

	return written;
}

/**
 * hvc_set_winsz() - Resize the hvc tty terminal window.
 * @work:	work structure.
 *
 * The routine shall not be called within an atomic context because it
 * might sleep.
 *
 * Locking:	hp->lock
 */
static void hvc_set_winsz(struct work_struct *work)
{
	struct hvc_struct *hp;
	unsigned long hvc_flags;
	struct tty_struct *tty;
	struct winsize ws;

	hp = container_of(work, struct hvc_struct, tty_resize);

	tty = tty_port_tty_get(&hp->port);
	if (!tty)
		return;

	spin_lock_irqsave(&hp->lock, hvc_flags);
	ws = hp->ws;
	spin_unlock_irqrestore(&hp->lock, hvc_flags);

	tty_do_resize(tty, &ws);
	tty_kref_put(tty);
}

/*
 * 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 0;

	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 0;
	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;

/*
 * Maximum number of bytes to get from the console driver if hvc_poll is
 * called from driver (and can't sleep). Any more than this and we break
 * and start polling with khvcd. This value was derived from from an OpenBMC
 * console with the OPAL driver that results in about 0.25ms interrupts off
 * latency.
 */
#define HVC_ATOMIC_READ_MAX	128

#define HVC_POLL_READ	0x00000001
#define HVC_POLL_WRITE	0x00000002

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

	spin_lock_irqsave(&hp->lock, flags);

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

	/* Reschedule us if still some write pending */
	if (hp->n_outbuf > 0) {
		poll_mask |= HVC_POLL_WRITE;
		/* If hvc_push() was not able to write, sleep a few msecs */
		timeout = (written_total) ? 0 : MIN_TIMEOUT;
	}

	if (may_sleep) {
		spin_unlock_irqrestore(&hp->lock, flags);
		cond_resched();
		spin_lock_irqsave(&hp->lock, flags);
	}

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

	/* Now check if we can get data (are we throttled ?) */
	if (tty_throttled(tty))
		goto out;

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

 read_again:
	/* Read data if any */
	count = tty_buffer_request_room(&hp->port, N_INBUF);

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

	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;
		}
		goto out;
	}

	for (i = 0; i < n; ++i) {
#ifdef CONFIG_MAGIC_SYSRQ
		if (hp->index == hvc_console.index) {
			/* Handle the SysRq Hack */
			/* XXX should support a sequence */
			if (buf[i] == '\x0f') {	/* ^O */
				/* if ^O is pressed again, reset
				 * sysrq_pressed and flip ^O char */
				sysrq_pressed = !sysrq_pressed;
				if (sysrq_pressed)
					continue;
			} else if (sysrq_pressed) {
				handle_sysrq(buf[i]);
				sysrq_pressed = 0;
				continue;
			}
		}
#endif /* CONFIG_MAGIC_SYSRQ */
		tty_insert_flip_char(&hp->port, buf[i], 0);
	}
	read_total += n;

	if (may_sleep) {
		/* Keep going until the flip is full */
		spin_unlock_irqrestore(&hp->lock, flags);
		cond_resched();
		spin_lock_irqsave(&hp->lock, flags);
		goto read_again;
	} else if (read_total < HVC_ATOMIC_READ_MAX) {
		/* Break and defer if it's a large read in atomic */
		goto read_again;
	}

	/*
	 * Latency break, schedule another poll immediately.
	 */
	poll_mask |= HVC_POLL_READ;

 out:
	/* 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(&hp->port);
	}
	tty_kref_put(tty);

	return poll_mask;
}

int hvc_poll(struct hvc_struct *hp)
{
	return __hvc_poll(hp, false);
}
EXPORT_SYMBOL_GPL(hvc_poll);

/**
 * __hvc_resize() - Update terminal window size information.
 * @hp:		HVC console pointer
 * @ws:		Terminal window size structure
 *
 * Stores the specified window size information in the hvc structure of @hp.
 * The function schedule the tty resize update.
 *
 * Locking:	Locking free; the function MUST be called holding hp->lock
 */
void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
{
	hp->ws = ws;
	schedule_work(&hp->tty_resize);
}
EXPORT_SYMBOL_GPL(__hvc_resize);

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

	set_freezable();
	do {
		poll_mask = 0;
		hvc_kicked = 0;
		try_to_freeze();
		wmb();
		if (!cpus_are_in_xmon()) {
			mutex_lock(&hvc_structs_mutex);
			list_for_each_entry(hp, &hvc_structs, next) {
				poll_mask |= __hvc_poll(hp, true);
				cond_resched();
			}
			mutex_unlock(&hvc_structs_mutex);
		} else
			poll_mask |= HVC_POLL_READ;
		if (hvc_kicked)
			continue;
		set_current_state(TASK_INTERRUPTIBLE);
		if (!hvc_kicked) {
			if (poll_mask == 0)
				schedule();
			else {
				unsigned long j_timeout;

				if (timeout < MAX_TIMEOUT)
					timeout += (timeout >> 6) + 1;

				/*
				 * We don't use msleep_interruptible otherwise
				 * "kick" will fail to wake us up
				 */
				j_timeout = msecs_to_jiffies(timeout) + 1;
				schedule_timeout_interruptible(j_timeout);
			}
		}
		__set_current_state(TASK_RUNNING);
	} while (!kthread_should_stop());

	return 0;
}

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

	if (!hp || !hp->ops->tiocmget)
		return -EINVAL;
	return hp->ops->tiocmget(hp);
}

static int hvc_tiocmset(struct tty_struct *tty,
			unsigned int set, unsigned int clear)
{
	struct hvc_struct *hp = tty->driver_data;

	if (!hp || !hp->ops->tiocmset)
		return -EINVAL;
	return hp->ops->tiocmset(hp, set, clear);
}

#ifdef CONFIG_CONSOLE_POLL
static int hvc_poll_init(struct tty_driver *driver, int line, char *options)
{
	return 0;
}

static int hvc_poll_get_char(struct tty_driver *driver, int line)
{
	struct tty_struct *tty = driver->ttys[0];
	struct hvc_struct *hp = tty->driver_data;
	int n;
	char ch;

	n = hp->ops->get_chars(hp->vtermno, &ch, 1);

	if (n <= 0)
		return NO_POLL_CHAR;

	return ch;
}

static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
{
	struct tty_struct *tty = driver->ttys[0];
	struct hvc_struct *hp = tty->driver_data;
	int n;

	do {
		n = hp->ops->put_chars(hp->vtermno, &ch, 1);
	} while (n <= 0);
}
#endif

static const struct tty_operations hvc_ops = {
	.install = hvc_install,
	.open = hvc_open,
	.close = hvc_close,
	.cleanup = hvc_cleanup,
	.write = hvc_write,
	.hangup = hvc_hangup,
	.unthrottle = hvc_unthrottle,
	.write_room = hvc_write_room,
	.chars_in_buffer = hvc_chars_in_buffer,
	.tiocmget = hvc_tiocmget,
	.tiocmset = hvc_tiocmset,
#ifdef CONFIG_CONSOLE_POLL
	.poll_init = hvc_poll_init,
	.poll_get_char = hvc_poll_get_char,
	.poll_put_char = hvc_poll_put_char,
#endif
};

static const struct tty_port_operations hvc_port_ops = {
	.destruct = hvc_port_destruct,
};

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

	/* We wait until a driver actually comes along */
	if (atomic_inc_not_zero(&hvc_needs_init)) {
		int err = hvc_init();
		if (err)
			return ERR_PTR(err);
	}

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

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

	tty_port_init(&hp->port);
	hp->port.ops = &hvc_port_ops;

	INIT_WORK(&hp->tty_resize, hvc_set_winsz);
	spin_lock_init(&hp->lock);
	mutex_lock(&hvc_structs_mutex);

	/*
	 * 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;

	if (i >= MAX_NR_HVC_CONSOLES) {

		/* find 'empty' slot for console */
		for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
		}

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

	hp->index = i;
	if (i < MAX_NR_HVC_CONSOLES) {
		cons_ops[i] = ops;
		vtermnos[i] = vtermno;
	}

	list_add_tail(&(hp->next), &hvc_structs);
	mutex_unlock(&hvc_structs_mutex);

	/* check if we need to re-register the kernel console */
	hvc_check_console(i);

	return hp;
}
EXPORT_SYMBOL_GPL(hvc_alloc);

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

	tty = tty_port_tty_get(&hp->port);

	console_lock();
	spin_lock_irqsave(&hp->lock, flags);
	if (hp->index < MAX_NR_HVC_CONSOLES) {
		vtermnos[hp->index] = -1;
		cons_ops[hp->index] = NULL;
	}

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

	spin_unlock_irqrestore(&hp->lock, flags);
	console_unlock();

	/*
	 * We 'put' the instance that was grabbed when the kref instance
	 * was initialized using kref_init().  Let the last holder of this
	 * kref cause it to be removed, which will probably be the tty_vhangup
	 * below.
	 */
	tty_port_put(&hp->port);

	/*
	 * This function call will auto chain call hvc_hangup.
	 */
	if (tty) {
		tty_vhangup(tty);
		tty_kref_put(tty);
	}
	return 0;
}
EXPORT_SYMBOL_GPL(hvc_remove);

/* Driver initialization: called as soon as someone uses hvc_alloc(). */
static int hvc_init(void)
{
	struct tty_driver *drv;
	int err;

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

	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_DRIVER_RESET_TERMIOS;
	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)) {
		printk(KERN_ERR "Couldn't create kthread for console.\n");
		err = PTR_ERR(hvc_task);
		goto put_tty;
	}

	err = tty_register_driver(drv);
	if (err) {
		printk(KERN_ERR "Couldn't register hvc console driver\n");
		goto stop_thread;
	}

	/*
	 * Make sure tty is fully registered before allowing it to be
	 * found by hvc_console_device.
	 */
	smp_mb();
	hvc_driver = drv;
	return 0;

stop_thread:
	kthread_stop(hvc_task);
	hvc_task = NULL;
put_tty:
	put_tty_driver(drv);
out:
	return err;
}
