/*
 *  PS3 virtual uart
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 *
 *  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; version 2 of the License.
 *
 *  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/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/ps3.h>

#include <asm/lv1call.h>
#include <asm/bitops.h>

#include "vuart.h"

MODULE_AUTHOR("Sony Corporation");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ps3 vuart");

/**
 * vuart - An inter-partition data link service.
 *  port 0: PS3 AV Settings.
 *  port 2: PS3 System Manager.
 *
 * The vuart provides a bi-directional byte stream data link between logical
 * partitions.  Its primary role is as a communications link between the guest
 * OS and the system policy module.  The current HV does not support any
 * connections other than those listed.
 */

enum {PORT_COUNT = 3,};

enum vuart_param {
	PARAM_TX_TRIGGER = 0,
	PARAM_RX_TRIGGER = 1,
	PARAM_INTERRUPT_MASK = 2,
	PARAM_RX_BUF_SIZE = 3, /* read only */
	PARAM_RX_BYTES = 4, /* read only */
	PARAM_TX_BUF_SIZE = 5, /* read only */
	PARAM_TX_BYTES = 6, /* read only */
	PARAM_INTERRUPT_STATUS = 7, /* read only */
};

enum vuart_interrupt_bit {
	INTERRUPT_BIT_TX = 0,
	INTERRUPT_BIT_RX = 1,
	INTERRUPT_BIT_DISCONNECT = 2,
};

enum vuart_interrupt_mask {
	INTERRUPT_MASK_TX = 1,
	INTERRUPT_MASK_RX = 2,
	INTERRUPT_MASK_DISCONNECT = 4,
};

/**
 * struct ports_bmp - bitmap indicating ports needing service.
 *
 * A 256 bit read only bitmap indicating ports needing service.  Do not write
 * to these bits.  Must not cross a page boundary.
 */

struct ports_bmp {
	u64 status;
	u64 unused[3];
} __attribute__ ((aligned (32)));

/* redefine dev_dbg to do a syntax check */

#if !defined(DEBUG)
#undef dev_dbg
static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
	const struct device *_dev, const char *fmt, ...) {return 0;}
#endif

#define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__)
static void __attribute__ ((unused)) _dump_ports_bmp(
	const struct ports_bmp* bmp, const char* func, int line)
{
	pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
}

static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id,
	unsigned int *port_number)
{
	switch(match_id) {
	case PS3_MATCH_ID_AV_SETTINGS:
		*port_number = 0;
		return 0;
	case PS3_MATCH_ID_SYSTEM_MANAGER:
		*port_number = 2;
		return 0;
	default:
		WARN_ON(1);
		*port_number = UINT_MAX;
		return -EINVAL;
	};
}

#define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
static void __attribute__ ((unused)) _dump_port_params(unsigned int port_number,
	const char* func, int line)
{
#if defined(DEBUG)
	static const char *strings[] = {
		"tx_trigger      ",
		"rx_trigger      ",
		"interrupt_mask  ",
		"rx_buf_size     ",
		"rx_bytes        ",
		"tx_buf_size     ",
		"tx_bytes        ",
		"interrupt_status",
	};
	int result;
	unsigned int i;
	u64 value;

	for (i = 0; i < ARRAY_SIZE(strings); i++) {
		result = lv1_get_virtual_uart_param(port_number, i, &value);

		if (result) {
			pr_debug("%s:%d: port_%u: %s failed: %s\n", func, line,
				port_number, strings[i], ps3_result(result));
			continue;
		}
		pr_debug("%s:%d: port_%u: %s = %lxh\n",
			func, line, port_number, strings[i], value);
	}
#endif
}

struct vuart_triggers {
	unsigned long rx;
	unsigned long tx;
};

int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
	struct vuart_triggers *trig)
{
	int result;
	unsigned long size;
	unsigned long val;

	result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_TX_TRIGGER, &trig->tx);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_RX_BUF_SIZE, &size);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: tx_buf_size failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_RX_TRIGGER, &val);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: rx_trigger failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	trig->rx = size - val;

	dev_dbg(&dev->core, "%s:%d: tx %lxh, rx %lxh\n", __func__, __LINE__,
		trig->tx, trig->rx);

	return result;
}

int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
	unsigned int rx)
{
	int result;
	unsigned long size;

	result = lv1_set_virtual_uart_param(dev->port_number,
		PARAM_TX_TRIGGER, tx);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_RX_BUF_SIZE, &size);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: tx_buf_size failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = lv1_set_virtual_uart_param(dev->port_number,
		PARAM_RX_TRIGGER, size - rx);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: rx_trigger failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	dev_dbg(&dev->core, "%s:%d: tx %xh, rx %xh\n", __func__, __LINE__,
		tx, rx);

	return result;
}

static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
	unsigned long *bytes_waiting)
{
	int result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_RX_BYTES, bytes_waiting);

	if (result)
		dev_dbg(&dev->core, "%s:%d: rx_bytes failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__,
		*bytes_waiting);
	return result;
}

static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
	unsigned long mask)
{
	int result;

	dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);

	dev->interrupt_mask = mask;

	result = lv1_set_virtual_uart_param(dev->port_number,
		PARAM_INTERRUPT_MASK, dev->interrupt_mask);

	if (result)
		dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	return result;
}

static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev,
	unsigned long *status)
{
	int result = lv1_get_virtual_uart_param(dev->port_number,
		PARAM_INTERRUPT_STATUS, status);

	if (result)
		dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
		__func__, __LINE__, dev->interrupt_mask, *status,
		dev->interrupt_mask & *status);

	return result;
}

int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0
		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		| INTERRUPT_MASK_TX);
}

int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0
		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		| INTERRUPT_MASK_RX);
}

int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		| INTERRUPT_MASK_DISCONNECT);
}

int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_TX)
		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		& ~INTERRUPT_MASK_TX) : 0;
}

int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_RX)
		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		& ~INTERRUPT_MASK_RX) : 0;
}

int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
{
	return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
		& ~INTERRUPT_MASK_DISCONNECT) : 0;
}

/**
 * ps3_vuart_raw_write - Low level write helper.
 *
 * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write.
 */

static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
	const void* buf, unsigned int bytes, unsigned long *bytes_written)
{
	int result;

	dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);

	result = lv1_write_virtual_uart(dev->port_number,
		ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: lv1_write_virtual_uart failed: "
			"%s\n", __func__, __LINE__, ps3_result(result));
		return result;
	}

	dev->stats.bytes_written += *bytes_written;

	dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__,
		__LINE__, *bytes_written, bytes, dev->stats.bytes_written);

	return result;
}

/**
 * ps3_vuart_raw_read - Low level read helper.
 *
 * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read.
 */

static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
	unsigned int bytes, unsigned long *bytes_read)
{
	int result;

	dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);

	result = lv1_read_virtual_uart(dev->port_number,
		ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: lv1_read_virtual_uart failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	dev->stats.bytes_read += *bytes_read;

	dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
		*bytes_read, bytes, dev->stats.bytes_read);

	return result;
}

/**
 * struct list_buffer - An element for a port device fifo buffer list.
 */

struct list_buffer {
	struct list_head link;
	const unsigned char *head;
	const unsigned char *tail;
	unsigned long dbg_number;
	unsigned char data[];
};

/**
 * ps3_vuart_write - the entry point for writing data to a port
 *
 * If the port is idle on entry as much of the incoming data is written to
 * the port as the port will accept.  Otherwise a list buffer is created
 * and any remaning incoming data is copied to that buffer.  The buffer is
 * then enqueued for transmision via the transmit interrupt.
 */

int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
	unsigned int bytes)
{
	static unsigned long dbg_number;
	int result;
	unsigned long flags;
	struct list_buffer *lb;

	dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
		bytes, bytes);

	spin_lock_irqsave(&dev->tx_list.lock, flags);

	if (list_empty(&dev->tx_list.head)) {
		unsigned long bytes_written;

		result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);

		spin_unlock_irqrestore(&dev->tx_list.lock, flags);

		if (result) {
			dev_dbg(&dev->core,
				"%s:%d: ps3_vuart_raw_write failed\n",
				__func__, __LINE__);
			return result;
		}

		if (bytes_written == bytes) {
			dev_dbg(&dev->core, "%s:%d: wrote %xh bytes\n",
				__func__, __LINE__, bytes);
			return 0;
		}

		bytes -= bytes_written;
		buf += bytes_written;
	} else
		spin_unlock_irqrestore(&dev->tx_list.lock, flags);

	lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);

	if (!lb) {
		return -ENOMEM;
	}

	memcpy(lb->data, buf, bytes);
	lb->head = lb->data;
	lb->tail = lb->data + bytes;
	lb->dbg_number = ++dbg_number;

	spin_lock_irqsave(&dev->tx_list.lock, flags);
	list_add_tail(&lb->link, &dev->tx_list.head);
	ps3_vuart_enable_interrupt_tx(dev);
	spin_unlock_irqrestore(&dev->tx_list.lock, flags);

	dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
		__func__, __LINE__, lb->dbg_number, bytes);

	return 0;
}

/**
 * ps3_vuart_read - the entry point for reading data from a port
 *
 * If enough bytes to satisfy the request are held in the buffer list those
 * bytes are dequeued and copied to the caller's buffer.  Emptied list buffers
 * are retiered.  If the request cannot be statified by bytes held in the list
 * buffers -EAGAIN is returned.
 */

int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
	unsigned int bytes)
{
	unsigned long flags;
	struct list_buffer *lb, *n;
	unsigned long bytes_read;

	dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
		bytes, bytes);

	spin_lock_irqsave(&dev->rx_list.lock, flags);

	if (dev->rx_list.bytes_held < bytes) {
		spin_unlock_irqrestore(&dev->rx_list.lock, flags);
		dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
			__func__, __LINE__, bytes - dev->rx_list.bytes_held);
		return -EAGAIN;
	}

	list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) {
		bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);

		memcpy(buf, lb->head, bytes_read);
		buf += bytes_read;
		bytes -= bytes_read;
		dev->rx_list.bytes_held -= bytes_read;

		if (bytes_read < lb->tail - lb->head) {
			lb->head += bytes_read;
			spin_unlock_irqrestore(&dev->rx_list.lock, flags);

			dev_dbg(&dev->core,
				"%s:%d: dequeued buf_%lu, %lxh bytes\n",
				__func__, __LINE__, lb->dbg_number, bytes_read);
			return 0;
		}

		dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__,
			lb->dbg_number);

		list_del(&lb->link);
		kfree(lb);
	}
	spin_unlock_irqrestore(&dev->rx_list.lock, flags);

	dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n",
		__func__, __LINE__, lb->dbg_number, bytes);

	return 0;
}

/**
 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
 *
 * Services the transmit interrupt for the port.  Writes as much data from the
 * buffer list as the port will accept.  Retires any emptied list buffers and
 * adjusts the final list buffer state for a partial write.
 */

static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
{
	int result = 0;
	unsigned long flags;
	struct list_buffer *lb, *n;
	unsigned long bytes_total = 0;

	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);

	spin_lock_irqsave(&dev->tx_list.lock, flags);

	list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) {

		unsigned long bytes_written;

		result = ps3_vuart_raw_write(dev, lb->head, lb->tail - lb->head,
			&bytes_written);

		if (result) {
			dev_dbg(&dev->core,
				"%s:%d: ps3_vuart_raw_write failed\n",
				__func__, __LINE__);
			break;
		}

		bytes_total += bytes_written;

		if (bytes_written < lb->tail - lb->head) {
			lb->head += bytes_written;
			dev_dbg(&dev->core,
				"%s:%d cleared buf_%lu, %lxh bytes\n",
				__func__, __LINE__, lb->dbg_number,
				bytes_written);
			goto port_full;
		}

		dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__,
			lb->dbg_number);

		list_del(&lb->link);
		kfree(lb);
	}

	ps3_vuart_disable_interrupt_tx(dev);
port_full:
	spin_unlock_irqrestore(&dev->tx_list.lock, flags);
	dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
		__func__, __LINE__, bytes_total);
	return result;
}

/**
 * ps3_vuart_handle_interrupt_rx - third stage receive interrupt handler
 *
 * Services the receive interrupt for the port.  Creates a list buffer and
 * copies all waiting port data to that buffer and enqueues the buffer in the
 * buffer list.  Buffer list data is dequeued via ps3_vuart_read.
 */

static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
{
	static unsigned long dbg_number;
	int result = 0;
	unsigned long flags;
	struct list_buffer *lb;
	unsigned long bytes;

	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);

	result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes);

	if (result)
		return -EIO;

	BUG_ON(!bytes);

	/* add some extra space for recently arrived data */

	bytes += 128;

	lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC);

	if (!lb)
		return -ENOMEM;

	ps3_vuart_raw_read(dev, lb->data, bytes, &bytes);

	lb->head = lb->data;
	lb->tail = lb->data + bytes;
	lb->dbg_number = ++dbg_number;

	spin_lock_irqsave(&dev->rx_list.lock, flags);
	list_add_tail(&lb->link, &dev->rx_list.head);
	dev->rx_list.bytes_held += bytes;
	spin_unlock_irqrestore(&dev->rx_list.lock, flags);

	dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n",
		__func__, __LINE__, lb->dbg_number, bytes);

	return 0;
}

static int ps3_vuart_handle_interrupt_disconnect(
	struct ps3_vuart_port_device *dev)
{
	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
	BUG_ON("no support");
	return -1;
}

/**
 * ps3_vuart_handle_port_interrupt - second stage interrupt handler
 *
 * Services any pending interrupt types for the port.  Passes control to the
 * third stage type specific interrupt handler.  Returns control to the first
 * stage handler after one iteration.
 */

static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
{
	int result;
	unsigned long status;

	result = ps3_vuart_get_interrupt_mask(dev, &status);

	if (result)
		return result;

	dev_dbg(&dev->core, "%s:%d: status: %lxh\n", __func__, __LINE__,
		status);

	if (status & INTERRUPT_MASK_DISCONNECT) {
		dev->stats.disconnect_interrupts++;
		result = ps3_vuart_handle_interrupt_disconnect(dev);
		if (result)
			ps3_vuart_disable_interrupt_disconnect(dev);
	}

	if (status & INTERRUPT_MASK_TX) {
		dev->stats.tx_interrupts++;
		result = ps3_vuart_handle_interrupt_tx(dev);
		if (result)
			ps3_vuart_disable_interrupt_tx(dev);
	}

	if (status & INTERRUPT_MASK_RX) {
		dev->stats.rx_interrupts++;
		result = ps3_vuart_handle_interrupt_rx(dev);
		if (result)
			ps3_vuart_disable_interrupt_rx(dev);
	}

	return 0;
}

struct vuart_private {
	unsigned int in_use;
	unsigned int virq;
	struct ps3_vuart_port_device *devices[PORT_COUNT];
	const struct ports_bmp bmp;
};

/**
 * ps3_vuart_irq_handler - first stage interrupt handler
 *
 * Loops finding any interrupting port and its associated instance data.
 * Passes control to the second stage port specific interrupt handler.  Loops
 * until all outstanding interrupts are serviced.
 */

static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
{
	struct vuart_private *private;

	BUG_ON(!_private);
	private = (struct vuart_private *)_private;

	while (1) {
		unsigned int port;

		dump_ports_bmp(&private->bmp);

		port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status);

		if (port == BITS_PER_LONG)
			break;

		BUG_ON(port >= PORT_COUNT);
		BUG_ON(!private->devices[port]);

		ps3_vuart_handle_port_interrupt(private->devices[port]);
	}

	return IRQ_HANDLED;
}

static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv)
{
	int result;
	struct ps3_vuart_port_driver *drv = to_ps3_vuart_port_driver(_drv);
	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);

	result = dev->match_id == drv->match_id;

	dev_info(&dev->core, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__,
		__LINE__, dev->match_id, dev->core.bus_id, drv->match_id,
		drv->core.name, (result ? "match" : "miss"));

	return result;
}

static struct vuart_private vuart_private;

static int ps3_vuart_probe(struct device *_dev)
{
	int result;
	unsigned long tmp;
	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
	struct ps3_vuart_port_driver *drv =
		to_ps3_vuart_port_driver(_dev->driver);

	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);

	BUG_ON(!drv);

	result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
			__func__, __LINE__, dev->match_id);
		result = -EINVAL;
		goto fail_match;
	}

	if (vuart_private.devices[dev->port_number]) {
		dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
			__LINE__, dev->port_number);
		result = -EBUSY;
		goto fail_match;
	}

	vuart_private.devices[dev->port_number] = dev;

	INIT_LIST_HEAD(&dev->tx_list.head);
	spin_lock_init(&dev->tx_list.lock);
	INIT_LIST_HEAD(&dev->rx_list.head);
	spin_lock_init(&dev->rx_list.lock);

	vuart_private.in_use++;
	if (vuart_private.in_use == 1) {
		result = ps3_alloc_vuart_irq((void*)&vuart_private.bmp.status,
			&vuart_private.virq);

		if (result) {
			dev_dbg(&dev->core,
				"%s:%d: ps3_alloc_vuart_irq failed (%d)\n",
				__func__, __LINE__, result);
			result = -EPERM;
			goto fail_alloc_irq;
		}

		result = request_irq(vuart_private.virq, ps3_vuart_irq_handler,
			IRQF_DISABLED, "vuart", &vuart_private);

		if (result) {
			dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
				__func__, __LINE__, result);
			goto fail_request_irq;
		}
	}

	ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);

	/* clear stale pending interrupts */
	ps3_vuart_get_interrupt_mask(dev, &tmp);

	ps3_vuart_set_triggers(dev, 1, 1);

	if (drv->probe)
		result = drv->probe(dev);
	else {
		result = 0;
		dev_info(&dev->core, "%s:%d: no probe method\n", __func__,
			__LINE__);
	}

	if (result) {
		dev_dbg(&dev->core, "%s:%d: drv->probe failed\n",
			__func__, __LINE__);
		goto fail_probe;
	}

	return result;

fail_probe:
fail_request_irq:
	vuart_private.in_use--;
	if (!vuart_private.in_use) {
		ps3_free_vuart_irq(vuart_private.virq);
		vuart_private.virq = NO_IRQ;
	}
fail_alloc_irq:
fail_match:
	dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
	return result;
}

static int ps3_vuart_remove(struct device *_dev)
{
	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
	struct ps3_vuart_port_driver *drv =
		to_ps3_vuart_port_driver(_dev->driver);

	dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
		dev->core.bus_id);

	BUG_ON(vuart_private.in_use < 1);

	if (drv->remove)
		drv->remove(dev);
	else
		dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
			__LINE__, dev->core.bus_id);

	vuart_private.in_use--;

	if (!vuart_private.in_use) {
		free_irq(vuart_private.virq, &vuart_private);
		ps3_free_vuart_irq(vuart_private.virq);
		vuart_private.virq = NO_IRQ;
	}
	return 0;
}

/**
 * ps3_vuart - The vuart instance.
 *
 * The vuart is managed as a bus that port devices connect to.
 */

struct bus_type ps3_vuart = {
        .name = "ps3_vuart",
	.match = ps3_vuart_match,
	.probe = ps3_vuart_probe,
	.remove = ps3_vuart_remove,
};

int __init ps3_vuart_init(void)
{
	int result;

	pr_debug("%s:%d:\n", __func__, __LINE__);
	result = bus_register(&ps3_vuart);
	BUG_ON(result);
	return result;
}

void __exit ps3_vuart_exit(void)
{
	pr_debug("%s:%d:\n", __func__, __LINE__);
	bus_unregister(&ps3_vuart);
}

core_initcall(ps3_vuart_init);
module_exit(ps3_vuart_exit);

/**
 * ps3_vuart_port_release_device - Remove a vuart port device.
 */

static void ps3_vuart_port_release_device(struct device *_dev)
{
	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
#if defined(DEBUG)
	memset(dev, 0xad, sizeof(struct ps3_vuart_port_device));
#endif
	kfree(dev);
}

/**
 * ps3_vuart_port_device_register - Add a vuart port device.
 */

int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
{
	int result;
	static unsigned int dev_count = 1;

	dev->core.parent = NULL;
	dev->core.bus = &ps3_vuart;
	dev->core.release = ps3_vuart_port_release_device;

	snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
		dev_count++);

	dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);

	result = device_register(&dev->core);

	return result;
}

EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);

/**
 * ps3_vuart_port_driver_register - Add a vuart port device driver.
 */

int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
{
	int result;

	pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
	drv->core.bus = &ps3_vuart;
	result = driver_register(&drv->core);
	return result;
}

EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);

/**
 * ps3_vuart_port_driver_unregister - Remove a vuart port device driver.
 */

void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
{
	driver_unregister(&drv->core);
}

EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister);
