// SPDX-License-Identifier: GPL-2.0
/* ePAPR hypervisor byte channel device driver
 *
 * Copyright 2009-2011 Freescale Semiconductor, Inc.
 *
 * Author: Timur Tabi <timur@freescale.com>
 *
 * This driver support three distinct interfaces, all of which are related to
 * ePAPR hypervisor byte channels.
 *
 * 1) An early-console (udbg) driver.  This provides early console output
 * through a byte channel.  The byte channel handle must be specified in a
 * Kconfig option.
 *
 * 2) A normal console driver.  Output is sent to the byte channel designated
 * for stdout in the device tree.  The console driver is for handling kernel
 * printk calls.
 *
 * 3) A tty driver, which is used to handle user-space input and output.  The
 * byte channel used for the console is designated as the default tty.
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <asm/epapr_hcalls.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/circ_buf.h>
#include <asm/udbg.h>

/* The size of the transmit circular buffer.  This must be a power of two. */
#define BUF_SIZE	2048

/* Per-byte channel private data */
struct ehv_bc_data {
	struct device *dev;
	struct tty_port port;
	uint32_t handle;
	unsigned int rx_irq;
	unsigned int tx_irq;

	spinlock_t lock;	/* lock for transmit buffer */
	unsigned char buf[BUF_SIZE];	/* transmit circular buffer */
	unsigned int head;	/* circular buffer head */
	unsigned int tail;	/* circular buffer tail */

	int tx_irq_enabled;	/* true == TX interrupt is enabled */
};

/* Array of byte channel objects */
static struct ehv_bc_data *bcs;

/* Byte channel handle for stdout (and stdin), taken from device tree */
static unsigned int stdout_bc;

/* Virtual IRQ for the byte channel handle for stdin, taken from device tree */
static unsigned int stdout_irq;

/**************************** SUPPORT FUNCTIONS ****************************/

/*
 * Enable the transmit interrupt
 *
 * Unlike a serial device, byte channels have no mechanism for disabling their
 * own receive or transmit interrupts.  To emulate that feature, we toggle
 * the IRQ in the kernel.
 *
 * We cannot just blindly call enable_irq() or disable_irq(), because these
 * calls are reference counted.  This means that we cannot call enable_irq()
 * if interrupts are already enabled.  This can happen in two situations:
 *
 * 1. The tty layer makes two back-to-back calls to ehv_bc_tty_write()
 * 2. A transmit interrupt occurs while executing ehv_bc_tx_dequeue()
 *
 * To work around this, we keep a flag to tell us if the IRQ is enabled or not.
 */
static void enable_tx_interrupt(struct ehv_bc_data *bc)
{
	if (!bc->tx_irq_enabled) {
		enable_irq(bc->tx_irq);
		bc->tx_irq_enabled = 1;
	}
}

static void disable_tx_interrupt(struct ehv_bc_data *bc)
{
	if (bc->tx_irq_enabled) {
		disable_irq_nosync(bc->tx_irq);
		bc->tx_irq_enabled = 0;
	}
}

/*
 * find the byte channel handle to use for the console
 *
 * The byte channel to be used for the console is specified via a "stdout"
 * property in the /chosen node.
 */
static int find_console_handle(void)
{
	struct device_node *np = of_stdout;
	const uint32_t *iprop;

	/* We don't care what the aliased node is actually called.  We only
	 * care if it's compatible with "epapr,hv-byte-channel", because that
	 * indicates that it's a byte channel node.
	 */
	if (!np || !of_device_is_compatible(np, "epapr,hv-byte-channel"))
		return 0;

	stdout_irq = irq_of_parse_and_map(np, 0);
	if (stdout_irq == NO_IRQ) {
		pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np);
		return 0;
	}

	/*
	 * The 'hv-handle' property contains the handle for this byte channel.
	 */
	iprop = of_get_property(np, "hv-handle", NULL);
	if (!iprop) {
		pr_err("ehv-bc: no 'hv-handle' property in %pOFn node\n",
		       np);
		return 0;
	}
	stdout_bc = be32_to_cpu(*iprop);
	return 1;
}

static unsigned int local_ev_byte_channel_send(unsigned int handle,
					       unsigned int *count,
					       const char *p)
{
	char buffer[EV_BYTE_CHANNEL_MAX_BYTES];
	unsigned int c = *count;

	if (c < sizeof(buffer)) {
		memcpy(buffer, p, c);
		memset(&buffer[c], 0, sizeof(buffer) - c);
		p = buffer;
	}
	return ev_byte_channel_send(handle, count, p);
}

/*************************** EARLY CONSOLE DRIVER ***************************/

#ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC

/*
 * send a byte to a byte channel, wait if necessary
 *
 * This function sends a byte to a byte channel, and it waits and
 * retries if the byte channel is full.  It returns if the character
 * has been sent, or if some error has occurred.
 *
 */
static void byte_channel_spin_send(const char data)
{
	int ret, count;

	do {
		count = 1;
		ret = local_ev_byte_channel_send(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE,
					   &count, &data);
	} while (ret == EV_EAGAIN);
}

/*
 * The udbg subsystem calls this function to display a single character.
 * We convert CR to a CR/LF.
 */
static void ehv_bc_udbg_putc(char c)
{
	if (c == '\n')
		byte_channel_spin_send('\r');

	byte_channel_spin_send(c);
}

/*
 * early console initialization
 *
 * PowerPC kernels support an early printk console, also known as udbg.
 * This function must be called via the ppc_md.init_early function pointer.
 * At this point, the device tree has been unflattened, so we can obtain the
 * byte channel handle for stdout.
 *
 * We only support displaying of characters (putc).  We do not support
 * keyboard input.
 */
void __init udbg_init_ehv_bc(void)
{
	unsigned int rx_count, tx_count;
	unsigned int ret;

	/* Verify the byte channel handle */
	ret = ev_byte_channel_poll(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE,
				   &rx_count, &tx_count);
	if (ret)
		return;

	udbg_putc = ehv_bc_udbg_putc;
	register_early_udbg_console();

	udbg_printf("ehv-bc: early console using byte channel handle %u\n",
		    CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
}

#endif

/****************************** CONSOLE DRIVER ******************************/

static struct tty_driver *ehv_bc_driver;

/*
 * Byte channel console sending worker function.
 *
 * For consoles, if the output buffer is full, we should just spin until it
 * clears.
 */
static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s,
			     unsigned int count)
{
	unsigned int len;
	int ret = 0;

	while (count) {
		len = min_t(unsigned int, count, EV_BYTE_CHANNEL_MAX_BYTES);
		do {
			ret = local_ev_byte_channel_send(handle, &len, s);
		} while (ret == EV_EAGAIN);
		count -= len;
		s += len;
	}

	return ret;
}

/*
 * write a string to the console
 *
 * This function gets called to write a string from the kernel, typically from
 * a printk().  This function spins until all data is written.
 *
 * We copy the data to a temporary buffer because we need to insert a \r in
 * front of every \n.  It's more efficient to copy the data to the buffer than
 * it is to make multiple hcalls for each character or each newline.
 */
static void ehv_bc_console_write(struct console *co, const char *s,
				 unsigned int count)
{
	char s2[EV_BYTE_CHANNEL_MAX_BYTES];
	unsigned int i, j = 0;
	char c;

	for (i = 0; i < count; i++) {
		c = *s++;

		if (c == '\n')
			s2[j++] = '\r';

		s2[j++] = c;
		if (j >= (EV_BYTE_CHANNEL_MAX_BYTES - 1)) {
			if (ehv_bc_console_byte_channel_send(stdout_bc, s2, j))
				return;
			j = 0;
		}
	}

	if (j)
		ehv_bc_console_byte_channel_send(stdout_bc, s2, j);
}

/*
 * When /dev/console is opened, the kernel iterates the console list looking
 * for one with ->device and then calls that method. On success, it expects
 * the passed-in int* to contain the minor number to use.
 */
static struct tty_driver *ehv_bc_console_device(struct console *co, int *index)
{
	*index = co->index;

	return ehv_bc_driver;
}

static struct console ehv_bc_console = {
	.name		= "ttyEHV",
	.write		= ehv_bc_console_write,
	.device		= ehv_bc_console_device,
	.flags		= CON_PRINTBUFFER | CON_ENABLED,
};

/*
 * Console initialization
 *
 * This is the first function that is called after the device tree is
 * available, so here is where we determine the byte channel handle and IRQ for
 * stdout/stdin, even though that information is used by the tty and character
 * drivers.
 */
static int __init ehv_bc_console_init(void)
{
	if (!find_console_handle()) {
		pr_debug("ehv-bc: stdout is not a byte channel\n");
		return -ENODEV;
	}

#ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC
	/* Print a friendly warning if the user chose the wrong byte channel
	 * handle for udbg.
	 */
	if (stdout_bc != CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE)
		pr_warn("ehv-bc: udbg handle %u is not the stdout handle\n",
			CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
#endif

	/* add_preferred_console() must be called before register_console(),
	   otherwise it won't work.  However, we don't want to enumerate all the
	   byte channels here, either, since we only care about one. */

	add_preferred_console(ehv_bc_console.name, ehv_bc_console.index, NULL);
	register_console(&ehv_bc_console);

	pr_info("ehv-bc: registered console driver for byte channel %u\n",
		stdout_bc);

	return 0;
}
console_initcall(ehv_bc_console_init);

/******************************** TTY DRIVER ********************************/

/*
 * byte channel receive interrupt handler
 *
 * This ISR is called whenever data is available on a byte channel.
 */
static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data)
{
	struct ehv_bc_data *bc = data;
	unsigned int rx_count, tx_count, len;
	int count;
	char buffer[EV_BYTE_CHANNEL_MAX_BYTES];
	int ret;

	/* Find out how much data needs to be read, and then ask the TTY layer
	 * if it can handle that much.  We want to ensure that every byte we
	 * read from the byte channel will be accepted by the TTY layer.
	 */
	ev_byte_channel_poll(bc->handle, &rx_count, &tx_count);
	count = tty_buffer_request_room(&bc->port, rx_count);

	/* 'count' is the maximum amount of data the TTY layer can accept at
	 * this time.  However, during testing, I was never able to get 'count'
	 * to be less than 'rx_count'.  I'm not sure whether I'm calling it
	 * correctly.
	 */

	while (count > 0) {
		len = min_t(unsigned int, count, sizeof(buffer));

		/* Read some data from the byte channel.  This function will
		 * never return more than EV_BYTE_CHANNEL_MAX_BYTES bytes.
		 */
		ev_byte_channel_receive(bc->handle, &len, buffer);

		/* 'len' is now the amount of data that's been received. 'len'
		 * can't be zero, and most likely it's equal to one.
		 */

		/* Pass the received data to the tty layer. */
		ret = tty_insert_flip_string(&bc->port, buffer, len);

		/* 'ret' is the number of bytes that the TTY layer accepted.
		 * If it's not equal to 'len', then it means the buffer is
		 * full, which should never happen.  If it does happen, we can
		 * exit gracefully, but we drop the last 'len - ret' characters
		 * that we read from the byte channel.
		 */
		if (ret != len)
			break;

		count -= len;
	}

	/* Tell the tty layer that we're done. */
	tty_flip_buffer_push(&bc->port);

	return IRQ_HANDLED;
}

/*
 * dequeue the transmit buffer to the hypervisor
 *
 * This function, which can be called in interrupt context, dequeues as much
 * data as possible from the transmit buffer to the byte channel.
 */
static void ehv_bc_tx_dequeue(struct ehv_bc_data *bc)
{
	unsigned int count;
	unsigned int len, ret;
	unsigned long flags;

	do {
		spin_lock_irqsave(&bc->lock, flags);
		len = min_t(unsigned int,
			    CIRC_CNT_TO_END(bc->head, bc->tail, BUF_SIZE),
			    EV_BYTE_CHANNEL_MAX_BYTES);

		ret = local_ev_byte_channel_send(bc->handle, &len, bc->buf + bc->tail);

		/* 'len' is valid only if the return code is 0 or EV_EAGAIN */
		if (!ret || (ret == EV_EAGAIN))
			bc->tail = (bc->tail + len) & (BUF_SIZE - 1);

		count = CIRC_CNT(bc->head, bc->tail, BUF_SIZE);
		spin_unlock_irqrestore(&bc->lock, flags);
	} while (count && !ret);

	spin_lock_irqsave(&bc->lock, flags);
	if (CIRC_CNT(bc->head, bc->tail, BUF_SIZE))
		/*
		 * If we haven't emptied the buffer, then enable the TX IRQ.
		 * We'll get an interrupt when there's more room in the
		 * hypervisor's output buffer.
		 */
		enable_tx_interrupt(bc);
	else
		disable_tx_interrupt(bc);
	spin_unlock_irqrestore(&bc->lock, flags);
}

/*
 * byte channel transmit interrupt handler
 *
 * This ISR is called whenever space becomes available for transmitting
 * characters on a byte channel.
 */
static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data)
{
	struct ehv_bc_data *bc = data;

	ehv_bc_tx_dequeue(bc);
	tty_port_tty_wakeup(&bc->port);

	return IRQ_HANDLED;
}

/*
 * This function is called when the tty layer has data for us send.  We store
 * the data first in a circular buffer, and then dequeue as much of that data
 * as possible.
 *
 * We don't need to worry about whether there is enough room in the buffer for
 * all the data.  The purpose of ehv_bc_tty_write_room() is to tell the tty
 * layer how much data it can safely send to us.  We guarantee that
 * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us
 * too much data.
 */
static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s,
			    int count)
{
	struct ehv_bc_data *bc = ttys->driver_data;
	unsigned long flags;
	unsigned int len;
	unsigned int written = 0;

	while (1) {
		spin_lock_irqsave(&bc->lock, flags);
		len = CIRC_SPACE_TO_END(bc->head, bc->tail, BUF_SIZE);
		if (count < len)
			len = count;
		if (len) {
			memcpy(bc->buf + bc->head, s, len);
			bc->head = (bc->head + len) & (BUF_SIZE - 1);
		}
		spin_unlock_irqrestore(&bc->lock, flags);
		if (!len)
			break;

		s += len;
		count -= len;
		written += len;
	}

	ehv_bc_tx_dequeue(bc);

	return written;
}

/*
 * This function can be called multiple times for a given tty_struct, which is
 * why we initialize bc->ttys in ehv_bc_tty_port_activate() instead.
 *
 * The tty layer will still call this function even if the device was not
 * registered (i.e. tty_register_device() was not called).  This happens
 * because tty_register_device() is optional and some legacy drivers don't
 * use it.  So we need to check for that.
 */
static int ehv_bc_tty_open(struct tty_struct *ttys, struct file *filp)
{
	struct ehv_bc_data *bc = &bcs[ttys->index];

	if (!bc->dev)
		return -ENODEV;

	return tty_port_open(&bc->port, ttys, filp);
}

/*
 * Amazingly, if ehv_bc_tty_open() returns an error code, the tty layer will
 * still call this function to close the tty device.  So we can't assume that
 * the tty port has been initialized.
 */
static void ehv_bc_tty_close(struct tty_struct *ttys, struct file *filp)
{
	struct ehv_bc_data *bc = &bcs[ttys->index];

	if (bc->dev)
		tty_port_close(&bc->port, ttys, filp);
}

/*
 * Return the amount of space in the output buffer
 *
 * 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 unsigned int ehv_bc_tty_write_room(struct tty_struct *ttys)
{
	struct ehv_bc_data *bc = ttys->driver_data;
	unsigned long flags;
	unsigned int count;

	spin_lock_irqsave(&bc->lock, flags);
	count = CIRC_SPACE(bc->head, bc->tail, BUF_SIZE);
	spin_unlock_irqrestore(&bc->lock, flags);

	return count;
}

/*
 * Stop sending data to the tty layer
 *
 * This function is called when the tty layer's input buffers are getting full,
 * so the driver should stop sending it data.  The easiest way to do this is to
 * disable the RX IRQ, which will prevent ehv_bc_tty_rx_isr() from being
 * called.
 *
 * The hypervisor will continue to queue up any incoming data.  If there is any
 * data in the queue when the RX interrupt is enabled, we'll immediately get an
 * RX interrupt.
 */
static void ehv_bc_tty_throttle(struct tty_struct *ttys)
{
	struct ehv_bc_data *bc = ttys->driver_data;

	disable_irq(bc->rx_irq);
}

/*
 * Resume sending data to the tty layer
 *
 * This function is called after previously calling ehv_bc_tty_throttle().  The
 * tty layer's input buffers now have more room, so the driver can resume
 * sending it data.
 */
static void ehv_bc_tty_unthrottle(struct tty_struct *ttys)
{
	struct ehv_bc_data *bc = ttys->driver_data;

	/* If there is any data in the queue when the RX interrupt is enabled,
	 * we'll immediately get an RX interrupt.
	 */
	enable_irq(bc->rx_irq);
}

static void ehv_bc_tty_hangup(struct tty_struct *ttys)
{
	struct ehv_bc_data *bc = ttys->driver_data;

	ehv_bc_tx_dequeue(bc);
	tty_port_hangup(&bc->port);
}

/*
 * TTY driver operations
 *
 * If we could ask the hypervisor how much data is still in the TX buffer, or
 * at least how big the TX buffers are, then we could implement the
 * .wait_until_sent and .chars_in_buffer functions.
 */
static const struct tty_operations ehv_bc_ops = {
	.open		= ehv_bc_tty_open,
	.close		= ehv_bc_tty_close,
	.write		= ehv_bc_tty_write,
	.write_room	= ehv_bc_tty_write_room,
	.throttle	= ehv_bc_tty_throttle,
	.unthrottle	= ehv_bc_tty_unthrottle,
	.hangup		= ehv_bc_tty_hangup,
};

/*
 * initialize the TTY port
 *
 * This function will only be called once, no matter how many times
 * ehv_bc_tty_open() is called.  That's why we register the ISR here, and also
 * why we initialize tty_struct-related variables here.
 */
static int ehv_bc_tty_port_activate(struct tty_port *port,
				    struct tty_struct *ttys)
{
	struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port);
	int ret;

	ttys->driver_data = bc;

	ret = request_irq(bc->rx_irq, ehv_bc_tty_rx_isr, 0, "ehv-bc", bc);
	if (ret < 0) {
		dev_err(bc->dev, "could not request rx irq %u (ret=%i)\n",
		       bc->rx_irq, ret);
		return ret;
	}

	/* request_irq also enables the IRQ */
	bc->tx_irq_enabled = 1;

	ret = request_irq(bc->tx_irq, ehv_bc_tty_tx_isr, 0, "ehv-bc", bc);
	if (ret < 0) {
		dev_err(bc->dev, "could not request tx irq %u (ret=%i)\n",
		       bc->tx_irq, ret);
		free_irq(bc->rx_irq, bc);
		return ret;
	}

	/* The TX IRQ is enabled only when we can't write all the data to the
	 * byte channel at once, so by default it's disabled.
	 */
	disable_tx_interrupt(bc);

	return 0;
}

static void ehv_bc_tty_port_shutdown(struct tty_port *port)
{
	struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port);

	free_irq(bc->tx_irq, bc);
	free_irq(bc->rx_irq, bc);
}

static const struct tty_port_operations ehv_bc_tty_port_ops = {
	.activate = ehv_bc_tty_port_activate,
	.shutdown = ehv_bc_tty_port_shutdown,
};

static int ehv_bc_tty_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct ehv_bc_data *bc;
	const uint32_t *iprop;
	unsigned int handle;
	int ret;
	static unsigned int index = 1;
	unsigned int i;

	iprop = of_get_property(np, "hv-handle", NULL);
	if (!iprop) {
		dev_err(&pdev->dev, "no 'hv-handle' property in %pOFn node\n",
			np);
		return -ENODEV;
	}

	/* We already told the console layer that the index for the console
	 * device is zero, so we need to make sure that we use that index when
	 * we probe the console byte channel node.
	 */
	handle = be32_to_cpu(*iprop);
	i = (handle == stdout_bc) ? 0 : index++;
	bc = &bcs[i];

	bc->handle = handle;
	bc->head = 0;
	bc->tail = 0;
	spin_lock_init(&bc->lock);

	bc->rx_irq = irq_of_parse_and_map(np, 0);
	bc->tx_irq = irq_of_parse_and_map(np, 1);
	if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) {
		dev_err(&pdev->dev, "no 'interrupts' property in %pOFn node\n",
			np);
		ret = -ENODEV;
		goto error;
	}

	tty_port_init(&bc->port);
	bc->port.ops = &ehv_bc_tty_port_ops;

	bc->dev = tty_port_register_device(&bc->port, ehv_bc_driver, i,
			&pdev->dev);
	if (IS_ERR(bc->dev)) {
		ret = PTR_ERR(bc->dev);
		dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret);
		goto error;
	}

	dev_set_drvdata(&pdev->dev, bc);

	dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n",
		ehv_bc_driver->name, i, bc->handle);

	return 0;

error:
	tty_port_destroy(&bc->port);
	irq_dispose_mapping(bc->tx_irq);
	irq_dispose_mapping(bc->rx_irq);

	memset(bc, 0, sizeof(struct ehv_bc_data));
	return ret;
}

static const struct of_device_id ehv_bc_tty_of_ids[] = {
	{ .compatible = "epapr,hv-byte-channel" },
	{}
};

static struct platform_driver ehv_bc_tty_driver = {
	.driver = {
		.name = "ehv-bc",
		.of_match_table = ehv_bc_tty_of_ids,
		.suppress_bind_attrs = true,
	},
	.probe		= ehv_bc_tty_probe,
};

/**
 * ehv_bc_init - ePAPR hypervisor byte channel driver initialization
 *
 * This function is called when this driver is loaded.
 */
static int __init ehv_bc_init(void)
{
	struct tty_driver *driver;
	struct device_node *np;
	unsigned int count = 0; /* Number of elements in bcs[] */
	int ret;

	pr_info("ePAPR hypervisor byte channel driver\n");

	/* Count the number of byte channels */
	for_each_compatible_node(np, NULL, "epapr,hv-byte-channel")
		count++;

	if (!count)
		return -ENODEV;

	/* The array index of an element in bcs[] is the same as the tty index
	 * for that element.  If you know the address of an element in the
	 * array, then you can use pointer math (e.g. "bc - bcs") to get its
	 * tty index.
	 */
	bcs = kcalloc(count, sizeof(struct ehv_bc_data), GFP_KERNEL);
	if (!bcs)
		return -ENOMEM;

	driver = tty_alloc_driver(count, TTY_DRIVER_REAL_RAW |
			TTY_DRIVER_DYNAMIC_DEV);
	if (IS_ERR(driver)) {
		ret = PTR_ERR(driver);
		goto err_free_bcs;
	}

	driver->driver_name = "ehv-bc";
	driver->name = ehv_bc_console.name;
	driver->type = TTY_DRIVER_TYPE_CONSOLE;
	driver->subtype = SYSTEM_TYPE_CONSOLE;
	driver->init_termios = tty_std_termios;
	tty_set_operations(driver, &ehv_bc_ops);

	ret = tty_register_driver(driver);
	if (ret) {
		pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
		goto err_tty_driver_kref_put;
	}

	ehv_bc_driver = driver;

	ret = platform_driver_register(&ehv_bc_tty_driver);
	if (ret) {
		pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
		       ret);
		goto err_deregister_tty_driver;
	}

	return 0;

err_deregister_tty_driver:
	ehv_bc_driver = NULL;
	tty_unregister_driver(driver);
err_tty_driver_kref_put:
	tty_driver_kref_put(driver);
err_free_bcs:
	kfree(bcs);

	return ret;
}
device_initcall(ehv_bc_init);
