* share_irqs - whether we pass SA_SHIRQ to request_irq(). This option
* is unsafe when used on edge-triggered interrupts.
*/
-unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
/*
* Debugging.
.fifo_size = 32,
.tx_loadsz = 32,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- .flags = UART_CAP_FIFO,
+ .flags = UART_CAP_FIFO | UART_CAP_UUE,
},
};
static void autoconfig_16550a(struct uart_8250_port *up)
{
unsigned char status1, status2;
+ unsigned int iersave;
up->port.type = PORT_16550A;
up->capabilities |= UART_CAP_FIFO;
* from EXCR1. Switch back to bank 0, change it in MCR. Then
* switch back to bank 2, read it from EXCR1 again and check
* it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
- * On PowerPC we don't want to change baud_base, as we have
- * a number of different divisors. -- Tom Rini
*/
serial_outp(up, UART_LCR, 0);
status1 = serial_in(up, UART_MCR);
serial_outp(up, UART_MCR, status1);
if ((status2 ^ status1) & UART_MCR_LOOP) {
-#ifndef CONFIG_PPC
+ unsigned short quot;
+
serial_outp(up, UART_LCR, 0xE0);
+
+ quot = serial_inp(up, UART_DLM) << 8;
+ quot += serial_inp(up, UART_DLL);
+ quot <<= 3;
+
status1 = serial_in(up, 0x04); /* EXCR1 */
status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
serial_outp(up, 0x04, status1);
+
+ serial_outp(up, UART_DLL, quot & 0xff);
+ serial_outp(up, UART_DLM, quot >> 8);
+
serial_outp(up, UART_LCR, 0);
- up->port.uartclk = 921600*16;
-#endif
+ up->port.uartclk = 921600*16;
up->port.type = PORT_NS16550A;
up->capabilities |= UART_NATSEMI;
return;
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
status2 = serial_in(up, UART_IIR) >> 5;
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_outp(up, UART_LCR, 0);
DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
return;
}
+
+ /*
+ * Try writing and reading the UART_IER_UUE bit (b6).
+ * If it works, this is probably one of the Xscale platform's
+ * internal UARTs.
+ * We're going to explicitly set the UUE bit to 0 before
+ * trying to write and read a 1 just to make sure it's not
+ * already a 1 and maybe locked there before we even start start.
+ */
+ iersave = serial_in(up, UART_IER);
+ serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
+ if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
+ /*
+ * OK it's in a known zero state, try writing and reading
+ * without disturbing the current state of the other bits.
+ */
+ serial_outp(up, UART_IER, iersave | UART_IER_UUE);
+ if (serial_in(up, UART_IER) & UART_IER_UUE) {
+ /*
+ * It's an Xscale.
+ * We'll leave the UART_IER_UUE bit set to 1 (enabled).
+ */
+ DEBUG_AUTOCONF("Xscale ");
+ up->port.type = PORT_XSCALE;
+ up->capabilities |= UART_CAP_UUE;
+ return;
+ }
+ } else {
+ /*
+ * If we got here we couldn't force the IER_UUE bit to 0.
+ * Log it and continue.
+ */
+ DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
+ }
+ serial_outp(up, UART_IER, iersave);
}
/*
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 */
+ /*
+ * If this failed then we will throw away the
+ * bytes but must do so to clear interrupts
+ */
}
ch = serial_inp(up, UART_RX);
flag = TTY_NORMAL;
up->port.icount.overrun++;
/*
- * Mask off conditions which should be ingored.
+ * Mask off conditions which should be ignored.
*/
lsr &= up->port.read_status_mask;
}
if (uart_handle_sysrq_char(&up->port, ch, regs))
goto ignore_char;
- if ((lsr & up->port.ignore_status_mask) == 0) {
- tty_insert_flip_char(tty, ch, flag);
- }
- if ((lsr & UART_LSR_OE) &&
- tty->flip.count < TTY_FLIPBUF_SIZE) {
- /*
- * Overrun is special, since it's reported
- * immediately, and doesn't affect the current
- * character.
- */
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- }
+
+ uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
+
ignore_char:
lsr = serial_inp(up, UART_LSR);
} while ((lsr & UART_LSR_DR) && (max_count-- > 0));
up->ier &= ~UART_IER_MSI;
if (UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
- if (up->port.type == PORT_XSCALE)
+ if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
serial_out(up, UART_IER, up->ier);
*/
ier = serial_in(up, UART_IER);
- if (up->port.type == PORT_XSCALE)
+ if (up->capabilities & UART_CAP_UUE)
serial_out(up, UART_IER, UART_IER_UUE);
else
serial_out(up, UART_IER, 0);
}
console_initcall(serial8250_console_init);
-static int __init serial8250_late_console_init(void)
-{
- if (!(serial8250_console.flags & CON_ENABLED))
- register_console(&serial8250_console);
- return 0;
-}
-late_initcall(serial8250_late_console_init);
-
static int __init find_port(struct uart_port *p)
{
int line;
return 0;
}
-static int serial8250_suspend(struct device *dev, u32 state, u32 level)
+static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
{
int i;
*/
static DECLARE_MUTEX(serial_sem);
-/*
- * Are the two ports equivalent?
- */
-static int uart_match_port(struct uart_port *port1, struct uart_port *port2)
-{
- if (port1->iotype != port2->iotype)
- return 0;
-
- switch (port1->iotype) {
- case UPIO_PORT:
- return (port1->iobase == port2->iobase);
- case UPIO_HUB6:
- return (port1->iobase == port2->iobase) &&
- (port1->hub6 == port2->hub6);
- case UPIO_MEM:
- return (port1->membase == port2->membase);
- }
- return 0;
-}
-
static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
{
int i;
* If this fails an error is returned.
*
* On success the port is ready to use and the line number is returned.
+ *
+ * Note: this function is deprecated - use serial8250_register_port
+ * instead.
*/
int register_serial(struct serial_struct *req)
{
*
* Remove one serial port. This may not be called from interrupt
* context. We hand the port back to our local PM control.
+ *
+ * Note: this function is deprecated - use serial8250_unregister_port
+ * instead.
*/
void unregister_serial(int line)
{