8250_gsc.c 3.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 *	Serial Device Initialisation for Lasi/Asp/Wax/Dino
 *
 *	(c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002
 *
 *	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.
 */

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/serial_core.h>
#include <linux/signal.h>
#include <linux/types.h>

#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/io.h>

#include "8250.h"

A
Alan Cox 已提交
27
static int __init serial_init_chip(struct parisc_device *dev)
L
Linus Torvalds 已提交
28
{
29
	struct uart_8250_port uart;
L
Linus Torvalds 已提交
30 31 32
	unsigned long address;
	int err;

33 34 35 36 37 38
#ifdef CONFIG_64BIT
	extern int iosapic_serial_irq(int cellnum);
	if (!dev->irq && (dev->id.sversion == 0xad))
		dev->irq = iosapic_serial_irq(dev->mod_index-1);
#endif

L
Linus Torvalds 已提交
39 40 41 42 43 44
	if (!dev->irq) {
		/* We find some unattached serial ports by walking native
		 * busses.  These should be silently ignored.  Otherwise,
		 * what we have here is a missing parent device, so tell
		 * the user what they're missing.
		 */
A
Alan Cox 已提交
45 46
		if (parisc_parent(dev)->id.hw_type != HPHW_IOA)
			printk(KERN_INFO
47
				"Serial: device 0x%llx not configured.\n"
48
				"Enable support for Wax, Lasi, Asp or Dino.\n",
49
				(unsigned long long)dev->hpa.start);
L
Linus Torvalds 已提交
50 51 52
		return -ENODEV;
	}

53
	address = dev->hpa.start;
A
Alan Cox 已提交
54
	if (dev->id.sversion != 0x8d)
L
Linus Torvalds 已提交
55 56
		address += 0x800;

57 58
	memset(&uart, 0, sizeof(uart));
	uart.port.iotype	= UPIO_MEM;
59
	/* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
60 61
	uart.port.uartclk	= (dev->id.sversion != 0xad) ?
					7272727 : 1843200;
62 63 64 65 66
	uart.port.mapbase	= address;
	uart.port.membase	= ioremap_nocache(address, 16);
	uart.port.irq	= dev->irq;
	uart.port.flags	= UPF_BOOT_AUTOCONF;
	uart.port.dev	= &dev->dev;
L
Linus Torvalds 已提交
67

68
	err = serial8250_register_8250_port(&uart);
L
Linus Torvalds 已提交
69
	if (err < 0) {
A
Alan Cox 已提交
70
		printk(KERN_WARNING
71 72
			"serial8250_register_8250_port returned error %d\n", err);
		iounmap(uart.port.membase);
L
Linus Torvalds 已提交
73 74
		return err;
	}
A
Alan Cox 已提交
75

L
Linus Torvalds 已提交
76 77 78 79 80 81 82
	return 0;
}

static struct parisc_device_id serial_tbl[] = {
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
83
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad },
L
Linus Torvalds 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	{ 0 }
};

/* Hack.  Some machines have SERIAL_0 attached to Lasi and SERIAL_1
 * attached to Dino.  Unfortunately, Dino appears before Lasi in the device
 * tree.  To ensure that ttyS0 == SERIAL_0, we register two drivers; one
 * which only knows about Lasi and then a second which will find all the
 * other serial ports.  HPUX ignores this problem.
 */
static struct parisc_device_id lasi_tbl[] = {
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */
	{ 0 }
};


MODULE_DEVICE_TABLE(parisc, serial_tbl);

static struct parisc_driver lasi_driver = {
	.name		= "serial_1",
	.id_table	= lasi_tbl,
	.probe		= serial_init_chip,
};

static struct parisc_driver serial_driver = {
	.name		= "serial",
	.id_table	= serial_tbl,
	.probe		= serial_init_chip,
};

A
Adrian Bunk 已提交
121
static int __init probe_serial_gsc(void)
L
Linus Torvalds 已提交
122 123 124 125 126 127 128
{
	register_parisc_driver(&lasi_driver);
	register_parisc_driver(&serial_driver);
	return 0;
}

module_init(probe_serial_gsc);
129 130

MODULE_LICENSE("GPL");