/*
 * Driver for the 98626/98644/internal serial interface on hp300/hp400
 * (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs)
 *
 * Ported from 2.2 and modified to use the normal 8250 driver
 * by Kars de Jong <jongk@linux-m68k.org>, May 2004.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
#include <linux/dio.h>
#include <linux/console.h>
#include <asm/io.h>

#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
#warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
#endif

#ifdef CONFIG_HPAPCI
struct hp300_port
{
	struct hp300_port *next;	/* next port */
	int line;			/* line (tty) number */
};

static struct hp300_port *hp300_ports;
#endif

#ifdef CONFIG_HPDCA

static int __devinit hpdca_init_one(struct dio_dev *d,
                                const struct dio_device_id *ent);
static void __devexit hpdca_remove_one(struct dio_dev *d);

static struct dio_device_id hpdca_dio_tbl[] = {
	{ DIO_ID_DCA0 },
	{ DIO_ID_DCA0REM },
	{ DIO_ID_DCA1 },
	{ DIO_ID_DCA1REM },
	{ 0 }
};

static struct dio_driver hpdca_driver = {
	.name      = "hpdca",
	.id_table  = hpdca_dio_tbl,
	.probe     = hpdca_init_one,
	.remove    = __devexit_p(hpdca_remove_one),
};

#endif

extern int hp300_uart_scode;

/* Offset to UART registers from base of DCA */
#define UART_OFFSET	17

#define DCA_ID		0x01	/* ID (read), reset (write) */
#define DCA_IC		0x03	/* Interrupt control        */

/* Interrupt control */
#define DCA_IC_IE	0x80	/* Master interrupt enable  */

#define HPDCA_BAUD_BASE 153600

/* Base address of the Frodo part */
#define FRODO_BASE	(0x41c000)

/*
 * Where we find the 8250-like APCI ports, and how far apart they are.
 */
#define FRODO_APCIBASE		0x0
#define FRODO_APCISPACE		0x20
#define FRODO_APCI_OFFSET(x)	(FRODO_APCIBASE + ((x) * FRODO_APCISPACE))

#define HPAPCI_BAUD_BASE 500400

#ifdef CONFIG_SERIAL_8250_CONSOLE
/*
 * Parse the bootinfo to find descriptions for headless console and 
 * debug serial ports and register them with the 8250 driver.
 * This function should be called before serial_console_init() is called
 * to make sure the serial console will be available for use. IA-64 kernel
 * calls this function from setup_arch() after the EFI and ACPI tables have
 * been parsed.
 */
int __init hp300_setup_serial_console(void)
{
	int scode;
	struct uart_port port;

	memset(&port, 0, sizeof(port));

	if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX)
		return 0;

	if (DIO_SCINHOLE(hp300_uart_scode))
		return 0;

	scode = hp300_uart_scode;

	/* Memory mapped I/O */
	port.iotype = UPIO_MEM;
	port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
	port.type = PORT_UNKNOWN;

	/* Check for APCI console */
	if (scode == 256) {
#ifdef CONFIG_HPAPCI
		printk(KERN_INFO "Serial console is HP APCI 1\n");

		port.uartclk = HPAPCI_BAUD_BASE * 16;
		port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1));
		port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
		port.regshift = 2;
		add_preferred_console("ttyS", port.line, "9600n8");
#else
		printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n");
		return 0;
#endif
	}
	else {
#ifdef CONFIG_HPDCA
		unsigned long pa = dio_scodetophysaddr(scode);
		if (!pa) {
			return 0;
		}

		printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode);

		port.uartclk = HPDCA_BAUD_BASE * 16;
		port.mapbase = (pa + UART_OFFSET);
		port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
		port.regshift = 1;
		port.irq = DIO_IPL(pa + DIO_VIRADDRBASE);

		/* Enable board-interrupts */
		out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);

		if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80) {
			add_preferred_console("ttyS", port.line, "9600n8");
		}
#else
		printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n");
		return 0;
#endif
	}

	if (early_serial_setup(&port) < 0) {
		printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n");
	}

	return 0;
}
#endif /* CONFIG_SERIAL_8250_CONSOLE */

#ifdef CONFIG_HPDCA
static int __devinit hpdca_init_one(struct dio_dev *d,
                                const struct dio_device_id *ent)
{
	struct serial_struct serial_req;
	int line;

#ifdef CONFIG_SERIAL_8250_CONSOLE
	if (hp300_uart_scode == d->scode) {
		/* Already got it. */
		return 0;
	}
#endif
	memset(&serial_req, 0, sizeof(struct serial_struct));

	/* Memory mapped I/O */
	serial_req.io_type = SERIAL_IO_MEM;
	serial_req.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
	serial_req.irq = d->ipl;
	serial_req.baud_base = HPDCA_BAUD_BASE;
	serial_req.iomap_base = (d->resource.start + UART_OFFSET);
	serial_req.iomem_base = (char *)(serial_req.iomap_base + DIO_VIRADDRBASE);
	serial_req.iomem_reg_shift = 1;
	line = register_serial(&serial_req);

	if (line < 0) {
		printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
		       " irq %d failed\n", d->scode, serial_req.irq);
		return -ENOMEM;
	}

	/* Enable board-interrupts */
	out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
	dio_set_drvdata(d, (void *)line);

	/* Reset the DCA */
	out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff);
	udelay(100);

	return 0;
}
#endif

static int __init hp300_8250_init(void)
{
	static int called = 0;
	int num_ports;
#ifdef CONFIG_HPAPCI
	int line;
	unsigned long base;
	struct serial_struct serial_req;
	struct hp300_port *port;
	int i;
#endif
	if (called)
		return -ENODEV;
	called = 1;

	if (!MACH_IS_HP300)
		return -ENODEV;

	num_ports = 0;

#ifdef CONFIG_HPDCA
	if (dio_module_init(&hpdca_driver) == 0)
		num_ports++;
#endif
#ifdef CONFIG_HPAPCI
	if (hp300_model < HP_400) {
		if (!num_ports)
			return -ENODEV;
		return 0;
	}
	/* These models have the Frodo chip.
	 * Port 0 is reserved for the Apollo Domain keyboard.
	 * Port 1 is either the console or the DCA.
	 */
	for (i = 1; i < 4; i++) {
		/* Port 1 is the console on a 425e, on other machines it's mapped to
		 * DCA.
		 */
#ifdef CONFIG_SERIAL_8250_CONSOLE
		if (i == 1) {
			continue;
		}
#endif

		/* Create new serial device */
		port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL);
		if (!port)
			return -ENOMEM;

		memset(&serial_req, 0, sizeof(struct serial_struct));

		base = (FRODO_BASE + FRODO_APCI_OFFSET(i));

		/* Memory mapped I/O */
		serial_req.io_type = SERIAL_IO_MEM;
		serial_req.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
		/* XXX - no interrupt support yet */
		serial_req.irq = 0;
		serial_req.baud_base = HPAPCI_BAUD_BASE;
		serial_req.iomap_base = base;
		serial_req.iomem_base = (char *)(serial_req.iomap_base + DIO_VIRADDRBASE);
		serial_req.iomem_reg_shift = 2;

		line = register_serial(&serial_req);

		if (line < 0) {
			printk(KERN_NOTICE "8250_hp300: register_serial() APCI %d"
			       " irq %d failed\n", i, serial_req.irq);
			kfree(port);
			continue;
		}

		port->line = line;
		port->next = hp300_ports;
		hp300_ports = port;

		num_ports++;
	}
#endif

	/* Any boards found? */
	if (!num_ports)
		return -ENODEV;

	return 0;
}

#ifdef CONFIG_HPDCA
static void __devexit hpdca_remove_one(struct dio_dev *d)
{
	int line;

	line = (int) dio_get_drvdata(d);
	if (d->resource.start) {
		/* Disable board-interrupts */
		out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
	}
	unregister_serial(line);
}
#endif

static void __exit hp300_8250_exit(void)
{
#ifdef CONFIG_HPAPCI
	struct hp300_port *port, *to_free;

	for (port = hp300_ports; port; ) {
		unregister_serial(port->line);
		to_free = port;
		port = port->next;
		kfree(to_free);
	}

	hp300_ports = NULL;
#endif
#ifdef CONFIG_HPDCA
	dio_unregister_driver(&hpdca_driver);
#endif
}

module_init(hp300_8250_init);
module_exit(hp300_8250_exit);
MODULE_DESCRIPTION("HP DCA/APCI serial driver");
MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>");
MODULE_LICENSE("GPL");
