aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorSascha Hauer <sascha@saschahauer.de>2005-08-31 16:48:47 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-08-31 16:48:47 -0400
commit0f302dc35412dc67035efc188b9d5c40711b4222 (patch)
tree57cbbe8e722e6a82bfd8bb3b8227898c54615c72 /drivers/serial
parentb129a8ccd53f74c43e4c83c8e0031a4990040830 (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.c79
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/imx.c20
-rw-r--r--drivers/serial/serial_core.c132
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);
2590MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); 2590MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
2591#endif 2591#endif
2592MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); 2592MODULE_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 */
2610int 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}
2655EXPORT_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 */
2667void unregister_serial(int line)
2668{
2669 serial8250_unregister_port(line);
2670}
2671EXPORT_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
831config SERIAL_TXX9 831config 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 */
294static unsigned int imx_get_mctrl(struct uart_port *port) 297static 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
299static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) 311static 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}
2290EXPORT_SYMBOL(uart_match_port); 2290EXPORT_SYMBOL(uart_match_port);
2291 2291
2292/*
2293 * Try to find an unused uart_state slot for a port.
2294 */
2295static struct uart_state *
2296uart_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 */
2347int 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 */
2404void 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
2422EXPORT_SYMBOL(uart_write_wakeup); 2292EXPORT_SYMBOL(uart_write_wakeup);
2423EXPORT_SYMBOL(uart_register_driver); 2293EXPORT_SYMBOL(uart_register_driver);
2424EXPORT_SYMBOL(uart_unregister_driver); 2294EXPORT_SYMBOL(uart_unregister_driver);
2425EXPORT_SYMBOL(uart_suspend_port); 2295EXPORT_SYMBOL(uart_suspend_port);
2426EXPORT_SYMBOL(uart_resume_port); 2296EXPORT_SYMBOL(uart_resume_port);
2427EXPORT_SYMBOL(uart_register_port);
2428EXPORT_SYMBOL(uart_unregister_port);
2429EXPORT_SYMBOL(uart_add_one_port); 2297EXPORT_SYMBOL(uart_add_one_port);
2430EXPORT_SYMBOL(uart_remove_one_port); 2298EXPORT_SYMBOL(uart_remove_one_port);
2431 2299