2 * Parse the EFI PCDP table to locate the console device.
4 * (c) Copyright 2002, 2003, 2004 Hewlett-Packard Development Company, L.P.
5 * Khalid Aziz <khalid.aziz@hp.com>
6 * Alex Williamson <alex.williamson@hp.com>
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/acpi.h>
15 #include <linux/console.h>
16 #include <linux/efi.h>
17 #include <linux/tty.h>
18 #include <linux/serial.h>
19 #include <linux/serial_core.h>
21 #include <asm/serial.h>
25 uart_irq_supported(int rev
, struct pcdp_uart
*uart
)
28 return uart
->pci_func
& PCDP_UART_IRQ
;
29 return uart
->flags
& PCDP_UART_IRQ
;
33 uart_pci(int rev
, struct pcdp_uart
*uart
)
36 return uart
->pci_func
& PCDP_UART_PCI
;
37 return uart
->flags
& PCDP_UART_PCI
;
41 uart_active_high_low(int rev
, struct pcdp_uart
*uart
)
43 if (uart_pci(rev
, uart
) || uart
->flags
& PCDP_UART_ACTIVE_LOW
)
44 return ACPI_ACTIVE_LOW
;
45 return ACPI_ACTIVE_HIGH
;
49 uart_edge_level(int rev
, struct pcdp_uart
*uart
)
51 if (uart_pci(rev
, uart
))
52 return ACPI_LEVEL_SENSITIVE
;
53 if (rev
< 3 || uart
->flags
& PCDP_UART_EDGE_SENSITIVE
)
54 return ACPI_EDGE_SENSITIVE
;
55 return ACPI_LEVEL_SENSITIVE
;
59 setup_serial_console(int rev
, struct pcdp_uart
*uart
)
61 #ifdef CONFIG_SERIAL_8250_CONSOLE
62 struct uart_port port
;
63 static char options
[16];
66 memset(&port
, 0, sizeof(port
));
67 port
.uartclk
= uart
->clock_rate
;
68 if (!port
.uartclk
) /* some FW doesn't supply this */
69 port
.uartclk
= BASE_BAUD
* 16;
71 if (uart
->addr
.address_space_id
== ACPI_ADR_SPACE_SYSTEM_MEMORY
) {
72 port
.mapbase
= uart
->addr
.address
;
73 port
.membase
= ioremap(port
.mapbase
, mapsize
);
75 printk(KERN_ERR
"%s: couldn't ioremap 0x%lx-0x%lx\n",
76 __FUNCTION__
, port
.mapbase
, port
.mapbase
+ mapsize
);
79 port
.iotype
= UPIO_MEM
;
80 } else if (uart
->addr
.address_space_id
== ACPI_ADR_SPACE_SYSTEM_IO
) {
81 port
.iobase
= uart
->addr
.address
;
82 port
.iotype
= UPIO_PORT
;
86 switch (uart
->pci_prog_intfc
) {
87 case 0x0: port
.type
= PORT_8250
; break;
88 case 0x1: port
.type
= PORT_16450
; break;
89 case 0x2: port
.type
= PORT_16550
; break;
90 case 0x3: port
.type
= PORT_16650
; break;
91 case 0x4: port
.type
= PORT_16750
; break;
92 case 0x5: port
.type
= PORT_16850
; break;
93 case 0x6: port
.type
= PORT_16C950
; break;
94 default: port
.type
= PORT_UNKNOWN
; break;
97 port
.flags
= UPF_SKIP_TEST
| UPF_BOOT_AUTOCONF
;
99 if (uart_irq_supported(rev
, uart
)) {
100 port
.irq
= acpi_register_gsi(uart
->gsi
,
101 uart_active_high_low(rev
, uart
),
102 uart_edge_level(rev
, uart
));
103 port
.flags
|= UPF_AUTO_IRQ
; /* some FW reported wrong GSI */
104 if (uart_pci(rev
, uart
))
105 port
.flags
|= UPF_SHARE_IRQ
;
108 if (early_serial_setup(&port
) < 0)
111 snprintf(options
, sizeof(options
), "%lun%d", uart
->baud
,
112 uart
->bits
? uart
->bits
: 8);
113 add_preferred_console("ttyS", port
.line
, options
);
115 printk(KERN_INFO
"PCDP: serial console at %s 0x%lx (ttyS%d, options %s)\n",
116 port
.iotype
== UPIO_MEM
? "MMIO" : "I/O",
117 uart
->addr
.address
, port
.line
, options
);
122 setup_vga_console(struct pcdp_vga
*vga
)
125 #ifdef CONFIG_VGA_CONSOLE
126 if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY
) {
127 printk(KERN_ERR
"PCDP: VGA selected, but frame buffer is not MMIO!\n");
131 conswitchp
= &vga_con
;
132 printk(KERN_INFO
"PCDP: VGA console\n");
138 efi_setup_pcdp_console(char *cmdline
)
141 struct pcdp_uart
*uart
;
142 struct pcdp_device
*dev
, *end
;
149 printk(KERN_INFO
"PCDP: v%d at 0x%p\n", pcdp
->rev
, pcdp
);
152 if (strstr(cmdline
, "console=ttyS0") || efi_uart_console_only())
156 for (i
= 0, uart
= pcdp
->uart
; i
< pcdp
->num_uarts
; i
++, uart
++) {
157 if (uart
->flags
& PCDP_UART_PRIMARY_CONSOLE
|| serial
) {
158 if (uart
->type
== PCDP_CONSOLE_UART
) {
159 setup_serial_console(pcdp
->rev
, uart
);
165 end
= (struct pcdp_device
*) ((u8
*) pcdp
+ pcdp
->length
);
166 for (dev
= (struct pcdp_device
*) (pcdp
->uart
+ pcdp
->num_uarts
);
168 dev
= (struct pcdp_device
*) ((u8
*) dev
+ dev
->length
)) {
169 if (dev
->flags
& PCDP_PRIMARY_CONSOLE
) {
170 if (dev
->type
== PCDP_CONSOLE_VGA
) {
171 setup_vga_console((struct pcdp_vga
*) dev
);
178 #ifdef CONFIG_IA64_EARLY_PRINTK_UART
180 hcdp_early_uart (void)
182 efi_system_table_t
*systab
;
183 efi_config_table_t
*config_tables
;
184 unsigned long addr
= 0;
185 struct pcdp
*pcdp
= 0;
186 struct pcdp_uart
*uart
;
189 systab
= (efi_system_table_t
*) ia64_boot_param
->efi_systab
;
192 systab
= __va(systab
);
194 config_tables
= (efi_config_table_t
*) systab
->tables
;
197 config_tables
= __va(config_tables
);
199 for (i
= 0; i
< systab
->nr_tables
; i
++) {
200 if (efi_guidcmp(config_tables
[i
].guid
, HCDP_TABLE_GUID
) == 0) {
201 pcdp
= (struct pcdp
*) config_tables
[i
].table
;
209 for (i
= 0, uart
= pcdp
->uart
; i
< pcdp
->num_uarts
; i
++, uart
++) {
210 if (uart
->type
== PCDP_CONSOLE_UART
) {
211 addr
= uart
->addr
.address
;
217 #endif /* CONFIG_IA64_EARLY_PRINTK_UART */