ia64/xen-unstable
changeset 18649:50aaffd8f87c
Enable PCI serial devices for console messages
The basic issue is that some PCI serial devices use a non-standard
crystal to control the baud rate divisor. This patch enhances the
`com' parameter to enable you to specify the crystal frequency used by
the serial device. Since this parameter already allows you to specify
I/O address and IRQ this is all that is needed to get a PCI serial
device to work. With this patch the `com' parameter is now defined
as:
comN=BBB[/CCC][,NPS[,III[,IRQ]]]
Where `CCC' is the crystal frequency. Note that if you specify 0 for
`IRQ' Xen will run the serial device in polled mode, obviating the
need for interrupts (an advantage since this is the only way I was
able to get my PCI serial device to work).
As an example, I am using the xen boot command:
kernel /xen.gz com1=3D115200,8n1,0xe880/921600,0
console=3Dcom1
Signed-off-by: Don Dugger <donald.d.dugger@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
The basic issue is that some PCI serial devices use a non-standard
crystal to control the baud rate divisor. This patch enhances the
`com' parameter to enable you to specify the crystal frequency used by
the serial device. Since this parameter already allows you to specify
I/O address and IRQ this is all that is needed to get a PCI serial
device to work. With this patch the `com' parameter is now defined
as:
comN=BBB[/CCC][,NPS[,III[,IRQ]]]
Where `CCC' is the crystal frequency. Note that if you specify 0 for
`IRQ' Xen will run the serial device in polled mode, obviating the
need for interrupts (an advantage since this is the only way I was
able to get my PCI serial device to work).
As an example, I am using the xen boot command:
kernel /xen.gz com1=3D115200,8n1,0xe880/921600,0
console=3Dcom1
Signed-off-by: Don Dugger <donald.d.dugger@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Fri Oct 17 12:00:25 2008 +0100 (2008-10-17) |
parents | 6bf61b830153 |
children | 609d0d34450f |
files | xen/drivers/char/ns16550.c |
line diff
1.1 --- a/xen/drivers/char/ns16550.c Thu Oct 16 18:45:48 2008 +0100 1.2 +++ b/xen/drivers/char/ns16550.c Fri Oct 17 12:00:25 2008 +0100 1.3 @@ -18,17 +18,19 @@ 1.4 #include <asm/io.h> 1.5 1.6 /* 1.7 - * Configure serial port with a string <baud>,DPS,<io-base>,<irq>. 1.8 + * Configure serial port with a string: 1.9 + * <baud>[/<clock_hz>][,DPS[,<io-base>[,<irq>]]]. 1.10 * The tail of the string can be omitted if platform defaults are sufficient. 1.11 * If the baud rate is pre-configured, perhaps by a bootloader, then 'auto' 1.12 - * can be specified in place of a numeric baud rate. 1.13 + * can be specified in place of a numeric baud rate. Polled mode is specified 1.14 + * by requesting irq 0. 1.15 */ 1.16 static char opt_com1[30] = "", opt_com2[30] = ""; 1.17 string_param("com1", opt_com1); 1.18 string_param("com2", opt_com2); 1.19 1.20 static struct ns16550 { 1.21 - int baud, data_bits, parity, stop_bits, irq; 1.22 + int baud, clock_hz, data_bits, parity, stop_bits, irq; 1.23 unsigned long io_base; /* I/O port or memory-mapped I/O address. */ 1.24 char *remapped_io_base; /* Remapped virtual address of mmap I/O. */ 1.25 /* UART with IRQ line: interrupt-driven I/O. */ 1.26 @@ -192,7 +194,7 @@ static void __devinit ns16550_init_preir 1.27 if ( uart->baud != BAUD_AUTO ) 1.28 { 1.29 /* Baud rate specified: program it into the divisor latch. */ 1.30 - divisor = UART_CLOCK_HZ / (uart->baud * 16); 1.31 + divisor = uart->clock_hz / (uart->baud << 4); 1.32 ns_write_reg(uart, DLL, (char)divisor); 1.33 ns_write_reg(uart, DLM, (char)(divisor >> 8)); 1.34 } 1.35 @@ -201,7 +203,7 @@ static void __devinit ns16550_init_preir 1.36 /* Baud rate already set: read it out from the divisor latch. */ 1.37 divisor = ns_read_reg(uart, DLL); 1.38 divisor |= ns_read_reg(uart, DLM) << 8; 1.39 - uart->baud = UART_CLOCK_HZ / (divisor * 16); 1.40 + uart->baud = uart->clock_hz / (divisor << 4); 1.41 } 1.42 ns_write_reg(uart, LCR, lcr); 1.43 1.44 @@ -355,6 +357,12 @@ static void __init ns16550_parse_port_co 1.45 else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 ) 1.46 uart->baud = baud; 1.47 1.48 + if ( *conf == '/') 1.49 + { 1.50 + conf++; 1.51 + uart->clock_hz = simple_strtoul(conf, &conf, 0) << 4; 1.52 + } 1.53 + 1.54 if ( *conf != ',' ) 1.55 goto config_parsed; 1.56 conf++; 1.57 @@ -408,6 +416,7 @@ void __init ns16550_init(int index, stru 1.58 uart->baud = (defaults->baud ? : 1.59 console_has((index == 0) ? "com1" : "com2") 1.60 ? BAUD_AUTO : 0); 1.61 + uart->clock_hz = UART_CLOCK_HZ; 1.62 uart->data_bits = defaults->data_bits; 1.63 uart->parity = parse_parity_char(defaults->parity); 1.64 uart->stop_bits = defaults->stop_bits;