Blame view
arch/mips/cavium-octeon/serial.c
3.55 KB
5b3b16880 MIPS: Add Cavium ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2004-2007 Cavium Networks */ #include <linux/console.h> #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> #include <linux/tty.h> |
ca4d3e674 MIPS: Add missing... |
16 |
#include <linux/irq.h> |
5b3b16880 MIPS: Add Cavium ... |
17 18 19 20 |
#include <asm/time.h> #include <asm/octeon/octeon.h> |
5b3b16880 MIPS: Add Cavium ... |
21 |
#define DEBUG_UART 1 |
5b3b16880 MIPS: Add Cavium ... |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
unsigned int octeon_serial_in(struct uart_port *up, int offset) { int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); if (offset == UART_IIR && (rv & 0xf) == 7) { /* Busy interrupt, read the USR (39) and try again. */ cvmx_read_csr((uint64_t)(up->membase + (39 << 3))); rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); } return rv; } void octeon_serial_out(struct uart_port *up, int offset, int value) { /* * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits * working. */ if (offset == UART_LCR) value &= 0x9f; cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value); } /* * Allocated in .bss, so it is all zeroed. */ #define OCTEON_MAX_UARTS 3 static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1]; static struct platform_device octeon_uart8250_device = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, .dev = { .platform_data = octeon_uart8250_data, }, }; static void __init octeon_uart_set_common(struct plat_serial8250_port *p) { p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; p->iotype = UPIO_MEM; p->regshift = 3; /* I/O addresses are every 8 bytes */ |
606c958e2 MIPS: Octeon: Ser... |
64 65 66 67 |
if (octeon_is_simulation()) /* Make simulator output fast*/ p->uartclk = 115200 * 16; else |
4b8bca702 MIPS: Octeon: Use... |
68 |
p->uartclk = octeon_get_io_clock_rate(); |
5b3b16880 MIPS: Add Cavium ... |
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
p->serial_in = octeon_serial_in; p->serial_out = octeon_serial_out; } static int __init octeon_serial_init(void) { int enable_uart0; int enable_uart1; int enable_uart2; struct plat_serial8250_port *p; #ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL /* * If we are configured to run as the second of two kernels, * disable uart0 and enable uart1. Uart0 is owned by the first * kernel */ enable_uart0 = 0; enable_uart1 = 1; #else /* * We are configured for the first kernel. We'll enable uart0 * if the bootloader told us to use 0, otherwise will enable * uart 1. */ enable_uart0 = (octeon_get_boot_uart() == 0); enable_uart1 = (octeon_get_boot_uart() == 1); #ifdef CONFIG_KGDB enable_uart1 = 1; #endif #endif /* Right now CN52XX is the only chip with a third uart */ enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX); p = octeon_uart8250_data; if (enable_uart0) { /* Add a ttyS device for hardware uart 0 */ octeon_uart_set_common(p); p->membase = (void *) CVMX_MIO_UARTX_RBR(0); p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1); p->irq = OCTEON_IRQ_UART0; p++; } if (enable_uart1) { /* Add a ttyS device for hardware uart 1 */ octeon_uart_set_common(p); p->membase = (void *) CVMX_MIO_UARTX_RBR(1); p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1); p->irq = OCTEON_IRQ_UART1; p++; } if (enable_uart2) { /* Add a ttyS device for hardware uart 2 */ octeon_uart_set_common(p); p->membase = (void *) CVMX_MIO_UART2_RBR; p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1); p->irq = OCTEON_IRQ_UART2; p++; } BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]); return platform_device_register(&octeon_uart8250_device); } device_initcall(octeon_serial_init); |