mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
[PATCH] txx9 serial update
Support for the new RBHMA4500 eval board for the TX4938. General update from the 8250 ancestor of this driver. Replace use of deprecated interfaces. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Acked-by: Russell King <rmk@arm.linux.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
fef266580e
commit
f5ee56cc18
@ -31,6 +31,8 @@
|
||||
* 1.01 Set fifosize to make tx_empry called properly.
|
||||
* Use standard uart_get_divisor.
|
||||
* 1.02 Cleanup. (import 8250.c changes)
|
||||
* 1.03 Fix low-latency mode. (import 8250.c changes)
|
||||
* 1.04 Remove usage of deprecated functions, cleanup.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
@ -54,7 +56,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
static char *serial_version = "1.02";
|
||||
static char *serial_version = "1.04";
|
||||
static char *serial_name = "TX39/49 Serial driver";
|
||||
|
||||
#define PASS_LIMIT 256
|
||||
@ -86,9 +88,9 @@ static char *serial_name = "TX39/49 Serial driver";
|
||||
*/
|
||||
#ifdef ENABLE_SERIAL_TXX9_PCI
|
||||
#define NR_PCI_BOARDS 4
|
||||
#define UART_NR (2 + NR_PCI_BOARDS)
|
||||
#define UART_NR (4 + NR_PCI_BOARDS)
|
||||
#else
|
||||
#define UART_NR 2
|
||||
#define UART_NR 4
|
||||
#endif
|
||||
|
||||
struct uart_txx9_port {
|
||||
@ -304,8 +306,11 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
|
||||
/* The following is not allowed by the tty layer and
|
||||
unsafe. It should be fixed ASAP */
|
||||
if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
|
||||
if(tty->low_latency)
|
||||
if (tty->low_latency) {
|
||||
spin_unlock(&up->port.lock);
|
||||
tty_flip_buffer_push(tty);
|
||||
spin_lock(&up->port.lock);
|
||||
}
|
||||
/* If this failed then we will throw away the
|
||||
bytes but must do so to clear interrupts */
|
||||
}
|
||||
@ -356,7 +361,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
|
||||
ignore_char:
|
||||
disr = sio_in(up, TXX9_SIDISR);
|
||||
} while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
|
||||
spin_unlock(&up->port.lock);
|
||||
tty_flip_buffer_push(tty);
|
||||
spin_lock(&up->port.lock);
|
||||
*status = disr;
|
||||
}
|
||||
|
||||
@ -667,17 +674,8 @@ serial_txx9_pm(struct uart_port *port, unsigned int state,
|
||||
unsigned int oldstate)
|
||||
{
|
||||
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
|
||||
if (state) {
|
||||
/* sleep */
|
||||
|
||||
if (up->pm)
|
||||
up->pm(port, state, oldstate);
|
||||
} else {
|
||||
/* wake */
|
||||
|
||||
if (up->pm)
|
||||
up->pm(port, state, oldstate);
|
||||
}
|
||||
}
|
||||
|
||||
static int serial_txx9_request_resource(struct uart_txx9_port *up)
|
||||
@ -979,14 +977,6 @@ static int __init serial_txx9_console_init(void)
|
||||
}
|
||||
console_initcall(serial_txx9_console_init);
|
||||
|
||||
static int __init serial_txx9_late_console_init(void)
|
||||
{
|
||||
if (!(serial_txx9_console.flags & CON_ENABLED))
|
||||
register_console(&serial_txx9_console);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(serial_txx9_late_console_init);
|
||||
|
||||
#define SERIAL_TXX9_CONSOLE &serial_txx9_console
|
||||
#else
|
||||
#define SERIAL_TXX9_CONSOLE NULL
|
||||
@ -1039,6 +1029,73 @@ static void serial_txx9_resume_port(int line)
|
||||
uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
|
||||
}
|
||||
|
||||
static DECLARE_MUTEX(serial_txx9_sem);
|
||||
|
||||
/**
|
||||
* serial_txx9_register_port - register a serial port
|
||||
* @port: serial port template
|
||||
*
|
||||
* Configure the serial port specified by the request.
|
||||
*
|
||||
* The port is then probed and if necessary the IRQ is autodetected
|
||||
* If this fails an error is returned.
|
||||
*
|
||||
* On success the port is ready to use and the line number is returned.
|
||||
*/
|
||||
static int __devinit serial_txx9_register_port(struct uart_port *port)
|
||||
{
|
||||
int i;
|
||||
struct uart_txx9_port *uart;
|
||||
int ret = -ENOSPC;
|
||||
|
||||
down(&serial_txx9_sem);
|
||||
for (i = 0; i < UART_NR; i++) {
|
||||
uart = &serial_txx9_ports[i];
|
||||
if (uart->port.type == PORT_UNKNOWN)
|
||||
break;
|
||||
}
|
||||
if (i < UART_NR) {
|
||||
uart_remove_one_port(&serial_txx9_reg, &uart->port);
|
||||
uart->port.iobase = port->iobase;
|
||||
uart->port.membase = port->membase;
|
||||
uart->port.irq = port->irq;
|
||||
uart->port.uartclk = port->uartclk;
|
||||
uart->port.iotype = port->iotype;
|
||||
uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
|
||||
uart->port.mapbase = port->mapbase;
|
||||
if (port->dev)
|
||||
uart->port.dev = port->dev;
|
||||
ret = uart_add_one_port(&serial_txx9_reg, &uart->port);
|
||||
if (ret == 0)
|
||||
ret = uart->port.line;
|
||||
}
|
||||
up(&serial_txx9_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* serial_txx9_unregister_port - remove a txx9 serial port at runtime
|
||||
* @line: serial line number
|
||||
*
|
||||
* Remove one serial port. This may not be called from interrupt
|
||||
* context. We hand the port back to the our control.
|
||||
*/
|
||||
static void __devexit serial_txx9_unregister_port(int line)
|
||||
{
|
||||
struct uart_txx9_port *uart = &serial_txx9_ports[line];
|
||||
|
||||
down(&serial_txx9_sem);
|
||||
uart_remove_one_port(&serial_txx9_reg, &uart->port);
|
||||
uart->port.flags = 0;
|
||||
uart->port.type = PORT_UNKNOWN;
|
||||
uart->port.iobase = 0;
|
||||
uart->port.mapbase = 0;
|
||||
uart->port.membase = 0;
|
||||
uart->port.dev = NULL;
|
||||
uart_add_one_port(&serial_txx9_reg, &uart->port);
|
||||
up(&serial_txx9_sem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe one serial board. Unfortunately, there is no rhyme nor reason
|
||||
* to the arrangement of serial ports on a PCI card.
|
||||
@ -1056,13 +1113,13 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||
|
||||
memset(&port, 0, sizeof(port));
|
||||
port.ops = &serial_txx9_pops;
|
||||
port.flags |= UPF_BOOT_AUTOCONF; /* uart_ops.config_port will be called */
|
||||
port.flags |= UPF_TXX9_HAVE_CTS_LINE;
|
||||
port.uartclk = 66670000;
|
||||
port.irq = dev->irq;
|
||||
port.iotype = UPIO_PORT;
|
||||
port.iobase = pci_resource_start(dev, 1);
|
||||
line = uart_register_port(&serial_txx9_reg, &port);
|
||||
port.dev = &dev->dev;
|
||||
line = serial_txx9_register_port(&port);
|
||||
if (line < 0) {
|
||||
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
|
||||
}
|
||||
@ -1078,7 +1135,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
|
||||
pci_set_drvdata(dev, NULL);
|
||||
|
||||
if (line) {
|
||||
uart_unregister_port(&serial_txx9_reg, line);
|
||||
serial_txx9_unregister_port(line);
|
||||
pci_disable_device(dev);
|
||||
}
|
||||
}
|
||||
@ -1089,6 +1146,8 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
|
||||
|
||||
if (line)
|
||||
serial_txx9_suspend_port(line);
|
||||
pci_save_state(dev);
|
||||
pci_set_power_state(dev, pci_choose_state(dev, state));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1096,8 +1155,13 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev)
|
||||
{
|
||||
int line = (int)(long)pci_get_drvdata(dev);
|
||||
|
||||
if (line)
|
||||
pci_set_power_state(dev, PCI_D0);
|
||||
pci_restore_state(dev);
|
||||
|
||||
if (line) {
|
||||
pci_enable_device(dev);
|
||||
serial_txx9_resume_port(line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user