More meth updates.
[linux-2.6/linux-mips.git] / drivers / serial / 8250_hcdp.c
blobdbc39d6bcd6ba028cec0c7bc4ad37e82d056c43f
1 /*
2 * linux/drivers/char/hcdp_serial.c
4 * Copyright (C) 2002 Hewlett-Packard Co.
5 * Khalid Aziz <khalid_aziz@hp.com>
7 * Parse the EFI HCDP table to locate serial console and debug ports and
8 * initialize them.
10 * 2002/08/29 davidm Adjust it to new 2.5 serial driver infrastructure.
13 #include <linux/config.h>
14 #include <linux/kernel.h>
15 #include <linux/efi.h>
16 #include <linux/init.h>
17 #include <linux/tty.h>
18 #include <linux/serial.h>
19 #include <linux/serial_core.h>
20 #include <linux/types.h>
21 #include <linux/acpi.h>
23 #include <asm/io.h>
24 #include <asm/serial.h>
25 #include <asm/acpi.h>
27 #include "8250_hcdp.h"
29 #undef SERIAL_DEBUG_HCDP
32 * Parse the HCDP table to find descriptions for headless console and debug
33 * serial ports and add them to rs_table[]. A pointer to HCDP table is
34 * passed as parameter. This function should be called before
35 * serial_console_init() is called to make sure the HCDP serial console will
36 * be available for use. IA-64 kernel calls this function from setup_arch()
37 * after the EFI and ACPI tables have been parsed.
39 void __init
40 setup_serial_hcdp(void *tablep)
42 hcdp_dev_t *hcdp_dev;
43 struct uart_port port;
44 unsigned long iobase;
45 hcdp_t hcdp;
46 int gsi, nr;
47 #if 0
48 static int shift_once = 1;
49 #endif
51 #ifdef SERIAL_DEBUG_HCDP
52 printk("Entering setup_serial_hcdp()\n");
53 #endif
55 /* Verify we have a valid table pointer */
56 if (!tablep)
57 return;
59 memset(&port, 0, sizeof(port));
62 * Don't trust firmware to give us a table starting at an aligned
63 * address. Make a local copy of the HCDP table with aligned
64 * structures.
66 memcpy(&hcdp, tablep, sizeof(hcdp));
69 * Perform a sanity check on the table. Table should have a signature
70 * of "HCDP" and it should be atleast 82 bytes long to have any
71 * useful information.
73 if ((strncmp(hcdp.signature, HCDP_SIGNATURE, HCDP_SIG_LEN) != 0))
74 return;
75 if (hcdp.len < 82)
76 return;
78 #ifdef SERIAL_DEBUG_HCDP
79 printk("setup_serial_hcdp(): table pointer = 0x%p, sig = '%.4s'\n",
80 tablep, hcdp.signature);
81 printk(" length = %d, rev = %d, ", hcdp.len, hcdp.rev);
82 printk("OEM ID = %.6s, # of entries = %d\n", hcdp.oemid,
83 hcdp.num_entries);
84 #endif
87 * Parse each device entry
89 for (nr = 0; nr < hcdp.num_entries; nr++) {
90 hcdp_dev = hcdp.hcdp_dev + nr;
92 * We will parse only the primary console device which is
93 * the first entry for these devices. We will ignore rest
94 * of the entries for the same type device that has already
95 * been parsed and initialized
97 if (hcdp_dev->type != HCDP_DEV_CONSOLE)
98 continue;
100 iobase = ((u64) hcdp_dev->base_addr.addrhi << 32) |
101 hcdp_dev->base_addr.addrlo;
102 gsi = hcdp_dev->global_int;
104 /* See PCI spec v2.2, Appendix D (Class Codes): */
105 switch (hcdp_dev->pci_prog_intfc) {
106 case 0x00:
107 port.type = PORT_8250;
108 break;
109 case 0x01:
110 port.type = PORT_16450;
111 break;
112 case 0x02:
113 port.type = PORT_16550;
114 break;
115 case 0x03:
116 port.type = PORT_16650;
117 break;
118 case 0x04:
119 port.type = PORT_16750;
120 break;
121 case 0x05:
122 port.type = PORT_16850;
123 break;
124 case 0x06:
125 port.type = PORT_16C950;
126 break;
127 default:
128 printk(KERN_WARNING "warning: EFI HCDP table reports "
129 "unknown serial programming interface 0x%02x; "
130 "will autoprobe.\n", hcdp_dev->pci_prog_intfc);
131 port.type = PORT_UNKNOWN;
132 break;
135 #ifdef SERIAL_DEBUG_HCDP
136 printk(" type = %s, uart = %d\n",
137 ((hcdp_dev->type == HCDP_DEV_CONSOLE) ?
138 "Headless Console" :
139 ((hcdp_dev->type == HCDP_DEV_DEBUG) ?
140 "Debug port" : "Huh????")), port.type);
141 printk(" base address space = %s, base address = 0x%lx\n",
142 ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) ?
143 "Memory Space" :
144 ((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) ?
145 "I/O space" : "PCI space")),
146 iobase);
147 printk(" gsi = %d, baud rate = %lu, bits = %d, clock = %d\n",
148 gsi, (unsigned long) hcdp_dev->baud, hcdp_dev->bits,
149 hcdp_dev->clock_rate);
150 if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE)
151 printk(" PCI id: %02x:%02x:%02x, vendor ID=0x%x, "
152 "dev ID=0x%x\n", hcdp_dev->pci_seg,
153 hcdp_dev->pci_bus, hcdp_dev->pci_dev,
154 hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id);
155 #endif
157 * Now fill in a port structure to update the 8250 port table..
159 if (hcdp_dev->clock_rate)
160 port.uartclk = hcdp_dev->clock_rate;
161 else
162 port.uartclk = BASE_BAUD * 16;
165 * Check if this is an I/O mapped address or a memory mapped
166 * address
168 if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) {
169 port.iobase = 0;
170 port.mapbase = iobase;
171 port.membase = ioremap(iobase, 64);
172 port.iotype = SERIAL_IO_MEM;
173 } else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) {
174 port.iobase = iobase;
175 port.mapbase = 0;
176 port.membase = NULL;
177 port.iotype = SERIAL_IO_PORT;
178 } else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
179 printk(KERN_WARNING"warning: No support for PCI serial console\n");
180 return;
182 #ifdef CONFIG_IA64
183 port.irq = acpi_register_irq(gsi, ACPI_ACTIVE_HIGH,
184 ACPI_EDGE_SENSITIVE);
185 #else
186 port.irq = gsi;
187 #endif
188 port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
189 if (gsi)
190 port.flags |= ASYNC_AUTO_IRQ;
193 * Note: the above memset() initializes port.line to 0,
194 * so we register this port as ttyS0.
196 if (early_serial_setup(&port) < 0) {
197 printk("setup_serial_hcdp(): early_serial_setup() "
198 "for HCDP serial console port failed. "
199 "Will try any additional consoles in HCDP.\n");
200 continue;
202 break;
205 #ifdef SERIAL_DEBUG_HCDP
206 printk("Leaving setup_serial_hcdp()\n");
207 #endif
210 #ifdef CONFIG_IA64_EARLY_PRINTK_UART
211 unsigned long
212 hcdp_early_uart (void)
214 efi_system_table_t *systab;
215 efi_config_table_t *config_tables;
216 unsigned long addr = 0;
217 hcdp_t *hcdp = 0;
218 hcdp_dev_t *dev;
219 int i;
221 systab = (efi_system_table_t *) ia64_boot_param->efi_systab;
222 if (!systab)
223 return 0;
224 systab = __va(systab);
226 config_tables = (efi_config_table_t *) systab->tables;
227 if (!config_tables)
228 return 0;
229 config_tables = __va(config_tables);
231 for (i = 0; i < systab->nr_tables; i++) {
232 if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
233 hcdp = (hcdp_t *) config_tables[i].table;
234 break;
237 if (!hcdp)
238 return 0;
239 hcdp = __va(hcdp);
241 for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) {
242 if (dev->type == HCDP_DEV_CONSOLE) {
243 addr = (u64) dev->base_addr.addrhi << 32 | dev->base_addr.addrlo;
244 break;
247 return addr;
249 #endif /* CONFIG_IA64_EARLY_PRINTK_UART */