ia64/xen-unstable

changeset 5299:35b69ed1f23b

bitkeeper revision 1.1660 (42a027a8dd_EUm7b7XhKL_lNM4H_Rg)

Add support for memory-mapped ns16550 uart.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Jun 03 09:49:28 2005 +0000 (2005-06-03)
parents b3907ddefba4
children 56913f1c3e0d
files xen/arch/x86/dmi_scan.c xen/drivers/char/ns16550.c xen/include/asm-x86/io.h
line diff
     1.1 --- a/xen/arch/x86/dmi_scan.c	Fri Jun 03 08:12:15 2005 +0000
     1.2 +++ b/xen/arch/x86/dmi_scan.c	Fri Jun 03 09:49:28 2005 +0000
     1.3 @@ -12,7 +12,6 @@
     1.4  
     1.5  #define bt_ioremap(b,l)  ((u8 *)__acpi_map_table(b,l))
     1.6  #define bt_iounmap(b,l)  ((void)0)
     1.7 -#define ioremap(b,l)     (__va(b))
     1.8  #define memcpy_fromio    memcpy
     1.9  #define alloc_bootmem(l) xmalloc_bytes(l)
    1.10  
     2.1 --- a/xen/drivers/char/ns16550.c	Fri Jun 03 08:12:15 2005 +0000
     2.2 +++ b/xen/drivers/char/ns16550.c	Fri Jun 03 09:49:28 2005 +0000
     2.3 @@ -21,11 +21,13 @@ string_param("com1", opt_com1);
     2.4  string_param("com2", opt_com2);
     2.5  
     2.6  static struct ns16550 {
     2.7 -    int baud, data_bits, parity, stop_bits, io_base, irq;
     2.8 +    int baud, data_bits, parity, stop_bits, irq;
     2.9 +    unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
    2.10 +    char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */ 
    2.11      struct irqaction irqaction;
    2.12  } ns16550_com[2] = {
    2.13 -    { 0, 0, 0, 0, 0x3f8, 4 },
    2.14 -    { 0, 0, 0, 0, 0x2f8, 3 }
    2.15 +    { 0, 0, 0, 0, 4, 0x3f8 },
    2.16 +    { 0, 0, 0, 0, 3, 0x2f8 }
    2.17  };
    2.18  
    2.19  /* Register offsets */
    2.20 @@ -82,6 +84,20 @@ static struct ns16550 {
    2.21  #define PARITY_MARK     (5<<3)
    2.22  #define PARITY_SPACE    (7<<3)
    2.23  
    2.24 +static char ns_read_reg(struct ns16550 *uart, int reg)
    2.25 +{
    2.26 +    if ( uart->remapped_io_base == NULL )
    2.27 +        return inb(uart->io_base + reg);
    2.28 +    return readb(uart->remapped_io_base + reg);
    2.29 +}
    2.30 +
    2.31 +static void ns_write_reg(struct ns16550 *uart, int reg, char c)
    2.32 +{
    2.33 +    if ( uart->remapped_io_base == NULL )
    2.34 +        return outb(c, uart->io_base + reg);
    2.35 +    writeb(c, uart->remapped_io_base + reg);
    2.36 +}
    2.37 +
    2.38  static void ns16550_interrupt(
    2.39      int irq, void *dev_id, struct cpu_user_regs *regs)
    2.40  {
    2.41 @@ -92,20 +108,20 @@ static void ns16550_putc(struct serial_p
    2.42  {
    2.43      struct ns16550 *uart = port->uart;
    2.44  
    2.45 -    while ( !(inb(uart->io_base + LSR) & LSR_THRE) )
    2.46 +    while ( !(ns_read_reg(uart, LSR) & LSR_THRE) )
    2.47          cpu_relax();
    2.48  
    2.49 -    outb(c, uart->io_base + THR);
    2.50 +    ns_write_reg(uart, THR, c);
    2.51  }
    2.52  
    2.53  static int ns16550_getc(struct serial_port *port, char *pc)
    2.54  {
    2.55      struct ns16550 *uart = port->uart;
    2.56  
    2.57 -    if ( !(inb(uart->io_base + LSR) & LSR_DR) )
    2.58 +    if ( !(ns_read_reg(uart, LSR) & LSR_DR) )
    2.59          return 0;
    2.60  
    2.61 -    *pc = inb(uart->io_base + RBR);
    2.62 +    *pc = ns_read_reg(uart, RBR);
    2.63      return 1;
    2.64  }
    2.65  
    2.66 @@ -114,22 +130,26 @@ static void ns16550_init_preirq(struct s
    2.67      struct ns16550 *uart = port->uart;
    2.68      unsigned char lcr;
    2.69  
    2.70 +    /* I/O ports are distinguished by their size (16 bits). */
    2.71 +    if ( uart->io_base >= 0x10000 )
    2.72 +        uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
    2.73 +
    2.74      lcr = (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | uart->parity;
    2.75  
    2.76      /* No interrupts. */
    2.77 -    outb(0, uart->io_base + IER);
    2.78 +    ns_write_reg(uart, IER, 0);
    2.79  
    2.80      /* Line control and baud-rate generator. */
    2.81 -    outb(lcr | LCR_DLAB,    uart->io_base + LCR);
    2.82 -    outb(115200/uart->baud, uart->io_base + DLL); /* baud lo */
    2.83 -    outb(0,                 uart->io_base + DLM); /* baud hi */
    2.84 -    outb(lcr,               uart->io_base + LCR); /* parity, data, stop */
    2.85 +    ns_write_reg(uart, LCR, lcr | LCR_DLAB);
    2.86 +    ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */
    2.87 +    ns_write_reg(uart, DLM, 0);                 /* baud hi */
    2.88 +    ns_write_reg(uart, LCR, lcr);               /* parity, data, stop */
    2.89  
    2.90      /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */
    2.91 -    outb(MCR_DTR | MCR_RTS, uart->io_base + MCR);
    2.92 +    ns_write_reg(uart, MCR, MCR_DTR | MCR_RTS);
    2.93  
    2.94      /* Enable and clear the FIFOs. Set a large trigger threshold. */
    2.95 -    outb(FCR_ENABLE | FCR_CLRX | FCR_CLTX | FCR_TRG14, uart->io_base + FCR);
    2.96 +    ns_write_reg(uart, FCR, FCR_ENABLE | FCR_CLRX | FCR_CLTX | FCR_TRG14);
    2.97  }
    2.98  
    2.99  static void ns16550_init_postirq(struct serial_port *port)
   2.100 @@ -144,13 +164,13 @@ static void ns16550_init_postirq(struct 
   2.101          printk("ERROR: Failed to allocate na16550 IRQ %d\n", uart->irq);
   2.102  
   2.103      /* For sanity, clear the receive FIFO. */
   2.104 -    outb(FCR_ENABLE | FCR_CLRX | FCR_TRG14, uart->io_base + FCR);
   2.105 +    ns_write_reg(uart, FCR, FCR_ENABLE | FCR_CLRX | FCR_TRG14);
   2.106  
   2.107      /* Master interrupt enable; also keep DTR/RTS asserted. */
   2.108 -    outb(MCR_OUT2 | MCR_DTR | MCR_RTS, uart->io_base + MCR);
   2.109 +    ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
   2.110  
   2.111      /* Enable receive interrupts. */
   2.112 -    outb(IER_ERDAI, uart->io_base + IER);
   2.113 +    ns_write_reg(uart, IER, IER_ERDAI);
   2.114  }
   2.115  
   2.116  #ifdef CONFIG_X86
   2.117 @@ -227,20 +247,13 @@ static void ns16550_parse_port_config(st
   2.118      if ( *conf == ',' )
   2.119      {
   2.120          conf++;
   2.121 -
   2.122          uart->io_base = simple_strtol(conf, &conf, 0);
   2.123 -        if ( (uart->io_base <= 0x0000) || (uart->io_base > 0xfff0) )
   2.124 -            PARSE_ERR("I/O port base 0x%x is outside the supported range.",
   2.125 -                      uart->io_base);
   2.126  
   2.127 -        if ( *conf != ',' )
   2.128 -            PARSE_ERR("Missing IRQ specifier.");
   2.129 -            
   2.130 -        conf++;
   2.131 -            
   2.132 -        uart->irq = simple_strtol(conf, &conf, 10);
   2.133 -        if ( (uart->irq <= 0) || (uart->irq >= 32) )
   2.134 -            PARSE_ERR("IRQ %d is outside the supported range.", uart->irq);
   2.135 +        if ( *conf == ',' )
   2.136 +        {
   2.137 +            conf++;
   2.138 +            uart->irq = simple_strtol(conf, &conf, 10);
   2.139 +        }
   2.140      }
   2.141  
   2.142      serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
     3.1 --- a/xen/include/asm-x86/io.h	Fri Jun 03 08:12:15 2005 +0000
     3.2 +++ b/xen/include/asm-x86/io.h	Fri Jun 03 09:49:28 2005 +0000
     3.3 @@ -54,6 +54,15 @@ static inline void * phys_to_virt(unsign
     3.4  #define page_to_pfn(_page)  ((unsigned long)((_page) - frame_table))
     3.5  #define page_to_virt(_page) phys_to_virt(page_to_phys(_page))
     3.6  
     3.7 +/* We don't need real ioremap() on Xen/x86. */
     3.8 +#define ioremap(x,l) (__va(x))
     3.9 +
    3.10 +#define readb(x) (*(volatile char *)(x))
    3.11 +#define readw(x) (*(volatile short *)(x))
    3.12 +#define readl(x) (*(volatile int *)(x))
    3.13 +#define writeb(d,x) (*(volatile char *)(x) = (d))
    3.14 +#define writew(d,x) (*(volatile short *)(x) = (d))
    3.15 +#define writel(d,x) (*(volatile int *)(x) = (d))
    3.16  
    3.17  /*
    3.18   * IO bus memory addresses are also 1:1 with the physical address