/*
 * Beat hypervisor console driver
 *
 * (C) Copyright 2006 TOSHIBA CORPORATION
 *
 * This code is based on drivers/char/hvc_rtas.c:
 * (C) Copyright IBM Corporation 2001-2005
 * (C) Copyright Red Hat, Inc. 2005
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/console.h>
#include <asm/prom.h>
#include <asm/hvconsole.h>
#include <asm/firmware.h>

#include "hvc_console.h"

extern int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *);
extern int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t);

struct hvc_struct *hvc_beat_dev = NULL;

/* bug: only one queue is available regardless of vtermno */
static int hvc_beat_get_chars(uint32_t vtermno, char *buf, int cnt)
{
	static unsigned char q[sizeof(unsigned long) * 2]
		__attribute__((aligned(sizeof(unsigned long))));
	static int qlen = 0;
	unsigned long got;

again:
	if (qlen) {
		if (qlen > cnt) {
			memcpy(buf, q, cnt);
			qlen -= cnt;
			memmove(q + cnt, q, qlen);
			return cnt;
		} else {	/* qlen <= cnt */
			int	r;

			memcpy(buf, q, qlen);
			r = qlen;
			qlen = 0;
			return r;
		}
	}
	if (beat_get_term_char(vtermno, &got,
		((unsigned long *)q), ((unsigned long *)q) + 1) == 0) {
		qlen = got;
		goto again;
	}
	return 0;
}

static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt)
{
	unsigned long kb[2];
	int rest, nlen;

	for (rest = cnt; rest > 0; rest -= nlen) {
		nlen = (rest > 16) ? 16 : rest;
		memcpy(kb, buf, nlen);
		beat_put_term_char(vtermno, rest, kb[0], kb[1]);
		rest -= nlen;
	}
	return cnt;
}

static struct hv_ops hvc_beat_get_put_ops = {
	.get_chars = hvc_beat_get_chars,
	.put_chars = hvc_beat_put_chars,
};

static int hvc_beat_useit = 1;

static int hvc_beat_config(char *p)
{
	hvc_beat_useit = simple_strtoul(p, NULL, 0);
	return 0;
}

static int hvc_beat_console_init(void)
{
	if (hvc_beat_useit && machine_is_compatible("Beat")) {
		hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
	}
	return 0;
}

/* temp */
static int hvc_beat_init(void)
{
	struct hvc_struct *hp;

	if (!firmware_has_feature(FW_FEATURE_BEAT))
		return -ENODEV;

	hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16);
	if (IS_ERR(hp))
		return PTR_ERR(hp);
	hvc_beat_dev = hp;
	return 0;
}

static void __exit hvc_beat_exit(void)
{
	if (hvc_beat_dev)
		hvc_remove(hvc_beat_dev);
}

module_init(hvc_beat_init);
module_exit(hvc_beat_exit);

__setup("hvc_beat=", hvc_beat_config);

console_initcall(hvc_beat_console_init);
