Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge master.kernel.org:/home/rmk/linux-2.6-serial

* master.kernel.org:/home/rmk/linux-2.6-serial:
[SERIAL] 8250: add locking to console write function
[SERIAL] Remove unconditional enable of TX irq for console
[SERIAL] 8250: set divisor register correctly for AMD Alchemy SoC uart
[SERIAL] AMD Alchemy UART: claim memory range
[SERIAL] Clean up serial locking when obtaining a reference to a port

+122 -72
+59 -15
drivers/serial/8250.c
··· 362 362 #define serial_inp(up, offset) serial_in(up, offset) 363 363 #define serial_outp(up, offset, value) serial_out(up, offset, value) 364 364 365 + /* Uart divisor latch read */ 366 + static inline int _serial_dl_read(struct uart_8250_port *up) 367 + { 368 + return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; 369 + } 370 + 371 + /* Uart divisor latch write */ 372 + static inline void _serial_dl_write(struct uart_8250_port *up, int value) 373 + { 374 + serial_outp(up, UART_DLL, value & 0xff); 375 + serial_outp(up, UART_DLM, value >> 8 & 0xff); 376 + } 377 + 378 + #ifdef CONFIG_SERIAL_8250_AU1X00 379 + /* Au1x00 haven't got a standard divisor latch */ 380 + static int serial_dl_read(struct uart_8250_port *up) 381 + { 382 + if (up->port.iotype == UPIO_AU) 383 + return __raw_readl(up->port.membase + 0x28); 384 + else 385 + return _serial_dl_read(up); 386 + } 387 + 388 + static void serial_dl_write(struct uart_8250_port *up, int value) 389 + { 390 + if (up->port.iotype == UPIO_AU) 391 + __raw_writel(value, up->port.membase + 0x28); 392 + else 393 + _serial_dl_write(up, value); 394 + } 395 + #else 396 + #define serial_dl_read(up) _serial_dl_read(up) 397 + #define serial_dl_write(up, value) _serial_dl_write(up, value) 398 + #endif 365 399 366 400 /* 367 401 * For the 16C950 ··· 528 494 */ 529 495 static int size_fifo(struct uart_8250_port *up) 530 496 { 531 - unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr; 497 + unsigned char old_fcr, old_mcr, old_lcr; 498 + unsigned short old_dl; 532 499 int count; 533 500 534 501 old_lcr = serial_inp(up, UART_LCR); ··· 540 505 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); 541 506 serial_outp(up, UART_MCR, UART_MCR_LOOP); 542 507 serial_outp(up, UART_LCR, UART_LCR_DLAB); 543 - old_dll = serial_inp(up, UART_DLL); 544 - old_dlm = serial_inp(up, UART_DLM); 545 - serial_outp(up, UART_DLL, 0x01); 546 - serial_outp(up, UART_DLM, 0x00); 508 + old_dl = serial_dl_read(up); 509 + serial_dl_write(up, 0x0001); 547 510 serial_outp(up, UART_LCR, 0x03); 548 511 for (count = 0; count < 256; count++) 549 512 serial_outp(up, UART_TX, count); ··· 552 519 serial_outp(up, UART_FCR, old_fcr); 553 520 serial_outp(up, UART_MCR, old_mcr); 554 521 serial_outp(up, UART_LCR, UART_LCR_DLAB); 555 - serial_outp(up, UART_DLL, old_dll); 556 - serial_outp(up, UART_DLM, old_dlm); 522 + serial_dl_write(up, old_dl); 557 523 serial_outp(up, UART_LCR, old_lcr); 558 524 559 525 return count; ··· 782 750 783 751 serial_outp(up, UART_LCR, 0xE0); 784 752 785 - quot = serial_inp(up, UART_DLM) << 8; 786 - quot += serial_inp(up, UART_DLL); 753 + quot = serial_dl_read(up); 787 754 quot <<= 3; 788 755 789 756 status1 = serial_in(up, 0x04); /* EXCR1 */ ··· 790 759 status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ 791 760 serial_outp(up, 0x04, status1); 792 761 793 - serial_outp(up, UART_DLL, quot & 0xff); 794 - serial_outp(up, UART_DLM, quot >> 8); 762 + serial_dl_write(up, quot); 795 763 796 764 serial_outp(up, UART_LCR, 0); 797 765 ··· 1892 1862 serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ 1893 1863 } 1894 1864 1895 - serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ 1896 - serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ 1865 + serial_dl_write(up, quot); 1897 1866 1898 1867 /* 1899 1868 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR ··· 1935 1906 int ret = 0; 1936 1907 1937 1908 switch (up->port.iotype) { 1909 + case UPIO_AU: 1910 + size = 0x100000; 1911 + /* fall thru */ 1938 1912 case UPIO_MEM: 1939 1913 if (!up->port.mapbase) 1940 1914 break; ··· 1970 1938 unsigned int size = 8 << up->port.regshift; 1971 1939 1972 1940 switch (up->port.iotype) { 1941 + case UPIO_AU: 1942 + size = 0x100000; 1943 + /* fall thru */ 1973 1944 case UPIO_MEM: 1974 1945 if (!up->port.mapbase) 1975 1946 break; ··· 2235 2200 serial8250_console_write(struct console *co, const char *s, unsigned int count) 2236 2201 { 2237 2202 struct uart_8250_port *up = &serial8250_ports[co->index]; 2203 + unsigned long flags; 2238 2204 unsigned int ier; 2205 + int locked = 1; 2239 2206 2240 2207 touch_nmi_watchdog(); 2208 + 2209 + if (oops_in_progress) { 2210 + locked = spin_trylock_irqsave(&up->port.lock, flags); 2211 + } else 2212 + spin_lock_irqsave(&up->port.lock, flags); 2241 2213 2242 2214 /* 2243 2215 * First save the IER then disable the interrupts ··· 2263 2221 * and restore the IER 2264 2222 */ 2265 2223 wait_for_xmitr(up, BOTH_EMPTY); 2266 - up->ier |= UART_IER_THRI; 2267 - serial_out(up, UART_IER, ier | UART_IER_THRI); 2224 + serial_out(up, UART_IER, ier); 2225 + 2226 + if (locked) 2227 + spin_unlock_irqrestore(&up->port.lock, flags); 2268 2228 } 2269 2229 2270 2230 static int serial8250_console_setup(struct console *co, char *options)
+2 -3
drivers/serial/8250_au1x00.c
··· 30 30 { \ 31 31 .iobase = _base, \ 32 32 .membase = (void __iomem *)_base,\ 33 - .mapbase = _base, \ 33 + .mapbase = CPHYSADDR(_base), \ 34 34 .irq = _irq, \ 35 35 .uartclk = 0, /* filled */ \ 36 36 .regshift = 2, \ 37 37 .iotype = UPIO_AU, \ 38 - .flags = UPF_SKIP_TEST | \ 39 - UPF_IOREMAP, \ 38 + .flags = UPF_SKIP_TEST \ 40 39 } 41 40 42 41 static struct plat_serial8250_port au1x00_data[] = {
+60 -54
drivers/serial/serial_core.c
··· 1500 1500 static struct uart_state *uart_get(struct uart_driver *drv, int line) 1501 1501 { 1502 1502 struct uart_state *state; 1503 + int ret = 0; 1503 1504 1504 - mutex_lock(&port_mutex); 1505 1505 state = drv->state + line; 1506 1506 if (mutex_lock_interruptible(&state->mutex)) { 1507 - state = ERR_PTR(-ERESTARTSYS); 1508 - goto out; 1507 + ret = -ERESTARTSYS; 1508 + goto err; 1509 1509 } 1510 1510 1511 1511 state->count++; 1512 - if (!state->port) { 1513 - state->count--; 1514 - mutex_unlock(&state->mutex); 1515 - state = ERR_PTR(-ENXIO); 1516 - goto out; 1512 + if (!state->port || state->port->flags & UPF_DEAD) { 1513 + ret = -ENXIO; 1514 + goto err_unlock; 1517 1515 } 1518 1516 1519 1517 if (!state->info) { ··· 1529 1531 tasklet_init(&state->info->tlet, uart_tasklet_action, 1530 1532 (unsigned long)state); 1531 1533 } else { 1532 - state->count--; 1533 - mutex_unlock(&state->mutex); 1534 - state = ERR_PTR(-ENOMEM); 1534 + ret = -ENOMEM; 1535 + goto err_unlock; 1535 1536 } 1536 1537 } 1537 - 1538 - out: 1539 - mutex_unlock(&port_mutex); 1540 1538 return state; 1539 + 1540 + err_unlock: 1541 + state->count--; 1542 + mutex_unlock(&state->mutex); 1543 + err: 1544 + return ERR_PTR(ret); 1541 1545 } 1542 1546 1543 1547 /* ··· 2085 2085 } 2086 2086 } 2087 2087 2088 - /* 2089 - * This reverses the effects of uart_configure_port, hanging up the 2090 - * port before removal. 2091 - */ 2092 - static void 2093 - uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state) 2094 - { 2095 - struct uart_port *port = state->port; 2096 - struct uart_info *info = state->info; 2097 - 2098 - if (info && info->tty) 2099 - tty_vhangup(info->tty); 2100 - 2101 - mutex_lock(&state->mutex); 2102 - 2103 - state->info = NULL; 2104 - 2105 - /* 2106 - * Free the port IO and memory resources, if any. 2107 - */ 2108 - if (port->type != PORT_UNKNOWN) 2109 - port->ops->release_port(port); 2110 - 2111 - /* 2112 - * Indicate that there isn't a port here anymore. 2113 - */ 2114 - port->type = PORT_UNKNOWN; 2115 - 2116 - /* 2117 - * Kill the tasklet, and free resources. 2118 - */ 2119 - if (info) { 2120 - tasklet_kill(&info->tlet); 2121 - kfree(info); 2122 - } 2123 - 2124 - mutex_unlock(&state->mutex); 2125 - } 2126 - 2127 2088 static struct tty_operations uart_ops = { 2128 2089 .open = uart_open, 2129 2090 .close = uart_close, ··· 2231 2270 state = drv->state + port->line; 2232 2271 2233 2272 mutex_lock(&port_mutex); 2273 + mutex_lock(&state->mutex); 2234 2274 if (state->port) { 2235 2275 ret = -EINVAL; 2236 2276 goto out; ··· 2266 2304 port->cons && !(port->cons->flags & CON_ENABLED)) 2267 2305 register_console(port->cons); 2268 2306 2307 + /* 2308 + * Ensure UPF_DEAD is not set. 2309 + */ 2310 + port->flags &= ~UPF_DEAD; 2311 + 2269 2312 out: 2313 + mutex_unlock(&state->mutex); 2270 2314 mutex_unlock(&port_mutex); 2271 2315 2272 2316 return ret; ··· 2290 2322 int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) 2291 2323 { 2292 2324 struct uart_state *state = drv->state + port->line; 2325 + struct uart_info *info; 2293 2326 2294 2327 BUG_ON(in_interrupt()); 2295 2328 ··· 2301 2332 mutex_lock(&port_mutex); 2302 2333 2303 2334 /* 2335 + * Mark the port "dead" - this prevents any opens from 2336 + * succeeding while we shut down the port. 2337 + */ 2338 + mutex_lock(&state->mutex); 2339 + port->flags |= UPF_DEAD; 2340 + mutex_unlock(&state->mutex); 2341 + 2342 + /* 2304 2343 * Remove the devices from devfs 2305 2344 */ 2306 2345 tty_unregister_device(drv->tty_driver, port->line); 2307 2346 2308 - uart_unconfigure_port(drv, state); 2347 + info = state->info; 2348 + if (info && info->tty) 2349 + tty_vhangup(info->tty); 2350 + 2351 + /* 2352 + * All users of this port should now be disconnected from 2353 + * this driver, and the port shut down. We should be the 2354 + * only thread fiddling with this port from now on. 2355 + */ 2356 + state->info = NULL; 2357 + 2358 + /* 2359 + * Free the port IO and memory resources, if any. 2360 + */ 2361 + if (port->type != PORT_UNKNOWN) 2362 + port->ops->release_port(port); 2363 + 2364 + /* 2365 + * Indicate that there isn't a port here anymore. 2366 + */ 2367 + port->type = PORT_UNKNOWN; 2368 + 2369 + /* 2370 + * Kill the tasklet, and free resources. 2371 + */ 2372 + if (info) { 2373 + tasklet_kill(&info->tlet); 2374 + kfree(info); 2375 + } 2376 + 2309 2377 state->port = NULL; 2310 2378 mutex_unlock(&port_mutex); 2311 2379
+1
include/linux/serial_core.h
··· 254 254 #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) 255 255 #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) 256 256 #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) 257 + #define UPF_DEAD ((__force upf_t) (1 << 30)) 257 258 #define UPF_IOREMAP ((__force upf_t) (1 << 31)) 258 259 259 260 #define UPF_CHANGE_MASK ((__force upf_t) (0x17fff))