// SPDX-License-Identifier: GPL-2.0-only
/*
 * driver for the GE IP-OCTAL boards
 *
 * Copyright (C) 2009-2012 CERN (www.cern.ch)
 * Author: Nicolas Serafini, EIC2 SA
 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/tty_flip.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/ipack.h>
#include "ipoctal.h"
#include "scc2698.h"

#define IP_OCTAL_ID_SPACE_VECTOR    0x41
#define IP_OCTAL_NB_BLOCKS          4

static const struct tty_operations ipoctal_fops;

struct ipoctal_channel {
	struct ipoctal_stats		stats;
	unsigned int			nb_bytes;
	wait_queue_head_t		queue;
	spinlock_t			lock;
	unsigned int			pointer_read;
	unsigned int			pointer_write;
	struct tty_port			tty_port;
	bool				tty_registered;
	union scc2698_channel __iomem	*regs;
	union scc2698_block __iomem	*block_regs;
	unsigned int			board_id;
	u8				isr_rx_rdy_mask;
	u8				isr_tx_rdy_mask;
	unsigned int			rx_enable;
};

struct ipoctal {
	struct ipack_device		*dev;
	unsigned int			board_id;
	struct ipoctal_channel		channel[NR_CHANNELS];
	struct tty_driver		*tty_drv;
	u8 __iomem			*mem8_space;
	u8 __iomem			*int_space;
};

static inline struct ipoctal *chan_to_ipoctal(struct ipoctal_channel *chan,
					      unsigned int index)
{
	return container_of(chan, struct ipoctal, channel[index]);
}

static void ipoctal_reset_channel(struct ipoctal_channel *channel)
{
	iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
	channel->rx_enable = 0;
	iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
	iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
	iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
	iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr);
}

static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
{
	struct ipoctal_channel *channel;

	channel = dev_get_drvdata(tty->dev);

	/*
	 * Enable RX. TX will be enabled when
	 * there is something to send
	 */
	iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
	channel->rx_enable = 1;
	return 0;
}

static int ipoctal_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct ipoctal_channel *channel = dev_get_drvdata(tty->dev);
	struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
	int res;

	if (!ipack_get_carrier(ipoctal->dev))
		return -EBUSY;

	res = tty_standard_install(driver, tty);
	if (res)
		goto err_put_carrier;

	tty->driver_data = channel;

	return 0;

err_put_carrier:
	ipack_put_carrier(ipoctal->dev);

	return res;
}

static int ipoctal_open(struct tty_struct *tty, struct file *file)
{
	struct ipoctal_channel *channel = tty->driver_data;

	return tty_port_open(&channel->tty_port, tty, file);
}

static void ipoctal_reset_stats(struct ipoctal_stats *stats)
{
	stats->tx = 0;
	stats->rx = 0;
	stats->rcv_break = 0;
	stats->framing_err = 0;
	stats->overrun_err = 0;
	stats->parity_err = 0;
}

static void ipoctal_free_channel(struct ipoctal_channel *channel)
{
	ipoctal_reset_stats(&channel->stats);
	channel->pointer_read = 0;
	channel->pointer_write = 0;
	channel->nb_bytes = 0;
}

static void ipoctal_close(struct tty_struct *tty, struct file *filp)
{
	struct ipoctal_channel *channel = tty->driver_data;

	tty_port_close(&channel->tty_port, tty, filp);
	ipoctal_free_channel(channel);
}

static int ipoctal_get_icount(struct tty_struct *tty,
			      struct serial_icounter_struct *icount)
{
	struct ipoctal_channel *channel = tty->driver_data;

	icount->cts = 0;
	icount->dsr = 0;
	icount->rng = 0;
	icount->dcd = 0;
	icount->rx = channel->stats.rx;
	icount->tx = channel->stats.tx;
	icount->frame = channel->stats.framing_err;
	icount->parity = channel->stats.parity_err;
	icount->brk = channel->stats.rcv_break;
	return 0;
}

static void ipoctal_irq_rx(struct ipoctal_channel *channel, u8 sr)
{
	struct tty_port *port = &channel->tty_port;
	unsigned char value;
	unsigned char flag;
	u8 isr;

	do {
		value = ioread8(&channel->regs->r.rhr);
		flag = TTY_NORMAL;
		/* Error: count statistics */
		if (sr & SR_ERROR) {
			iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);

			if (sr & SR_OVERRUN_ERROR) {
				channel->stats.overrun_err++;
				/* Overrun doesn't affect the current character*/
				tty_insert_flip_char(port, 0, TTY_OVERRUN);
			}
			if (sr & SR_PARITY_ERROR) {
				channel->stats.parity_err++;
				flag = TTY_PARITY;
			}
			if (sr & SR_FRAMING_ERROR) {
				channel->stats.framing_err++;
				flag = TTY_FRAME;
			}
			if (sr & SR_RECEIVED_BREAK) {
				channel->stats.rcv_break++;
				flag = TTY_BREAK;
			}
		}
		tty_insert_flip_char(port, value, flag);

		/* Check if there are more characters in RX FIFO
		 * If there are more, the isr register for this channel
		 * has enabled the RxRDY|FFULL bit.
		 */
		isr = ioread8(&channel->block_regs->r.isr);
		sr = ioread8(&channel->regs->r.sr);
	} while (isr & channel->isr_rx_rdy_mask);

	tty_flip_buffer_push(port);
}

static void ipoctal_irq_tx(struct ipoctal_channel *channel)
{
	unsigned char value;
	unsigned int *pointer_write = &channel->pointer_write;

	if (channel->nb_bytes == 0)
		return;

	spin_lock(&channel->lock);
	value = channel->tty_port.xmit_buf[*pointer_write];
	iowrite8(value, &channel->regs->w.thr);
	channel->stats.tx++;
	(*pointer_write)++;
	*pointer_write = *pointer_write % PAGE_SIZE;
	channel->nb_bytes--;
	spin_unlock(&channel->lock);
}

static void ipoctal_irq_channel(struct ipoctal_channel *channel)
{
	u8 isr, sr;

	/* The HW is organized in pair of channels.  See which register we need
	 * to read from */
	isr = ioread8(&channel->block_regs->r.isr);
	sr = ioread8(&channel->regs->r.sr);

	if (isr & (IMR_DELTA_BREAK_A | IMR_DELTA_BREAK_B))
		iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr);

	if ((sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
		iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
		/* In case of RS-485, change from TX to RX when finishing TX.
		 * Half-duplex. */
		if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
			iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
			iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
			channel->rx_enable = 1;
		}
	}

	/* RX data */
	if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY))
		ipoctal_irq_rx(channel, sr);

	/* TX of each character */
	if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
		ipoctal_irq_tx(channel);
}

static irqreturn_t ipoctal_irq_handler(void *arg)
{
	unsigned int i;
	struct ipoctal *ipoctal = arg;

	/* Clear the IPack device interrupt */
	readw(ipoctal->int_space + ACK_INT_REQ0);
	readw(ipoctal->int_space + ACK_INT_REQ1);

	/* Check all channels */
	for (i = 0; i < NR_CHANNELS; i++)
		ipoctal_irq_channel(&ipoctal->channel[i]);

	return IRQ_HANDLED;
}

static const struct tty_port_operations ipoctal_tty_port_ops = {
	.dtr_rts = NULL,
	.activate = ipoctal_port_activate,
};

static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
			     unsigned int slot)
{
	int res;
	int i;
	struct tty_driver *drv;
	struct ipoctal_channel *channel;
	struct ipack_region *region;
	void __iomem *addr;
	union scc2698_channel __iomem *chan_regs;
	union scc2698_block __iomem *block_regs;

	ipoctal->board_id = ipoctal->dev->id_device;

	region = &ipoctal->dev->region[IPACK_IO_SPACE];
	addr = devm_ioremap(&ipoctal->dev->dev,
				    region->start, region->size);
	if (!addr) {
		dev_err(&ipoctal->dev->dev,
			"Unable to map slot [%d:%d] IO space!\n",
			bus_nr, slot);
		return -EADDRNOTAVAIL;
	}
	/* Save the virtual address to access the registers easily */
	chan_regs =
		(union scc2698_channel __iomem *) addr;
	block_regs =
		(union scc2698_block __iomem *) addr;

	region = &ipoctal->dev->region[IPACK_INT_SPACE];
	ipoctal->int_space =
		devm_ioremap(&ipoctal->dev->dev,
				     region->start, region->size);
	if (!ipoctal->int_space) {
		dev_err(&ipoctal->dev->dev,
			"Unable to map slot [%d:%d] INT space!\n",
			bus_nr, slot);
		return -EADDRNOTAVAIL;
	}

	region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
	ipoctal->mem8_space =
		devm_ioremap(&ipoctal->dev->dev,
				     region->start, 0x8000);
	if (!ipoctal->mem8_space) {
		dev_err(&ipoctal->dev->dev,
			"Unable to map slot [%d:%d] MEM8 space!\n",
			bus_nr, slot);
		return -EADDRNOTAVAIL;
	}


	/* Disable RX and TX before touching anything */
	for (i = 0; i < NR_CHANNELS ; i++) {
		struct ipoctal_channel *channel = &ipoctal->channel[i];
		channel->regs = chan_regs + i;
		channel->block_regs = block_regs + (i >> 1);
		channel->board_id = ipoctal->board_id;
		if (i & 1) {
			channel->isr_tx_rdy_mask = ISR_TxRDY_B;
			channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B;
		} else {
			channel->isr_tx_rdy_mask = ISR_TxRDY_A;
			channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A;
		}

		ipoctal_reset_channel(channel);
		iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY,
			 &channel->regs->w.mr); /* mr1 */
		iowrite8(0, &channel->regs->w.mr); /* mr2 */
		iowrite8(TX_CLK_9600  | RX_CLK_9600, &channel->regs->w.csr);
	}

	for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
		iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr);
		iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN,
			 &block_regs[i].w.opcr);
		iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A |
			 IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B,
			 &block_regs[i].w.imr);
	}

	/* Dummy write */
	iowrite8(1, ipoctal->mem8_space + 1);

	/* Register the TTY device */

	/* Each IP-OCTAL channel is a TTY port */
	drv = tty_alloc_driver(NR_CHANNELS, TTY_DRIVER_REAL_RAW |
			TTY_DRIVER_DYNAMIC_DEV);
	if (IS_ERR(drv))
		return PTR_ERR(drv);

	/* Fill struct tty_driver with ipoctal data */
	drv->owner = THIS_MODULE;
	drv->driver_name = KBUILD_MODNAME;
	drv->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot);
	if (!drv->name) {
		res = -ENOMEM;
		goto err_put_driver;
	}
	drv->major = 0;

	drv->minor_start = 0;
	drv->type = TTY_DRIVER_TYPE_SERIAL;
	drv->subtype = SERIAL_TYPE_NORMAL;
	drv->init_termios = tty_std_termios;
	drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	drv->init_termios.c_ispeed = 9600;
	drv->init_termios.c_ospeed = 9600;

	tty_set_operations(drv, &ipoctal_fops);
	res = tty_register_driver(drv);
	if (res) {
		dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
		goto err_free_name;
	}

	/* Save struct tty_driver for use it when uninstalling the device */
	ipoctal->tty_drv = drv;

	for (i = 0; i < NR_CHANNELS; i++) {
		struct device *tty_dev;

		channel = &ipoctal->channel[i];
		tty_port_init(&channel->tty_port);
		res = tty_port_alloc_xmit_buf(&channel->tty_port);
		if (res)
			continue;
		channel->tty_port.ops = &ipoctal_tty_port_ops;

		ipoctal_reset_stats(&channel->stats);
		channel->nb_bytes = 0;
		spin_lock_init(&channel->lock);
		channel->pointer_read = 0;
		channel->pointer_write = 0;
		tty_dev = tty_port_register_device_attr(&channel->tty_port, drv,
							i, NULL, channel, NULL);
		if (IS_ERR(tty_dev)) {
			dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
			tty_port_free_xmit_buf(&channel->tty_port);
			tty_port_destroy(&channel->tty_port);
			continue;
		}
		channel->tty_registered = true;
	}

	/*
	 * IP-OCTAL has different addresses to copy its IRQ vector.
	 * Depending of the carrier these addresses are accesible or not.
	 * More info in the datasheet.
	 */
	ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
				       ipoctal_irq_handler, ipoctal);

	return 0;

err_free_name:
	kfree(drv->name);
err_put_driver:
	tty_driver_kref_put(drv);

	return res;
}

static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
					    const u8 *buf, int count)
{
	unsigned long flags;
	int i;
	unsigned int *pointer_read = &channel->pointer_read;

	/* Copy the bytes from the user buffer to the internal one */
	for (i = 0; i < count; i++) {
		if (i <= (PAGE_SIZE - channel->nb_bytes)) {
			spin_lock_irqsave(&channel->lock, flags);
			channel->tty_port.xmit_buf[*pointer_read] = buf[i];
			*pointer_read = (*pointer_read + 1) % PAGE_SIZE;
			channel->nb_bytes++;
			spin_unlock_irqrestore(&channel->lock, flags);
		} else {
			break;
		}
	}
	return i;
}

static ssize_t ipoctal_write_tty(struct tty_struct *tty, const u8 *buf,
				 size_t count)
{
	struct ipoctal_channel *channel = tty->driver_data;
	unsigned int char_copied;

	char_copied = ipoctal_copy_write_buffer(channel, buf, count);

	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
	if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
		iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
		channel->rx_enable = 0;
		iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
	}

	/*
	 * Send a packet and then disable TX to avoid failure after several send
	 * operations
	 */
	iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
	return char_copied;
}

static unsigned int ipoctal_write_room(struct tty_struct *tty)
{
	struct ipoctal_channel *channel = tty->driver_data;

	return PAGE_SIZE - channel->nb_bytes;
}

static unsigned int ipoctal_chars_in_buffer(struct tty_struct *tty)
{
	struct ipoctal_channel *channel = tty->driver_data;

	return channel->nb_bytes;
}

static void ipoctal_set_termios(struct tty_struct *tty,
				const struct ktermios *old_termios)
{
	unsigned int cflag;
	unsigned char mr1 = 0;
	unsigned char mr2 = 0;
	unsigned char csr = 0;
	struct ipoctal_channel *channel = tty->driver_data;
	speed_t baud;

	cflag = tty->termios.c_cflag;

	/* Disable and reset everything before change the setup */
	ipoctal_reset_channel(channel);

	/* Set Bits per chars */
	switch (cflag & CSIZE) {
	case CS6:
		mr1 |= MR1_CHRL_6_BITS;
		break;
	case CS7:
		mr1 |= MR1_CHRL_7_BITS;
		break;
	case CS8:
	default:
		mr1 |= MR1_CHRL_8_BITS;
		/* By default, select CS8 */
		tty->termios.c_cflag = (cflag & ~CSIZE) | CS8;
		break;
	}

	/* Set Parity */
	if (cflag & PARENB)
		if (cflag & PARODD)
			mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD;
		else
			mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN;
	else
		mr1 |= MR1_PARITY_OFF;

	/* Mark or space parity is not supported */
	tty->termios.c_cflag &= ~CMSPAR;

	/* Set stop bits */
	if (cflag & CSTOPB)
		mr2 |= MR2_STOP_BITS_LENGTH_2;
	else
		mr2 |= MR2_STOP_BITS_LENGTH_1;

	/* Set the flow control */
	switch (channel->board_id) {
	case IPACK1_DEVICE_ID_SBS_OCTAL_232:
		if (cflag & CRTSCTS) {
			mr1 |= MR1_RxRTS_CONTROL_ON;
			mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON;
		} else {
			mr1 |= MR1_RxRTS_CONTROL_OFF;
			mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
		}
		break;
	case IPACK1_DEVICE_ID_SBS_OCTAL_422:
		mr1 |= MR1_RxRTS_CONTROL_OFF;
		mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
		break;
	case IPACK1_DEVICE_ID_SBS_OCTAL_485:
		mr1 |= MR1_RxRTS_CONTROL_OFF;
		mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF;
		break;
	default:
		return;
	}

	baud = tty_get_baud_rate(tty);
	tty_termios_encode_baud_rate(&tty->termios, baud, baud);

	/* Set baud rate */
	switch (baud) {
	case 75:
		csr |= TX_CLK_75 | RX_CLK_75;
		break;
	case 110:
		csr |= TX_CLK_110 | RX_CLK_110;
		break;
	case 150:
		csr |= TX_CLK_150 | RX_CLK_150;
		break;
	case 300:
		csr |= TX_CLK_300 | RX_CLK_300;
		break;
	case 600:
		csr |= TX_CLK_600 | RX_CLK_600;
		break;
	case 1200:
		csr |= TX_CLK_1200 | RX_CLK_1200;
		break;
	case 1800:
		csr |= TX_CLK_1800 | RX_CLK_1800;
		break;
	case 2000:
		csr |= TX_CLK_2000 | RX_CLK_2000;
		break;
	case 2400:
		csr |= TX_CLK_2400 | RX_CLK_2400;
		break;
	case 4800:
		csr |= TX_CLK_4800  | RX_CLK_4800;
		break;
	case 9600:
		csr |= TX_CLK_9600  | RX_CLK_9600;
		break;
	case 19200:
		csr |= TX_CLK_19200 | RX_CLK_19200;
		break;
	case 38400:
	default:
		csr |= TX_CLK_38400 | RX_CLK_38400;
		/* In case of default, we establish 38400 bps */
		tty_termios_encode_baud_rate(&tty->termios, 38400, 38400);
		break;
	}

	mr1 |= MR1_ERROR_CHAR;
	mr1 |= MR1_RxINT_RxRDY;

	/* Write the control registers */
	iowrite8(mr1, &channel->regs->w.mr);
	iowrite8(mr2, &channel->regs->w.mr);
	iowrite8(csr, &channel->regs->w.csr);

	/* Enable again the RX, if it was before */
	if (channel->rx_enable)
		iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
}

static void ipoctal_hangup(struct tty_struct *tty)
{
	unsigned long flags;
	struct ipoctal_channel *channel = tty->driver_data;

	if (channel == NULL)
		return;

	spin_lock_irqsave(&channel->lock, flags);
	channel->nb_bytes = 0;
	channel->pointer_read = 0;
	channel->pointer_write = 0;
	spin_unlock_irqrestore(&channel->lock, flags);

	tty_port_hangup(&channel->tty_port);

	ipoctal_reset_channel(channel);
	tty_port_set_initialized(&channel->tty_port, false);
	wake_up_interruptible(&channel->tty_port.open_wait);
}

static void ipoctal_shutdown(struct tty_struct *tty)
{
	struct ipoctal_channel *channel = tty->driver_data;

	if (channel == NULL)
		return;

	ipoctal_reset_channel(channel);
	tty_port_set_initialized(&channel->tty_port, false);
}

static void ipoctal_cleanup(struct tty_struct *tty)
{
	struct ipoctal_channel *channel = tty->driver_data;
	struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);

	/* release the carrier driver */
	ipack_put_carrier(ipoctal->dev);
}

static const struct tty_operations ipoctal_fops = {
	.ioctl =		NULL,
	.install =		ipoctal_install,
	.open =			ipoctal_open,
	.close =		ipoctal_close,
	.write =		ipoctal_write_tty,
	.set_termios =		ipoctal_set_termios,
	.write_room =		ipoctal_write_room,
	.chars_in_buffer =	ipoctal_chars_in_buffer,
	.get_icount =		ipoctal_get_icount,
	.hangup =		ipoctal_hangup,
	.shutdown =		ipoctal_shutdown,
	.cleanup =              ipoctal_cleanup,
};

static int ipoctal_probe(struct ipack_device *dev)
{
	int res;
	struct ipoctal *ipoctal;

	ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL);
	if (ipoctal == NULL)
		return -ENOMEM;

	ipoctal->dev = dev;
	res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
	if (res)
		goto out_uninst;

	dev_set_drvdata(&dev->dev, ipoctal);
	return 0;

out_uninst:
	kfree(ipoctal);
	return res;
}

static void __ipoctal_remove(struct ipoctal *ipoctal)
{
	int i;

	ipoctal->dev->bus->ops->free_irq(ipoctal->dev);

	for (i = 0; i < NR_CHANNELS; i++) {
		struct ipoctal_channel *channel = &ipoctal->channel[i];

		if (!channel->tty_registered)
			continue;

		tty_unregister_device(ipoctal->tty_drv, i);
		tty_port_free_xmit_buf(&channel->tty_port);
		tty_port_destroy(&channel->tty_port);
	}

	tty_unregister_driver(ipoctal->tty_drv);
	kfree(ipoctal->tty_drv->name);
	tty_driver_kref_put(ipoctal->tty_drv);
	kfree(ipoctal);
}

static void ipoctal_remove(struct ipack_device *idev)
{
	__ipoctal_remove(dev_get_drvdata(&idev->dev));
}

static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
			IPACK1_DEVICE_ID_SBS_OCTAL_232) },
	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
			IPACK1_DEVICE_ID_SBS_OCTAL_422) },
	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
			IPACK1_DEVICE_ID_SBS_OCTAL_485) },
	{ 0, },
};

MODULE_DEVICE_TABLE(ipack, ipoctal_ids);

static const struct ipack_driver_ops ipoctal_drv_ops = {
	.probe  = ipoctal_probe,
	.remove = ipoctal_remove,
};

static struct ipack_driver driver = {
	.ops      = &ipoctal_drv_ops,
	.id_table = ipoctal_ids,
};

static int __init ipoctal_init(void)
{
	return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME);
}

static void __exit ipoctal_exit(void)
{
	ipack_driver_unregister(&driver);
}

MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver");
MODULE_LICENSE("GPL");

module_init(ipoctal_init);
module_exit(ipoctal_exit);
