diff options
author | Sascha Hauer <sascha@saschahauer.de> | 2005-08-31 16:48:47 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-08-31 16:48:47 -0400 |
commit | 0f302dc35412dc67035efc188b9d5c40711b4222 (patch) | |
tree | 57cbbe8e722e6a82bfd8bb3b8227898c54615c72 /drivers/serial | |
parent | b129a8ccd53f74c43e4c83c8e0031a4990040830 (diff) |
[ARM] 2866/1: add i.MX set_mctrl / get_mctrl functions
Patch from Sascha Hauer
This patch adds support for setting and getting RTS / CTS via
set_mtctrl / get_mctrl functions.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250.c | 79 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 2 | ||||
-rw-r--r-- | drivers/serial/imx.c | 20 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 132 |
4 files changed, 20 insertions, 213 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index cedb5f2f35cc..30a0a3d10145 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2590,82 +2590,3 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); | |||
2590 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); | 2590 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); |
2591 | #endif | 2591 | #endif |
2592 | MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); | 2592 | MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); |
2593 | |||
2594 | /** | ||
2595 | * register_serial - configure a 16x50 serial port at runtime | ||
2596 | * @req: request structure | ||
2597 | * | ||
2598 | * Configure the serial port specified by the request. If the | ||
2599 | * port exists and is in use an error is returned. If the port | ||
2600 | * is not currently in the table it is added. | ||
2601 | * | ||
2602 | * The port is then probed and if necessary the IRQ is autodetected | ||
2603 | * If this fails an error is returned. | ||
2604 | * | ||
2605 | * On success the port is ready to use and the line number is returned. | ||
2606 | * | ||
2607 | * Note: this function is deprecated - use serial8250_register_port | ||
2608 | * instead. | ||
2609 | */ | ||
2610 | int register_serial(struct serial_struct *req) | ||
2611 | { | ||
2612 | struct uart_port port; | ||
2613 | |||
2614 | port.iobase = req->port; | ||
2615 | port.membase = req->iomem_base; | ||
2616 | port.irq = req->irq; | ||
2617 | port.uartclk = req->baud_base * 16; | ||
2618 | port.fifosize = req->xmit_fifo_size; | ||
2619 | port.regshift = req->iomem_reg_shift; | ||
2620 | port.iotype = req->io_type; | ||
2621 | port.flags = req->flags | UPF_BOOT_AUTOCONF; | ||
2622 | port.mapbase = req->iomap_base; | ||
2623 | port.dev = NULL; | ||
2624 | |||
2625 | if (share_irqs) | ||
2626 | port.flags |= UPF_SHARE_IRQ; | ||
2627 | |||
2628 | if (HIGH_BITS_OFFSET) | ||
2629 | port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET; | ||
2630 | |||
2631 | /* | ||
2632 | * If a clock rate wasn't specified by the low level driver, then | ||
2633 | * default to the standard clock rate. This should be 115200 (*16) | ||
2634 | * and should not depend on the architecture's BASE_BAUD definition. | ||
2635 | * However, since this API will be deprecated, it's probably a | ||
2636 | * better idea to convert the drivers to use the new API | ||
2637 | * (serial8250_register_port and serial8250_unregister_port). | ||
2638 | */ | ||
2639 | if (port.uartclk == 0) { | ||
2640 | printk(KERN_WARNING | ||
2641 | "Serial: registering port at [%08x,%08lx,%p] irq %d with zero baud_base\n", | ||
2642 | port.iobase, port.mapbase, port.membase, port.irq); | ||
2643 | printk(KERN_WARNING "Serial: see %s:%d for more information\n", | ||
2644 | __FILE__, __LINE__); | ||
2645 | dump_stack(); | ||
2646 | |||
2647 | /* | ||
2648 | * Fix it up for now, but this is only a temporary measure. | ||
2649 | */ | ||
2650 | port.uartclk = BASE_BAUD * 16; | ||
2651 | } | ||
2652 | |||
2653 | return serial8250_register_port(&port); | ||
2654 | } | ||
2655 | EXPORT_SYMBOL(register_serial); | ||
2656 | |||
2657 | /** | ||
2658 | * unregister_serial - remove a 16x50 serial port at runtime | ||
2659 | * @line: serial line number | ||
2660 | * | ||
2661 | * Remove one serial port. This may not be called from interrupt | ||
2662 | * context. We hand the port back to our local PM control. | ||
2663 | * | ||
2664 | * Note: this function is deprecated - use serial8250_unregister_port | ||
2665 | * instead. | ||
2666 | */ | ||
2667 | void unregister_serial(int line) | ||
2668 | { | ||
2669 | serial8250_unregister_port(line); | ||
2670 | } | ||
2671 | EXPORT_SYMBOL(unregister_serial); | ||
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d5797618a3b9..74b80f7c062d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -830,7 +830,7 @@ config SERIAL_M32R_PLDSIO | |||
830 | 830 | ||
831 | config SERIAL_TXX9 | 831 | config SERIAL_TXX9 |
832 | bool "TMPTX39XX/49XX SIO support" | 832 | bool "TMPTX39XX/49XX SIO support" |
833 | depends HAS_TXX9_SERIAL | 833 | depends HAS_TXX9_SERIAL && BROKEN |
834 | select SERIAL_CORE | 834 | select SERIAL_CORE |
835 | default y | 835 | default y |
836 | 836 | ||
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 8861bcf84adf..4c985e6b3784 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -291,13 +291,31 @@ static unsigned int imx_tx_empty(struct uart_port *port) | |||
291 | return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; | 291 | return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | /* | ||
295 | * We have a modem side uart, so the meanings of RTS and CTS are inverted. | ||
296 | */ | ||
294 | static unsigned int imx_get_mctrl(struct uart_port *port) | 297 | static unsigned int imx_get_mctrl(struct uart_port *port) |
295 | { | 298 | { |
296 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 299 | struct imx_port *sport = (struct imx_port *)port; |
300 | unsigned int tmp = TIOCM_DSR | TIOCM_CAR; | ||
301 | |||
302 | if (USR1((u32)sport->port.membase) & USR1_RTSS) | ||
303 | tmp |= TIOCM_CTS; | ||
304 | |||
305 | if (UCR2((u32)sport->port.membase) & UCR2_CTS) | ||
306 | tmp |= TIOCM_RTS; | ||
307 | |||
308 | return tmp; | ||
297 | } | 309 | } |
298 | 310 | ||
299 | static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) | 311 | static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) |
300 | { | 312 | { |
313 | struct imx_port *sport = (struct imx_port *)port; | ||
314 | |||
315 | if (mctrl & TIOCM_RTS) | ||
316 | UCR2((u32)sport->port.membase) |= UCR2_CTS; | ||
317 | else | ||
318 | UCR2((u32)sport->port.membase) &= ~UCR2_CTS; | ||
301 | } | 319 | } |
302 | 320 | ||
303 | /* | 321 | /* |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index ac3a0bf924db..dea156a62d0a 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2289,143 +2289,11 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) | |||
2289 | } | 2289 | } |
2290 | EXPORT_SYMBOL(uart_match_port); | 2290 | EXPORT_SYMBOL(uart_match_port); |
2291 | 2291 | ||
2292 | /* | ||
2293 | * Try to find an unused uart_state slot for a port. | ||
2294 | */ | ||
2295 | static struct uart_state * | ||
2296 | uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port) | ||
2297 | { | ||
2298 | int i; | ||
2299 | |||
2300 | /* | ||
2301 | * First, find a port entry which matches. Note: if we do | ||
2302 | * find a matching entry, and it has a non-zero use count, | ||
2303 | * then we can't register the port. | ||
2304 | */ | ||
2305 | for (i = 0; i < drv->nr; i++) | ||
2306 | if (uart_match_port(drv->state[i].port, port)) | ||
2307 | return &drv->state[i]; | ||
2308 | |||
2309 | /* | ||
2310 | * We didn't find a matching entry, so look for the first | ||
2311 | * free entry. We look for one which hasn't been previously | ||
2312 | * used (indicated by zero iobase). | ||
2313 | */ | ||
2314 | for (i = 0; i < drv->nr; i++) | ||
2315 | if (drv->state[i].port->type == PORT_UNKNOWN && | ||
2316 | drv->state[i].port->iobase == 0 && | ||
2317 | drv->state[i].count == 0) | ||
2318 | return &drv->state[i]; | ||
2319 | |||
2320 | /* | ||
2321 | * That also failed. Last resort is to find any currently | ||
2322 | * entry which doesn't have a real port associated with it. | ||
2323 | */ | ||
2324 | for (i = 0; i < drv->nr; i++) | ||
2325 | if (drv->state[i].port->type == PORT_UNKNOWN && | ||
2326 | drv->state[i].count == 0) | ||
2327 | return &drv->state[i]; | ||
2328 | |||
2329 | return NULL; | ||
2330 | } | ||
2331 | |||
2332 | /** | ||
2333 | * uart_register_port: register uart settings with a port | ||
2334 | * @drv: pointer to the uart low level driver structure for this port | ||
2335 | * @port: uart port structure describing the port | ||
2336 | * | ||
2337 | * Register UART settings with the specified low level driver. Detect | ||
2338 | * the type of the port if UPF_BOOT_AUTOCONF is set, and detect the | ||
2339 | * IRQ if UPF_AUTO_IRQ is set. | ||
2340 | * | ||
2341 | * We try to pick the same port for the same IO base address, so that | ||
2342 | * when a modem is plugged in, unplugged and plugged back in, it gets | ||
2343 | * allocated the same port. | ||
2344 | * | ||
2345 | * Returns negative error, or positive line number. | ||
2346 | */ | ||
2347 | int uart_register_port(struct uart_driver *drv, struct uart_port *port) | ||
2348 | { | ||
2349 | struct uart_state *state; | ||
2350 | int ret; | ||
2351 | |||
2352 | down(&port_sem); | ||
2353 | |||
2354 | state = uart_find_match_or_unused(drv, port); | ||
2355 | |||
2356 | if (state) { | ||
2357 | /* | ||
2358 | * Ok, we've found a line that we can use. | ||
2359 | * | ||
2360 | * If we find a port that matches this one, and it appears | ||
2361 | * to be in-use (even if it doesn't have a type) we shouldn't | ||
2362 | * alter it underneath itself - the port may be open and | ||
2363 | * trying to do useful work. | ||
2364 | */ | ||
2365 | if (uart_users(state) != 0) { | ||
2366 | ret = -EBUSY; | ||
2367 | goto out; | ||
2368 | } | ||
2369 | |||
2370 | /* | ||
2371 | * If the port is already initialised, don't touch it. | ||
2372 | */ | ||
2373 | if (state->port->type == PORT_UNKNOWN) { | ||
2374 | state->port->iobase = port->iobase; | ||
2375 | state->port->membase = port->membase; | ||
2376 | state->port->irq = port->irq; | ||
2377 | state->port->uartclk = port->uartclk; | ||
2378 | state->port->fifosize = port->fifosize; | ||
2379 | state->port->regshift = port->regshift; | ||
2380 | state->port->iotype = port->iotype; | ||
2381 | state->port->flags = port->flags; | ||
2382 | state->port->line = state - drv->state; | ||
2383 | state->port->mapbase = port->mapbase; | ||
2384 | |||
2385 | uart_configure_port(drv, state, state->port); | ||
2386 | } | ||
2387 | |||
2388 | ret = state->port->line; | ||
2389 | } else | ||
2390 | ret = -ENOSPC; | ||
2391 | out: | ||
2392 | up(&port_sem); | ||
2393 | return ret; | ||
2394 | } | ||
2395 | |||
2396 | /** | ||
2397 | * uart_unregister_port - de-allocate a port | ||
2398 | * @drv: pointer to the uart low level driver structure for this port | ||
2399 | * @line: line index previously returned from uart_register_port() | ||
2400 | * | ||
2401 | * Hang up the specified line associated with the low level driver, | ||
2402 | * and mark the port as unused. | ||
2403 | */ | ||
2404 | void uart_unregister_port(struct uart_driver *drv, int line) | ||
2405 | { | ||
2406 | struct uart_state *state; | ||
2407 | |||
2408 | if (line < 0 || line >= drv->nr) { | ||
2409 | printk(KERN_ERR "Attempt to unregister "); | ||
2410 | printk("%s%d", drv->dev_name, line); | ||
2411 | printk("\n"); | ||
2412 | return; | ||
2413 | } | ||
2414 | |||
2415 | state = drv->state + line; | ||
2416 | |||
2417 | down(&port_sem); | ||
2418 | uart_unconfigure_port(drv, state); | ||
2419 | up(&port_sem); | ||
2420 | } | ||
2421 | |||
2422 | EXPORT_SYMBOL(uart_write_wakeup); | 2292 | EXPORT_SYMBOL(uart_write_wakeup); |
2423 | EXPORT_SYMBOL(uart_register_driver); | 2293 | EXPORT_SYMBOL(uart_register_driver); |
2424 | EXPORT_SYMBOL(uart_unregister_driver); | 2294 | EXPORT_SYMBOL(uart_unregister_driver); |
2425 | EXPORT_SYMBOL(uart_suspend_port); | 2295 | EXPORT_SYMBOL(uart_suspend_port); |
2426 | EXPORT_SYMBOL(uart_resume_port); | 2296 | EXPORT_SYMBOL(uart_resume_port); |
2427 | EXPORT_SYMBOL(uart_register_port); | ||
2428 | EXPORT_SYMBOL(uart_unregister_port); | ||
2429 | EXPORT_SYMBOL(uart_add_one_port); | 2297 | EXPORT_SYMBOL(uart_add_one_port); |
2430 | EXPORT_SYMBOL(uart_remove_one_port); | 2298 | EXPORT_SYMBOL(uart_remove_one_port); |
2431 | 2299 | ||