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