mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm into for-rmk
This commit is contained in:
commit
af7a535688
10414 changed files with 552605 additions and 479816 deletions
|
|
@ -4,8 +4,6 @@
|
|||
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
|
||||
*
|
||||
* Based on drivers/char/serial.c
|
||||
*
|
||||
* $Id: 21285.c,v 1.37 2002/07/28 10:03:27 rmk Exp $
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
|
|
@ -21,7 +19,7 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define BAUD_BASE (mem_fclk_21285/64)
|
||||
|
||||
|
|
@ -88,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port)
|
|||
static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned int status, ch, flag, rxs, max_count = 256;
|
||||
|
||||
status = *CSR_UARTFLG;
|
||||
|
|
@ -237,8 +235,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
|
||||
quot = uart_get_divisor(port, baud);
|
||||
|
||||
if (port->info && port->info->tty) {
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
if (port->info && port->info->port.tty) {
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned int b = port->uartclk / (16 * quot);
|
||||
tty_encode_baud_rate(tty, b, b);
|
||||
}
|
||||
|
|
@ -494,7 +492,7 @@ static int __init serial21285_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Serial: 21285 driver $Revision: 1.37 $\n");
|
||||
printk(KERN_INFO "Serial: 21285 driver\n");
|
||||
|
||||
serial21285_setup_ports();
|
||||
|
||||
|
|
@ -515,5 +513,5 @@ module_init(serial21285_init);
|
|||
module_exit(serial21285_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver $Revision: 1.37 $");
|
||||
MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver");
|
||||
MODULE_ALIAS_CHARDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
|
|||
{
|
||||
#if 0
|
||||
if(status & DCD) {
|
||||
if((info->tty->termios->c_cflag & CRTSCTS) &&
|
||||
if((info->port.tty->termios->c_cflag & CRTSCTS) &&
|
||||
((info->curregs[3] & AUTO_ENAB)==0)) {
|
||||
info->curregs[3] |= AUTO_ENAB;
|
||||
info->pendregs[3] |= AUTO_ENAB;
|
||||
|
|
@ -274,7 +274,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
|
|||
|
||||
static void receive_chars(struct m68k_serial *info, unsigned short rx)
|
||||
{
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
m68328_uart *uart = &uart_addr[info->line];
|
||||
unsigned char ch, flag;
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ static void transmit_chars(struct m68k_serial *info)
|
|||
goto clear_and_return;
|
||||
}
|
||||
|
||||
if((info->xmit_cnt <= 0) || info->tty->stopped) {
|
||||
if((info->xmit_cnt <= 0) || info->port.tty->stopped) {
|
||||
/* That's peculiar... TX ints off */
|
||||
uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
|
||||
goto clear_and_return;
|
||||
|
|
@ -403,7 +403,7 @@ static void do_softint(struct work_struct *work)
|
|||
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue);
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
#if 0
|
||||
|
|
@ -427,7 +427,7 @@ static void do_serial_hangup(struct work_struct *work)
|
|||
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup);
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
|
|
@ -471,8 +471,8 @@ static int startup(struct m68k_serial * info)
|
|||
uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
|
||||
#endif
|
||||
|
||||
if (info->tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
|
||||
/*
|
||||
|
|
@ -506,8 +506,8 @@ static void shutdown(struct m68k_serial * info)
|
|||
info->xmit_buf = 0;
|
||||
}
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->flags &= ~S_INITIALIZED;
|
||||
local_irq_restore(flags);
|
||||
|
|
@ -573,9 +573,9 @@ static void change_speed(struct m68k_serial *info)
|
|||
unsigned cflag;
|
||||
int i;
|
||||
|
||||
if (!info->tty || !info->tty->termios)
|
||||
if (!info->port.tty || !info->port.tty->termios)
|
||||
return;
|
||||
cflag = info->tty->termios->c_cflag;
|
||||
cflag = info->port.tty->termios->c_cflag;
|
||||
if (!(port = info->port))
|
||||
return;
|
||||
|
||||
|
|
@ -1131,7 +1131,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
|||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
#warning "This is not and has never been valid so fix it"
|
||||
#if 0
|
||||
if (tty->ldisc.num != ldiscs[N_TTY].num) {
|
||||
|
|
@ -1169,7 +1169,7 @@ void rs_hangup(struct tty_struct *tty)
|
|||
info->event = 0;
|
||||
info->count = 0;
|
||||
info->flags &= ~S_NORMAL_ACTIVE;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
wake_up_interruptible(&info->open_wait);
|
||||
}
|
||||
|
||||
|
|
@ -1286,7 +1286,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
|
|||
|
||||
info->count++;
|
||||
tty->driver_data = info;
|
||||
info->tty = tty;
|
||||
info->port.tty = tty;
|
||||
|
||||
/*
|
||||
* Start up serial port
|
||||
|
|
@ -1363,7 +1363,7 @@ rs68328_init(void)
|
|||
info = &m68k_soft[i];
|
||||
info->magic = SERIAL_MAGIC;
|
||||
info->port = (int) &uart_addr[i];
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
info->irq = uart_irqs[i];
|
||||
info->custom_divisor = 16;
|
||||
info->close_delay = 50;
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ static void rs_360_start(struct tty_struct *tty)
|
|||
|
||||
static _INLINE_ void receive_chars(ser_info_t *info)
|
||||
{
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
unsigned char ch, flag, *cp;
|
||||
/*int ignored = 0;*/
|
||||
int i;
|
||||
|
|
@ -514,7 +514,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
|
|||
|
||||
static _INLINE_ void receive_break(ser_info_t *info)
|
||||
{
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
|
||||
info->state->icount.brk++;
|
||||
/* Check to see if there is room in the tty buffer for
|
||||
|
|
@ -528,7 +528,7 @@ static _INLINE_ void transmit_chars(ser_info_t *info)
|
|||
{
|
||||
|
||||
if ((info->flags & TX_WAKEUP) ||
|
||||
(info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
|
||||
(info->port.tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
|
||||
schedule_work(&info->tqueue);
|
||||
}
|
||||
|
||||
|
|
@ -584,12 +584,12 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
|
|||
}
|
||||
}
|
||||
if (info->flags & ASYNC_CTS_FLOW) {
|
||||
if (info->tty->hw_stopped) {
|
||||
if (info->port.tty->hw_stopped) {
|
||||
if (status & UART_MSR_CTS) {
|
||||
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
|
||||
printk("CTS tx start...");
|
||||
#endif
|
||||
info->tty->hw_stopped = 0;
|
||||
info->port.tty->hw_stopped = 0;
|
||||
info->IER |= UART_IER_THRI;
|
||||
serial_out(info, UART_IER, info->IER);
|
||||
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
|
||||
|
|
@ -600,7 +600,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
|
|||
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
|
||||
printk("CTS tx stop...");
|
||||
#endif
|
||||
info->tty->hw_stopped = 1;
|
||||
info->port.tty->hw_stopped = 1;
|
||||
info->IER &= ~UART_IER_THRI;
|
||||
serial_out(info, UART_IER, info->IER);
|
||||
}
|
||||
|
|
@ -670,7 +670,7 @@ static void do_softint(void *private_)
|
|||
ser_info_t *info = (ser_info_t *) private_;
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
|
|
@ -693,7 +693,7 @@ static void do_serial_hangup(void *private_)
|
|||
struct async_struct *info = (struct async_struct *) private_;
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
|
|
@ -721,8 +721,8 @@ static int startup(ser_info_t *info)
|
|||
|
||||
#ifdef maybe
|
||||
if (!state->port || !state->type) {
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
goto errout;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -734,12 +734,12 @@ static int startup(ser_info_t *info)
|
|||
|
||||
#ifdef modem_control
|
||||
info->MCR = 0;
|
||||
if (info->tty->termios->c_cflag & CBAUD)
|
||||
if (info->port.tty->termios->c_cflag & CBAUD)
|
||||
info->MCR = UART_MCR_DTR | UART_MCR_RTS;
|
||||
#endif
|
||||
|
||||
if (info->tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
/*
|
||||
* and set the speed of the serial port
|
||||
|
|
@ -842,8 +842,8 @@ static void shutdown(ser_info_t *info)
|
|||
smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
}
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->flags &= ~ASYNC_INITIALIZED;
|
||||
local_irq_restore(flags);
|
||||
|
|
@ -863,9 +863,9 @@ static void change_speed(ser_info_t *info)
|
|||
volatile struct smc_regs *smcp;
|
||||
volatile struct scc_regs *sccp;
|
||||
|
||||
if (!info->tty || !info->tty->termios)
|
||||
if (!info->port.tty || !info->port.tty->termios)
|
||||
return;
|
||||
cflag = info->tty->termios->c_cflag;
|
||||
cflag = info->port.tty->termios->c_cflag;
|
||||
|
||||
state = info->state;
|
||||
|
||||
|
|
@ -936,24 +936,24 @@ static void change_speed(ser_info_t *info)
|
|||
* Set up parity check flag
|
||||
*/
|
||||
info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
|
||||
if (I_INPCK(info->tty))
|
||||
if (I_INPCK(info->port.tty))
|
||||
info->read_status_mask |= BD_SC_FR | BD_SC_PR;
|
||||
if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
|
||||
if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
|
||||
info->read_status_mask |= BD_SC_BR;
|
||||
|
||||
/*
|
||||
* Characters to ignore
|
||||
*/
|
||||
info->ignore_status_mask = 0;
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
info->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
|
||||
if (I_IGNBRK(info->tty)) {
|
||||
if (I_IGNBRK(info->port.tty)) {
|
||||
info->ignore_status_mask |= BD_SC_BR;
|
||||
/*
|
||||
* If we're ignore parity and break indicators, ignore
|
||||
* overruns too. (For real raw support).
|
||||
*/
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
info->ignore_status_mask |= BD_SC_OV;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1658,7 +1658,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
|
|||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
if (info->close_delay) {
|
||||
msleep_interruptible(jiffies_to_msecs(info->close_delay));
|
||||
|
|
@ -1758,7 +1758,7 @@ static void rs_360_hangup(struct tty_struct *tty)
|
|||
info->event = 0;
|
||||
state->count = 0;
|
||||
info->flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
wake_up_interruptible(&info->open_wait);
|
||||
}
|
||||
|
||||
|
|
@ -1919,7 +1919,7 @@ static int rs_360_open(struct tty_struct *tty, struct file * filp)
|
|||
printk("rs_open %s, count = %d\n", tty->name, info->state->count);
|
||||
#endif
|
||||
tty->driver_data = info;
|
||||
info->tty = tty;
|
||||
info->port.tty = tty;
|
||||
|
||||
/*
|
||||
* Start up serial port
|
||||
|
|
@ -1976,7 +1976,7 @@ static inline int line_info(char *buf, struct serial_state *state)
|
|||
info->port = state->port;
|
||||
info->flags = state->flags;
|
||||
info->quot = 0;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
}
|
||||
local_irq_disable();
|
||||
status = serial_in(info, UART_MSR);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $
|
||||
*
|
||||
* A note about mapbase / membase
|
||||
*
|
||||
* mapbase is the physical address of the IO port.
|
||||
|
|
@ -1289,13 +1287,24 @@ static void serial8250_enable_ms(struct uart_port *port)
|
|||
static void
|
||||
receive_chars(struct uart_8250_port *up, unsigned int *status)
|
||||
{
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned char ch, lsr = *status;
|
||||
int max_count = 256;
|
||||
char flag;
|
||||
|
||||
do {
|
||||
ch = serial_inp(up, UART_RX);
|
||||
if (likely(lsr & UART_LSR_DR))
|
||||
ch = serial_inp(up, UART_RX);
|
||||
else
|
||||
/*
|
||||
* Intel 82571 has a Serial Over Lan device that will
|
||||
* set UART_LSR_BI without setting UART_LSR_DR when
|
||||
* it receives a break. To avoid reading from the
|
||||
* receive buffer without UART_LSR_DR bit set, we
|
||||
* just force the read character to be 0
|
||||
*/
|
||||
ch = 0;
|
||||
|
||||
flag = TTY_NORMAL;
|
||||
up->port.icount.rx++;
|
||||
|
||||
|
|
@ -1344,7 +1353,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
|
|||
|
||||
ignore_char:
|
||||
lsr = serial_inp(up, UART_LSR);
|
||||
} while ((lsr & UART_LSR_DR) && (max_count-- > 0));
|
||||
} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
|
||||
spin_unlock(&up->port.lock);
|
||||
tty_flip_buffer_push(tty);
|
||||
spin_lock(&up->port.lock);
|
||||
|
|
@ -1427,7 +1436,7 @@ serial8250_handle_port(struct uart_8250_port *up)
|
|||
|
||||
DEBUG_INTR("status = %x...", status);
|
||||
|
||||
if (status & UART_LSR_DR)
|
||||
if (status & (UART_LSR_DR | UART_LSR_BI))
|
||||
receive_chars(up, &status);
|
||||
check_modem_status(up);
|
||||
if (status & UART_LSR_THRE)
|
||||
|
|
@ -1877,6 +1886,8 @@ static int serial8250_startup(struct uart_port *port)
|
|||
* allow register changes to become visible.
|
||||
*/
|
||||
spin_lock_irqsave(&up->port.lock, flags);
|
||||
if (up->port.flags & UPF_SHARE_IRQ)
|
||||
disable_irq_nosync(up->port.irq);
|
||||
|
||||
wait_for_xmitr(up, UART_LSR_THRE);
|
||||
serial_out_sync(up, UART_IER, UART_IER_THRI);
|
||||
|
|
@ -1888,6 +1899,8 @@ static int serial8250_startup(struct uart_port *port)
|
|||
iir = serial_in(up, UART_IIR);
|
||||
serial_out(up, UART_IER, 0);
|
||||
|
||||
if (up->port.flags & UPF_SHARE_IRQ)
|
||||
enable_irq(up->port.irq);
|
||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||
|
||||
/*
|
||||
|
|
@ -2934,7 +2947,7 @@ static int __init serial8250_init(void)
|
|||
if (nr_uarts > UART_NR)
|
||||
nr_uarts = UART_NR;
|
||||
|
||||
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
|
||||
printk(KERN_INFO "Serial: 8250/16550 driver"
|
||||
"%d ports, IRQ sharing %sabled\n", nr_uarts,
|
||||
share_irqs ? "en" : "dis");
|
||||
|
||||
|
|
@ -2995,7 +3008,7 @@ EXPORT_SYMBOL(serial8250_suspend_port);
|
|||
EXPORT_SYMBOL(serial8250_resume_port);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $");
|
||||
MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
|
||||
|
||||
module_param(share_irqs, uint, 0644);
|
||||
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* $Id: 8250.h,v 1.8 2002/07/21 21:32:30 rmk Exp $
|
||||
*/
|
||||
|
||||
#include <linux/serial_8250.h>
|
||||
|
|
|
|||
|
|
@ -119,3 +119,5 @@ int __init probe_serial_gsc(void)
|
|||
}
|
||||
|
||||
module_init(probe_serial_gsc);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@
|
|||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License.
|
||||
*
|
||||
* $Id: 8250_pci.c,v 1.28 2002/11/02 11:14:18 rmk Exp $
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -769,6 +767,9 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
|
|||
#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
|
||||
#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
|
||||
|
||||
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
|
||||
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
|
||||
|
||||
/*
|
||||
* Master list of serial port init/setup/exit quirks.
|
||||
* This does not describe the general nature of the port.
|
||||
|
|
@ -882,6 +883,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
|||
.setup = pci_default_setup,
|
||||
.exit = __devexit_p(pci_plx9050_exit),
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_9050,
|
||||
.subvendor = PCI_VENDOR_ID_PLX,
|
||||
.subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
|
||||
.init = pci_plx9050_init,
|
||||
.setup = pci_default_setup,
|
||||
.exit = __devexit_p(pci_plx9050_exit),
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_ROMULUS,
|
||||
|
|
@ -2199,6 +2209,11 @@ static struct pci_device_id serial_pci_tbl[] = {
|
|||
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
pbn_b2_4_921600 },
|
||||
/* Unknown card - subdevice 0x1584 */
|
||||
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
|
||||
PCI_VENDOR_ID_PLX,
|
||||
PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
|
||||
pbn_b0_4_115200 },
|
||||
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
|
||||
PCI_SUBVENDOR_ID_KEYSPAN,
|
||||
PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License.
|
||||
*
|
||||
* $Id: 8250_pnp.c,v 1.10 2002/07/21 21:32:30 rmk Exp $
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -383,21 +381,14 @@ static int __devinit check_name(char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit check_resources(struct pnp_option *option)
|
||||
static int __devinit check_resources(struct pnp_dev *dev)
|
||||
{
|
||||
struct pnp_option *tmp;
|
||||
if (!option)
|
||||
return 0;
|
||||
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
|
||||
int i;
|
||||
|
||||
for (tmp = option; tmp; tmp = tmp->next) {
|
||||
struct pnp_port *port;
|
||||
for (port = tmp->port; port; port = port->next)
|
||||
if ((port->size == 8) &&
|
||||
((port->min == 0x2f8) ||
|
||||
(port->min == 0x3f8) ||
|
||||
(port->min == 0x2e8) ||
|
||||
(port->min == 0x3e8)))
|
||||
return 1;
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++) {
|
||||
if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -420,10 +411,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
|
|||
(dev->card && check_name(dev->card->name))))
|
||||
return -ENODEV;
|
||||
|
||||
if (check_resources(dev->independent))
|
||||
return 0;
|
||||
|
||||
if (check_resources(dev->dependent))
|
||||
if (check_resources(dev))
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#
|
||||
# Serial device configuration
|
||||
#
|
||||
# $Id: Kconfig,v 1.11 2004/03/11 18:08:04 lethal Exp $
|
||||
#
|
||||
|
||||
menu "Serial drivers"
|
||||
depends on HAS_IOMEM
|
||||
|
|
@ -945,22 +943,6 @@ config SERIAL_IP22_ZILOG_CONSOLE
|
|||
depends on SERIAL_IP22_ZILOG=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
|
||||
config V850E_UART
|
||||
bool "NEC V850E on-chip UART support"
|
||||
depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
|
||||
select SERIAL_CORE
|
||||
default y
|
||||
|
||||
config V850E_UARTB
|
||||
bool
|
||||
depends on V850E_UART && V850E_ME2
|
||||
default y
|
||||
|
||||
config V850E_UART_CONSOLE
|
||||
bool "Use NEC V850E on-chip UART for console"
|
||||
depends on V850E_UART
|
||||
select SERIAL_CORE_CONSOLE
|
||||
|
||||
config SERIAL_SH_SCI
|
||||
tristate "SuperH SCI(F) serial port support"
|
||||
depends on SUPERH || H8300
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#
|
||||
# Makefile for the kernel serial device drivers.
|
||||
#
|
||||
# $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
|
||||
#
|
||||
|
||||
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
|
||||
obj-$(CONFIG_SERIAL_21285) += 21285.o
|
||||
|
|
@ -44,7 +42,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o
|
|||
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
|
||||
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
|
||||
obj-$(CONFIG_SERIAL_MCF) += mcf.o
|
||||
obj-$(CONFIG_V850E_UART) += v850e_uart.o
|
||||
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
|
||||
obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
|
||||
obj-$(CONFIG_SERIAL_DZ) += dz.o
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
|
||||
*
|
||||
* This is a generic driver for ARM AMBA-type serial ports. They
|
||||
* have a lot of 16550-like features, but are not register compatible.
|
||||
* Note that although they do have CTS, DCD and DSR inputs, they do
|
||||
|
|
@ -119,7 +117,7 @@ static void pl010_enable_ms(struct uart_port *port)
|
|||
|
||||
static void pl010_rx_chars(struct uart_amba_port *uap)
|
||||
{
|
||||
struct tty_struct *tty = uap->port.info->tty;
|
||||
struct tty_struct *tty = uap->port.info->port.tty;
|
||||
unsigned int status, ch, flag, rsr, max_count = 256;
|
||||
|
||||
status = readb(uap->port.membase + UART01x_FR);
|
||||
|
|
@ -791,7 +789,7 @@ static int __init pl010_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Serial: AMBA driver $Revision: 1.41 $\n");
|
||||
printk(KERN_INFO "Serial: AMBA driver\n");
|
||||
|
||||
ret = uart_register_driver(&amba_reg);
|
||||
if (ret == 0) {
|
||||
|
|
@ -812,5 +810,5 @@ module_init(pl010_init);
|
|||
module_exit(pl010_exit);
|
||||
|
||||
MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
|
||||
MODULE_DESCRIPTION("ARM AMBA serial port driver $Revision: 1.41 $");
|
||||
MODULE_DESCRIPTION("ARM AMBA serial port driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
|
||||
*
|
||||
* This is a generic driver for ARM AMBA-type serial ports. They
|
||||
* have a lot of 16550-like features, but are not register compatible.
|
||||
* Note that although they do have CTS, DCD and DSR inputs, they do
|
||||
|
|
@ -109,7 +107,7 @@ static void pl011_enable_ms(struct uart_port *port)
|
|||
|
||||
static void pl011_rx_chars(struct uart_amba_port *uap)
|
||||
{
|
||||
struct tty_struct *tty = uap->port.info->tty;
|
||||
struct tty_struct *tty = uap->port.info->port.tty;
|
||||
unsigned int status, ch, flag, max_count = 256;
|
||||
|
||||
status = readw(uap->port.membase + UART01x_FR);
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@
|
|||
#include <asm/io.h>
|
||||
|
||||
#include <asm/mach/serial_at91.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <mach/board.h>
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <mach/cpu.h>
|
||||
#include <mach/gpio.h>
|
||||
#endif
|
||||
|
||||
#define PDC_BUFFER_SIZE 512
|
||||
|
|
@ -662,14 +662,14 @@ static void atmel_rx_from_ring(struct uart_port *port)
|
|||
* uart_start(), which takes the lock.
|
||||
*/
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(port->info->tty);
|
||||
tty_flip_buffer_push(port->info->port.tty);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void atmel_rx_from_dma(struct uart_port *port)
|
||||
{
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
struct atmel_dma_buffer *pdc;
|
||||
int rx_idx = atmel_port->pdc_rx_idx;
|
||||
unsigned int head;
|
||||
|
|
@ -794,7 +794,7 @@ static void atmel_tasklet_func(unsigned long data)
|
|||
static int atmel_startup(struct uart_port *port)
|
||||
{
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
int retval;
|
||||
|
||||
/*
|
||||
|
|
@ -955,6 +955,20 @@ static void atmel_shutdown(struct uart_port *port)
|
|||
atmel_close_hook(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush any TX data submitted for DMA. Called when the TX circular
|
||||
* buffer is reset.
|
||||
*/
|
||||
static void atmel_flush_buffer(struct uart_port *port)
|
||||
{
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
|
||||
if (atmel_use_dma_tx(port)) {
|
||||
UART_PUT_TCR(port, 0);
|
||||
atmel_port->pdc_tx.ofs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Power / Clock management.
|
||||
*/
|
||||
|
|
@ -1189,6 +1203,7 @@ static struct uart_ops atmel_pops = {
|
|||
.break_ctl = atmel_break_ctl,
|
||||
.startup = atmel_startup,
|
||||
.shutdown = atmel_shutdown,
|
||||
.flush_buffer = atmel_flush_buffer,
|
||||
.set_termios = atmel_set_termios,
|
||||
.type = atmel_type,
|
||||
.release_port = atmel_release_port,
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ int kgdb_get_debug_char(void)
|
|||
#ifdef CONFIG_SERIAL_BFIN_PIO
|
||||
static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
|
||||
{
|
||||
struct tty_struct *tty = uart->port.info->tty;
|
||||
struct tty_struct *tty = uart->port.info->port.tty;
|
||||
unsigned int status, ch, flg;
|
||||
static struct timeval anomaly_start = { .tv_sec = 0 };
|
||||
|
||||
|
|
@ -393,7 +393,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
|
|||
|
||||
static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
|
||||
{
|
||||
struct tty_struct *tty = uart->port.info->tty;
|
||||
struct tty_struct *tty = uart->port.info->port.tty;
|
||||
int i, flg, status;
|
||||
|
||||
status = UART_GET_LSR(uart);
|
||||
|
|
@ -552,7 +552,7 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
|
|||
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
|
||||
unsigned int status;
|
||||
struct uart_info *info = uart->port.info;
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
|
||||
status = bfin_serial_get_mctrl(&uart->port);
|
||||
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
|
||||
|
|
@ -814,10 +814,10 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
|
|||
int line = port->line;
|
||||
unsigned short val;
|
||||
|
||||
if (line >= port->info->tty->driver->num)
|
||||
if (line >= port->info->port.tty->driver->num)
|
||||
return;
|
||||
|
||||
switch (port->info->tty->ldisc.num) {
|
||||
switch (port->info->port.tty->termios->c_line) {
|
||||
case N_IRDA:
|
||||
val = UART_GET_GCTL(&bfin_serial_ports[line]);
|
||||
val |= (IREN | RPOLC);
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
|
|||
static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct sport_uart_port *up = dev_id;
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned int ch;
|
||||
|
||||
do {
|
||||
|
|
@ -201,7 +201,7 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
|
|||
static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct sport_uart_port *up = dev_id;
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned int stat = SPORT_GET_STAT(up);
|
||||
|
||||
/* Overflow in RX FIFO */
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: clps711x.c,v 1.42 2002/07/28 10:03:28 rmk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
|
|
@ -42,7 +39,7 @@
|
|||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware/clps7111.h>
|
||||
|
|
@ -96,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
|
|||
static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned int status, ch, flg;
|
||||
|
||||
status = clps_readl(SYSFLG(port));
|
||||
|
|
@ -551,7 +548,7 @@ static int __init clps711xuart_init(void)
|
|||
{
|
||||
int ret, i;
|
||||
|
||||
printk(KERN_INFO "Serial: CLPS711x driver $Revision: 1.42 $\n");
|
||||
printk(KERN_INFO "Serial: CLPS711x driver\n");
|
||||
|
||||
ret = uart_register_driver(&clps711x_reg);
|
||||
if (ret)
|
||||
|
|
@ -577,6 +574,6 @@ module_init(clps711xuart_init);
|
|||
module_exit(clps711xuart_exit);
|
||||
|
||||
MODULE_AUTHOR("Deep Blue Solutions Ltd");
|
||||
MODULE_DESCRIPTION("CLPS-711x generic serial driver $Revision: 1.42 $");
|
||||
MODULE_DESCRIPTION("CLPS-711x generic serial driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* Copyright (C) 2004 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 2006 (c) MontaVista Software, Inc.
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#define SERIAL_CPM_MAJOR 204
|
||||
#define SERIAL_CPM_MINOR 46
|
||||
|
||||
#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC)
|
||||
#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC)
|
||||
#define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING)
|
||||
#define FLAG_DISCARDING 0x00000004 /* when set, don't discard */
|
||||
#define FLAG_SMC 0x00000002
|
||||
|
|
@ -50,6 +50,15 @@
|
|||
|
||||
#define SCC_WAIT_CLOSING 100
|
||||
|
||||
#define GPIO_CTS 0
|
||||
#define GPIO_RTS 1
|
||||
#define GPIO_DCD 2
|
||||
#define GPIO_DSR 3
|
||||
#define GPIO_DTR 4
|
||||
#define GPIO_RI 5
|
||||
|
||||
#define NUM_GPIOS (GPIO_RI+1)
|
||||
|
||||
struct uart_cpm_port {
|
||||
struct uart_port port;
|
||||
u16 rx_nrfifos;
|
||||
|
|
@ -68,9 +77,10 @@ struct uart_cpm_port {
|
|||
unsigned char *rx_buf;
|
||||
u32 flags;
|
||||
void (*set_lineif)(struct uart_cpm_port *);
|
||||
struct clk *clk;
|
||||
u8 brg;
|
||||
uint dp_addr;
|
||||
void *mem_addr;
|
||||
void *mem_addr;
|
||||
dma_addr_t dma_addr;
|
||||
u32 mem_size;
|
||||
/* helpers */
|
||||
|
|
@ -79,14 +89,12 @@ struct uart_cpm_port {
|
|||
/* Keep track of 'odd' SMC2 wirings */
|
||||
int is_portb;
|
||||
/* wait on close if needed */
|
||||
int wait_closing;
|
||||
int wait_closing;
|
||||
/* value to combine with opcode to form cpm command */
|
||||
u32 command;
|
||||
int gpios[NUM_GPIOS];
|
||||
};
|
||||
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
extern int cpm_uart_port_map[UART_NR];
|
||||
#endif
|
||||
extern int cpm_uart_nr;
|
||||
extern struct uart_cpm_port cpm_uart_ports[UART_NR];
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* Copyright (C) 2004, 2007 Freescale Semiconductor, Inc.
|
||||
* (C) 2004 Intracom, S.A.
|
||||
* (C) 2005-2006 MontaVista Software, Inc.
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -42,6 +42,10 @@
|
|||
#include <linux/bootmem.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fs_uart_pd.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
|
@ -49,10 +53,6 @@
|
|||
#include <asm/fs_pd.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
#include <linux/of_platform.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
#define SUPPORT_SYSRQ
|
||||
#endif
|
||||
|
|
@ -72,59 +72,6 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
|
|||
|
||||
/**************************************************************/
|
||||
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
/* Track which ports are configured as uarts */
|
||||
int cpm_uart_port_map[UART_NR];
|
||||
/* How many ports did we config as uarts */
|
||||
int cpm_uart_nr;
|
||||
|
||||
/* Place-holder for board-specific stuff */
|
||||
struct platform_device* __attribute__ ((weak)) __init
|
||||
early_uart_get_pdev(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void cpm_uart_count(void)
|
||||
{
|
||||
cpm_uart_nr = 0;
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC1
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC2
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC1
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC2
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC3
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC4
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get UART number by its id */
|
||||
static int cpm_uart_id2nr(int id)
|
||||
{
|
||||
int i;
|
||||
if (id < UART_NR) {
|
||||
for (i=0; i<UART_NR; i++) {
|
||||
if (cpm_uart_port_map[i] == id)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found or invalid argument */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check, if transmit buffers are processed
|
||||
*/
|
||||
|
|
@ -152,13 +99,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
|
|||
|
||||
static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
/* Whee. Do nothing. */
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
|
||||
if (pinfo->gpios[GPIO_RTS] >= 0)
|
||||
gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
|
||||
|
||||
if (pinfo->gpios[GPIO_DTR] >= 0)
|
||||
gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
|
||||
}
|
||||
|
||||
static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
/* Whee. Do nothing. */
|
||||
return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
|
||||
|
||||
if (pinfo->gpios[GPIO_CTS] >= 0) {
|
||||
if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
|
||||
mctrl &= ~TIOCM_CTS;
|
||||
}
|
||||
|
||||
if (pinfo->gpios[GPIO_DSR] >= 0) {
|
||||
if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
|
||||
mctrl &= ~TIOCM_DSR;
|
||||
}
|
||||
|
||||
if (pinfo->gpios[GPIO_DCD] >= 0) {
|
||||
if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
|
||||
mctrl &= ~TIOCM_CAR;
|
||||
}
|
||||
|
||||
if (pinfo->gpios[GPIO_RI] >= 0) {
|
||||
if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
|
||||
mctrl |= TIOCM_RNG;
|
||||
}
|
||||
|
||||
return mctrl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -257,6 +232,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
|
|||
cpm_uart_tx_pump(port);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
static int serial_polled;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Receive characters
|
||||
*/
|
||||
|
|
@ -265,7 +244,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
|
|||
int i;
|
||||
unsigned char ch;
|
||||
u8 *cp;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
cbd_t __iomem *bdp;
|
||||
u16 status;
|
||||
|
|
@ -278,6 +257,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
|
|||
*/
|
||||
bdp = pinfo->rx_cur;
|
||||
for (;;) {
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* get status */
|
||||
status = in_be16(&bdp->cbd_sc);
|
||||
/* If this one is empty, return happy */
|
||||
|
|
@ -309,7 +294,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
|
|||
goto handle_error;
|
||||
if (uart_handle_sysrq_char(port, ch))
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
error_return:
|
||||
tty_insert_flip_char(tty, ch, flg);
|
||||
|
||||
|
|
@ -476,10 +466,13 @@ static void cpm_uart_shutdown(struct uart_port *port)
|
|||
}
|
||||
|
||||
/* Shut them really down and reinit buffer descriptors */
|
||||
if (IS_SMC(pinfo))
|
||||
if (IS_SMC(pinfo)) {
|
||||
out_be16(&pinfo->smcup->smc_brkcr, 0);
|
||||
cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
|
||||
else
|
||||
} else {
|
||||
out_be16(&pinfo->sccup->scc_brkcr, 0);
|
||||
cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
|
||||
}
|
||||
|
||||
cpm_uart_initbd(pinfo);
|
||||
}
|
||||
|
|
@ -546,6 +539,11 @@ static void cpm_uart_set_termios(struct uart_port *port,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the timeout
|
||||
*/
|
||||
uart_update_timeout(port, termios->c_cflag, baud);
|
||||
|
||||
/*
|
||||
* Set up parity check flag
|
||||
*/
|
||||
|
|
@ -590,14 +588,19 @@ static void cpm_uart_set_termios(struct uart_port *port,
|
|||
* enables, because we want to put them back if they were
|
||||
* present.
|
||||
*/
|
||||
prev_mode = in_be16(&smcp->smc_smcmr);
|
||||
out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART);
|
||||
setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN)));
|
||||
prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN);
|
||||
/* Output in *one* operation, so we don't interrupt RX/TX if they
|
||||
* were already enabled. */
|
||||
out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval |
|
||||
SMCMR_SM_UART | prev_mode);
|
||||
} else {
|
||||
out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
|
||||
}
|
||||
|
||||
cpm_set_brg(pinfo->brg - 1, baud);
|
||||
if (pinfo->clk)
|
||||
clk_set_rate(pinfo->clk, baud);
|
||||
else
|
||||
cpm_set_brg(pinfo->brg - 1, baud);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -916,6 +919,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
|
|||
cpm_uart_request_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
/* Serial polling routines for writing and reading from the uart while
|
||||
* in an interrupt or debug context.
|
||||
*/
|
||||
|
||||
#define GDB_BUF_SIZE 512 /* power of 2, please */
|
||||
|
||||
static char poll_buf[GDB_BUF_SIZE];
|
||||
static char *pollp;
|
||||
static int poll_chars;
|
||||
|
||||
static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
|
||||
{
|
||||
u_char c, *cp;
|
||||
volatile cbd_t *bdp;
|
||||
int i;
|
||||
|
||||
/* Get the address of the host memory buffer.
|
||||
*/
|
||||
bdp = pinfo->rx_cur;
|
||||
while (bdp->cbd_sc & BD_SC_EMPTY)
|
||||
;
|
||||
|
||||
/* If the buffer address is in the CPM DPRAM, don't
|
||||
* convert it.
|
||||
*/
|
||||
cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
|
||||
|
||||
if (obuf) {
|
||||
i = c = bdp->cbd_datlen;
|
||||
while (i-- > 0)
|
||||
*obuf++ = *cp++;
|
||||
} else
|
||||
c = *cp;
|
||||
bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
|
||||
bdp->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
if (bdp->cbd_sc & BD_SC_WRAP)
|
||||
bdp = pinfo->rx_bd_base;
|
||||
else
|
||||
bdp++;
|
||||
pinfo->rx_cur = (cbd_t *)bdp;
|
||||
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
static int cpm_get_poll_char(struct uart_port *port)
|
||||
{
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
|
||||
if (!serial_polled) {
|
||||
serial_polled = 1;
|
||||
poll_chars = 0;
|
||||
}
|
||||
if (poll_chars <= 0) {
|
||||
poll_chars = poll_wait_key(poll_buf, pinfo);
|
||||
pollp = poll_buf;
|
||||
}
|
||||
poll_chars--;
|
||||
return *pollp++;
|
||||
}
|
||||
|
||||
static void cpm_put_poll_char(struct uart_port *port,
|
||||
unsigned char c)
|
||||
{
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
static char ch[2];
|
||||
|
||||
ch[0] = (char)c;
|
||||
cpm_uart_early_write(pinfo->port.line, ch, 1);
|
||||
}
|
||||
#endif /* CONFIG_CONSOLE_POLL */
|
||||
|
||||
static struct uart_ops cpm_uart_pops = {
|
||||
.tx_empty = cpm_uart_tx_empty,
|
||||
.set_mctrl = cpm_uart_set_mctrl,
|
||||
|
|
@ -933,9 +1010,12 @@ static struct uart_ops cpm_uart_pops = {
|
|||
.request_port = cpm_uart_request_port,
|
||||
.config_port = cpm_uart_config_port,
|
||||
.verify_port = cpm_uart_verify_port,
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
.poll_get_char = cpm_get_poll_char,
|
||||
.poll_put_char = cpm_put_poll_char,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
struct uart_cpm_port cpm_uart_ports[UART_NR];
|
||||
|
||||
static int cpm_uart_init_port(struct device_node *np,
|
||||
|
|
@ -945,14 +1025,23 @@ static int cpm_uart_init_port(struct device_node *np,
|
|||
void __iomem *mem, *pram;
|
||||
int len;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
data = of_get_property(np, "fsl,cpm-brg", &len);
|
||||
if (!data || len != 4) {
|
||||
printk(KERN_ERR "CPM UART %s has no/invalid "
|
||||
"fsl,cpm-brg property.\n", np->name);
|
||||
return -EINVAL;
|
||||
data = of_get_property(np, "clock", NULL);
|
||||
if (data) {
|
||||
struct clk *clk = clk_get(NULL, (const char*)data);
|
||||
if (!IS_ERR(clk))
|
||||
pinfo->clk = clk;
|
||||
}
|
||||
if (!pinfo->clk) {
|
||||
data = of_get_property(np, "fsl,cpm-brg", &len);
|
||||
if (!data || len != 4) {
|
||||
printk(KERN_ERR "CPM UART %s has no/invalid "
|
||||
"fsl,cpm-brg property.\n", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
pinfo->brg = *data;
|
||||
}
|
||||
pinfo->brg = *data;
|
||||
|
||||
data = of_get_property(np, "fsl,cpm-command", &len);
|
||||
if (!data || len != 4) {
|
||||
|
|
@ -995,6 +1084,7 @@ static int cpm_uart_init_port(struct device_node *np,
|
|||
pinfo->port.type = PORT_CPM;
|
||||
pinfo->port.ops = &cpm_uart_pops,
|
||||
pinfo->port.iotype = UPIO_MEM;
|
||||
pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
|
||||
spin_lock_init(&pinfo->port.lock);
|
||||
|
||||
pinfo->port.irq = of_irq_to_resource(np, 0, NULL);
|
||||
|
|
@ -1003,6 +1093,9 @@ static int cpm_uart_init_port(struct device_node *np,
|
|||
goto out_pram;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_GPIOS; i++)
|
||||
pinfo->gpios[i] = of_get_gpio(np, i);
|
||||
|
||||
return cpm_uart_request_port(&pinfo->port);
|
||||
|
||||
out_pram:
|
||||
|
|
@ -1012,153 +1105,6 @@ out_mem:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct uart_cpm_port cpm_uart_ports[UART_NR] = {
|
||||
[UART_SMC1] = {
|
||||
.port = {
|
||||
.irq = SMC1_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock),
|
||||
},
|
||||
.flags = FLAG_SMC,
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = smc1_lineif,
|
||||
},
|
||||
[UART_SMC2] = {
|
||||
.port = {
|
||||
.irq = SMC2_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock),
|
||||
},
|
||||
.flags = FLAG_SMC,
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = smc2_lineif,
|
||||
#ifdef CONFIG_SERIAL_CPM_ALT_SMC2
|
||||
.is_portb = 1,
|
||||
#endif
|
||||
},
|
||||
[UART_SCC1] = {
|
||||
.port = {
|
||||
.irq = SCC1_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock),
|
||||
},
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = scc1_lineif,
|
||||
.wait_closing = SCC_WAIT_CLOSING,
|
||||
},
|
||||
[UART_SCC2] = {
|
||||
.port = {
|
||||
.irq = SCC2_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock),
|
||||
},
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = scc2_lineif,
|
||||
.wait_closing = SCC_WAIT_CLOSING,
|
||||
},
|
||||
[UART_SCC3] = {
|
||||
.port = {
|
||||
.irq = SCC3_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock),
|
||||
},
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = scc3_lineif,
|
||||
.wait_closing = SCC_WAIT_CLOSING,
|
||||
},
|
||||
[UART_SCC4] = {
|
||||
.port = {
|
||||
.irq = SCC4_IRQ,
|
||||
.ops = &cpm_uart_pops,
|
||||
.iotype = UPIO_MEM,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock),
|
||||
},
|
||||
.tx_nrfifos = TX_NUM_FIFO,
|
||||
.tx_fifosize = TX_BUF_SIZE,
|
||||
.rx_nrfifos = RX_NUM_FIFO,
|
||||
.rx_fifosize = RX_BUF_SIZE,
|
||||
.set_lineif = scc4_lineif,
|
||||
.wait_closing = SCC_WAIT_CLOSING,
|
||||
},
|
||||
};
|
||||
|
||||
int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
|
||||
{
|
||||
struct resource *r;
|
||||
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
|
||||
int idx; /* It is UART_SMCx or UART_SCCx index */
|
||||
struct uart_cpm_port *pinfo;
|
||||
int line;
|
||||
u32 mem, pram;
|
||||
|
||||
idx = pdata->fs_no = fs_uart_get_id(pdata);
|
||||
|
||||
line = cpm_uart_id2nr(idx);
|
||||
if(line < 0) {
|
||||
printk(KERN_ERR"%s(): port %d is not registered", __func__, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
|
||||
|
||||
pinfo->brg = pdata->brg;
|
||||
|
||||
if (!is_con) {
|
||||
pinfo->port.line = line;
|
||||
pinfo->port.flags = UPF_BOOT_AUTOCONF;
|
||||
}
|
||||
|
||||
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
|
||||
return -EINVAL;
|
||||
mem = (u32)ioremap(r->start, r->end - r->start + 1);
|
||||
|
||||
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
|
||||
return -EINVAL;
|
||||
pram = (u32)ioremap(r->start, r->end - r->start + 1);
|
||||
|
||||
if(idx > fsid_smc2_uart) {
|
||||
pinfo->sccp = (scc_t *)mem;
|
||||
pinfo->sccup = (scc_uart_t *)pram;
|
||||
} else {
|
||||
pinfo->smcp = (smc_t *)mem;
|
||||
pinfo->smcup = (smc_uart_t *)pram;
|
||||
}
|
||||
pinfo->tx_nrfifos = pdata->tx_num_fifo;
|
||||
pinfo->tx_fifosize = pdata->tx_buf_size;
|
||||
|
||||
pinfo->rx_nrfifos = pdata->rx_num_fifo;
|
||||
pinfo->rx_fifosize = pdata->rx_buf_size;
|
||||
|
||||
pinfo->port.uartclk = pdata->uart_clk;
|
||||
pinfo->port.mapbase = (unsigned long)mem;
|
||||
pinfo->port.irq = platform_get_irq(pdev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_CONSOLE
|
||||
/*
|
||||
* Print a string to the serial port trying not to disturb
|
||||
|
|
@ -1169,15 +1115,18 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
|
|||
static void cpm_uart_console_write(struct console *co, const char *s,
|
||||
u_int count)
|
||||
{
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
|
||||
#else
|
||||
struct uart_cpm_port *pinfo =
|
||||
&cpm_uart_ports[cpm_uart_port_map[co->index]];
|
||||
#endif
|
||||
unsigned int i;
|
||||
cbd_t __iomem *bdp, *bdbase;
|
||||
unsigned char *cp;
|
||||
unsigned long flags;
|
||||
int nolock = oops_in_progress;
|
||||
|
||||
if (unlikely(nolock)) {
|
||||
local_irq_save(flags);
|
||||
} else {
|
||||
spin_lock_irqsave(&pinfo->port.lock, flags);
|
||||
}
|
||||
|
||||
/* Get the address of the host memory buffer.
|
||||
*/
|
||||
|
|
@ -1239,6 +1188,12 @@ static void cpm_uart_console_write(struct console *co, const char *s,
|
|||
;
|
||||
|
||||
pinfo->tx_cur = bdp;
|
||||
|
||||
if (unlikely(nolock)) {
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&pinfo->port.lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1252,7 +1207,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
|
|||
struct uart_cpm_port *pinfo;
|
||||
struct uart_port *port;
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
struct device_node *np = NULL;
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -1284,35 +1238,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
#else
|
||||
|
||||
struct fs_uart_platform_info *pdata;
|
||||
struct platform_device* pdev = early_uart_get_pdev(co->index);
|
||||
|
||||
if (!pdev) {
|
||||
pr_info("cpm_uart: console: compat mode\n");
|
||||
/* compatibility - will be cleaned up */
|
||||
cpm_uart_init_portdesc();
|
||||
}
|
||||
|
||||
port =
|
||||
(struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
|
||||
pinfo = (struct uart_cpm_port *)port;
|
||||
if (!pdev) {
|
||||
if (pinfo->set_lineif)
|
||||
pinfo->set_lineif(pinfo);
|
||||
} else {
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (pdata)
|
||||
if (pdata->init_ioports)
|
||||
pdata->init_ioports(pdata);
|
||||
|
||||
cpm_uart_drv_get_platform_data(pdev, 1);
|
||||
}
|
||||
|
||||
pinfo->flags |= FLAG_CONSOLE;
|
||||
#endif
|
||||
|
||||
if (options) {
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
} else {
|
||||
|
|
@ -1324,12 +1249,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
|
|||
udbg_putc = NULL;
|
||||
#endif
|
||||
|
||||
cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
|
||||
|
||||
if (IS_SMC(pinfo)) {
|
||||
out_be16(&pinfo->smcup->smc_brkcr, 0);
|
||||
cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
|
||||
clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
|
||||
clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
|
||||
} else {
|
||||
out_be16(&pinfo->sccup->scc_brkcr, 0);
|
||||
cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
|
||||
clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
|
||||
clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
}
|
||||
|
|
@ -1386,7 +1313,6 @@ static struct uart_driver cpm_reg = {
|
|||
.nr = UART_NR,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
static int probe_index;
|
||||
|
||||
static int __devinit cpm_uart_probe(struct of_device *ofdev,
|
||||
|
|
@ -1457,135 +1383,6 @@ static void __exit cpm_uart_exit(void)
|
|||
of_unregister_platform_driver(&cpm_uart_driver);
|
||||
uart_unregister_driver(&cpm_reg);
|
||||
}
|
||||
#else
|
||||
static int cpm_uart_drv_probe(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct fs_uart_platform_info *pdata;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if(!pdev) {
|
||||
printk(KERN_ERR"CPM UART: platform data missing!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
|
||||
if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
|
||||
return ret;
|
||||
|
||||
pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
|
||||
|
||||
if (pdata->init_ioports)
|
||||
pdata->init_ioports(pdata);
|
||||
|
||||
ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpm_uart_drv_remove(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
|
||||
cpm_uart_id2nr(pdata->fs_no));
|
||||
|
||||
uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver cpm_smc_uart_driver = {
|
||||
.name = "fsl-cpm-smc:uart",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = cpm_uart_drv_probe,
|
||||
.remove = cpm_uart_drv_remove,
|
||||
};
|
||||
|
||||
static struct device_driver cpm_scc_uart_driver = {
|
||||
.name = "fsl-cpm-scc:uart",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = cpm_uart_drv_probe,
|
||||
.remove = cpm_uart_drv_remove,
|
||||
};
|
||||
|
||||
/*
|
||||
This is supposed to match uart devices on platform bus,
|
||||
*/
|
||||
static int match_is_uart (struct device* dev, void* data)
|
||||
{
|
||||
struct platform_device* pdev = container_of(dev, struct platform_device, dev);
|
||||
int ret = 0;
|
||||
/* this was setfunc as uart */
|
||||
if(strstr(pdev->name,":uart")) {
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int cpm_uart_init(void) {
|
||||
|
||||
int ret;
|
||||
int i;
|
||||
struct device *dev;
|
||||
printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");
|
||||
|
||||
/* lookup the bus for uart devices */
|
||||
dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);
|
||||
|
||||
/* There are devices on the bus - all should be OK */
|
||||
if (dev) {
|
||||
cpm_uart_count();
|
||||
cpm_reg.nr = cpm_uart_nr;
|
||||
|
||||
if (!(ret = uart_register_driver(&cpm_reg))) {
|
||||
if ((ret = driver_register(&cpm_smc_uart_driver))) {
|
||||
uart_unregister_driver(&cpm_reg);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = driver_register(&cpm_scc_uart_driver))) {
|
||||
driver_unregister(&cpm_scc_uart_driver);
|
||||
uart_unregister_driver(&cpm_reg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No capable platform devices found - falling back to legacy mode */
|
||||
pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
|
||||
pr_info(
|
||||
"cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
|
||||
|
||||
/* Don't run this again, if the console driver did it already */
|
||||
if (cpm_uart_nr == 0)
|
||||
cpm_uart_init_portdesc();
|
||||
|
||||
cpm_reg.nr = cpm_uart_nr;
|
||||
ret = uart_register_driver(&cpm_reg);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < cpm_uart_nr; i++) {
|
||||
int con = cpm_uart_port_map[i];
|
||||
cpm_uart_ports[con].port.line = i;
|
||||
cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
|
||||
if (cpm_uart_ports[con].set_lineif)
|
||||
cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]);
|
||||
uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cpm_uart_exit(void)
|
||||
{
|
||||
driver_unregister(&cpm_scc_uart_driver);
|
||||
driver_unregister(&cpm_smc_uart_driver);
|
||||
uart_unregister_driver(&cpm_reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
module_init(cpm_uart_init);
|
||||
module_exit(cpm_uart_exit);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* Copyright (C) 2004 Freescale Semiconductor, Inc.
|
||||
* (C) 2004 Intracom, S.A.
|
||||
* (C) 2006 MontaVista Software, Inc.
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -51,7 +51,6 @@
|
|||
|
||||
/**************************************************************/
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
|
||||
{
|
||||
cpm_command(port->command, cmd);
|
||||
|
|
@ -68,75 +67,6 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
|
|||
iounmap(pram);
|
||||
}
|
||||
|
||||
#else
|
||||
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
|
||||
{
|
||||
ushort val;
|
||||
int line = port - cpm_uart_ports;
|
||||
volatile cpm8xx_t *cp = cpmp;
|
||||
|
||||
switch (line) {
|
||||
case UART_SMC1:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SMC2:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC1:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC2:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC3:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC4:
|
||||
val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
cp->cp_cpcr = val;
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) ;
|
||||
}
|
||||
|
||||
void smc1_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
pinfo->brg = 1;
|
||||
}
|
||||
|
||||
void smc2_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
pinfo->brg = 2;
|
||||
}
|
||||
|
||||
void scc1_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
/* XXX SCC1: insert port configuration here */
|
||||
pinfo->brg = 1;
|
||||
}
|
||||
|
||||
void scc2_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
/* XXX SCC2: insert port configuration here */
|
||||
pinfo->brg = 2;
|
||||
}
|
||||
|
||||
void scc3_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
/* XXX SCC3: insert port configuration here */
|
||||
pinfo->brg = 3;
|
||||
}
|
||||
|
||||
void scc4_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
/* XXX SCC4: insert port configuration here */
|
||||
pinfo->brg = 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate DP-Ram and memory buffers. We need to allocate a transmit and
|
||||
* receive buffer descriptors from dual port ram, and a character
|
||||
|
|
@ -205,101 +135,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
|
|||
|
||||
cpm_dpfree(pinfo->dp_addr);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
/* Setup any dynamic params in the uart desc */
|
||||
int cpm_uart_init_portdesc(void)
|
||||
{
|
||||
pr_debug("CPM uart[-]:init portdesc\n");
|
||||
|
||||
cpm_uart_nr = 0;
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC1
|
||||
cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0];
|
||||
/*
|
||||
* Is SMC1 being relocated?
|
||||
*/
|
||||
# ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
|
||||
cpm_uart_ports[UART_SMC1].smcup =
|
||||
(smc_uart_t *) & cpmp->cp_dparam[0x3C0];
|
||||
# else
|
||||
cpm_uart_ports[UART_SMC1].smcup =
|
||||
(smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC1];
|
||||
# endif
|
||||
cpm_uart_ports[UART_SMC1].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_smc[0];
|
||||
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
|
||||
cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC2
|
||||
cpm_uart_ports[UART_SMC2].smcp = &cpmp->cp_smc[1];
|
||||
cpm_uart_ports[UART_SMC2].smcup =
|
||||
(smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC2];
|
||||
cpm_uart_ports[UART_SMC2].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_smc[1];
|
||||
cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
|
||||
cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC1
|
||||
cpm_uart_ports[UART_SCC1].sccp = &cpmp->cp_scc[0];
|
||||
cpm_uart_ports[UART_SCC1].sccup =
|
||||
(scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC1];
|
||||
cpm_uart_ports[UART_SCC1].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_scc[0];
|
||||
cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC2
|
||||
cpm_uart_ports[UART_SCC2].sccp = &cpmp->cp_scc[1];
|
||||
cpm_uart_ports[UART_SCC2].sccup =
|
||||
(scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC2];
|
||||
cpm_uart_ports[UART_SCC2].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_scc[1];
|
||||
cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC3
|
||||
cpm_uart_ports[UART_SCC3].sccp = &cpmp->cp_scc[2];
|
||||
cpm_uart_ports[UART_SCC3].sccup =
|
||||
(scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC3];
|
||||
cpm_uart_ports[UART_SCC3].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_scc[2];
|
||||
cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC4
|
||||
cpm_uart_ports[UART_SCC4].sccp = &cpmp->cp_scc[3];
|
||||
cpm_uart_ports[UART_SCC4].sccup =
|
||||
(scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC4];
|
||||
cpm_uart_ports[UART_SCC4].port.mapbase =
|
||||
(unsigned long)&cpmp->cp_scc[3];
|
||||
cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports
|
||||
*
|
||||
*
|
||||
* definitions for cpm1
|
||||
*
|
||||
*/
|
||||
|
|
@ -12,16 +12,6 @@
|
|||
|
||||
#include <asm/cpm1.h>
|
||||
|
||||
/* defines for IRQs */
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
#define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1)
|
||||
#define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2)
|
||||
#define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1)
|
||||
#define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2)
|
||||
#define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3)
|
||||
#define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4)
|
||||
#endif
|
||||
|
||||
static inline void cpm_set_brg(int brg, int baud)
|
||||
{
|
||||
cpm_setbrg(brg, baud);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
*
|
||||
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
|
||||
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2004 Freescale Semiconductor, Inc.
|
||||
* (C) 2004 Intracom, S.A.
|
||||
* (C) 2006 MontaVista Software, Inc.
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -41,9 +41,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/fs_pd.h>
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
#include <asm/prom.h>
|
||||
#endif
|
||||
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -52,7 +50,6 @@
|
|||
|
||||
/**************************************************************/
|
||||
|
||||
#ifdef CONFIG_PPC_CPM_NEW_BINDING
|
||||
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
|
||||
{
|
||||
cpm_command(port->command, cmd);
|
||||
|
|
@ -106,174 +103,8 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
|
|||
iounmap(pram);
|
||||
}
|
||||
|
||||
#else
|
||||
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
|
||||
{
|
||||
ulong val;
|
||||
int line = port - cpm_uart_ports;
|
||||
volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
|
||||
|
||||
|
||||
switch (line) {
|
||||
case UART_SMC1:
|
||||
val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SMC2:
|
||||
val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC1:
|
||||
val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC2:
|
||||
val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC3:
|
||||
val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
case UART_SCC4:
|
||||
val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0,
|
||||
cmd) | CPM_CR_FLG;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
cp->cp_cpcr = val;
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) ;
|
||||
|
||||
cpm2_unmap(cp);
|
||||
}
|
||||
|
||||
void smc1_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
|
||||
/* SMC1 is only on port D */
|
||||
io->iop_ppard |= 0x00c00000;
|
||||
io->iop_pdird |= 0x00400000;
|
||||
io->iop_pdird &= ~0x00800000;
|
||||
io->iop_psord &= ~0x00c00000;
|
||||
|
||||
/* Wire BRG1 to SMC1 */
|
||||
cpmux->cmx_smr &= 0x0f;
|
||||
pinfo->brg = 1;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
|
||||
void smc2_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
|
||||
/* SMC2 is only on port A */
|
||||
io->iop_ppara |= 0x00c00000;
|
||||
io->iop_pdira |= 0x00400000;
|
||||
io->iop_pdira &= ~0x00800000;
|
||||
io->iop_psora &= ~0x00c00000;
|
||||
|
||||
/* Wire BRG2 to SMC2 */
|
||||
cpmux->cmx_smr &= 0xf0;
|
||||
pinfo->brg = 2;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
|
||||
void scc1_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
|
||||
/* Use Port D for SCC1 instead of other functions. */
|
||||
io->iop_ppard |= 0x00000003;
|
||||
io->iop_psord &= ~0x00000001; /* Rx */
|
||||
io->iop_psord |= 0x00000002; /* Tx */
|
||||
io->iop_pdird &= ~0x00000001; /* Rx */
|
||||
io->iop_pdird |= 0x00000002; /* Tx */
|
||||
|
||||
/* Wire BRG1 to SCC1 */
|
||||
cpmux->cmx_scr &= 0x00ffffff;
|
||||
cpmux->cmx_scr |= 0x00000000;
|
||||
pinfo->brg = 1;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
|
||||
void scc2_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
/*
|
||||
* STx GP3 uses the SCC2 secondary option pin assignment
|
||||
* which this driver doesn't account for in the static
|
||||
* pin assignments. This kind of board specific info
|
||||
* really has to get out of the driver so boards can
|
||||
* be supported in a sane fashion.
|
||||
*/
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
#ifndef CONFIG_STX_GP3
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
|
||||
io->iop_pparb |= 0x008b0000;
|
||||
io->iop_pdirb |= 0x00880000;
|
||||
io->iop_psorb |= 0x00880000;
|
||||
io->iop_pdirb &= ~0x00030000;
|
||||
io->iop_psorb &= ~0x00030000;
|
||||
#endif
|
||||
cpmux->cmx_scr &= 0xff00ffff;
|
||||
cpmux->cmx_scr |= 0x00090000;
|
||||
pinfo->brg = 2;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
|
||||
void scc3_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
|
||||
io->iop_pparb |= 0x008b0000;
|
||||
io->iop_pdirb |= 0x00880000;
|
||||
io->iop_psorb |= 0x00880000;
|
||||
io->iop_pdirb &= ~0x00030000;
|
||||
io->iop_psorb &= ~0x00030000;
|
||||
cpmux->cmx_scr &= 0xffff00ff;
|
||||
cpmux->cmx_scr |= 0x00001200;
|
||||
pinfo->brg = 3;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
|
||||
void scc4_lineif(struct uart_cpm_port *pinfo)
|
||||
{
|
||||
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
|
||||
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
|
||||
|
||||
io->iop_ppard |= 0x00000600;
|
||||
io->iop_psord &= ~0x00000600; /* Tx/Rx */
|
||||
io->iop_pdird &= ~0x00000200; /* Rx */
|
||||
io->iop_pdird |= 0x00000400; /* Tx */
|
||||
|
||||
cpmux->cmx_scr &= 0xffffff00;
|
||||
cpmux->cmx_scr |= 0x0000001b;
|
||||
pinfo->brg = 4;
|
||||
|
||||
cpm2_unmap(cpmux);
|
||||
cpm2_unmap(io);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate DP-Ram and memory buffers. We need to allocate a transmit and
|
||||
* Allocate DP-Ram and memory buffers. We need to allocate a transmit and
|
||||
* receive buffer descriptors from dual port ram, and a character
|
||||
* buffer area from host mem. If we are allocating for the console we need
|
||||
* to do it from bootmem
|
||||
|
|
@ -340,111 +171,3 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
|
|||
|
||||
cpm_dpfree(pinfo->dp_addr);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
/* Setup any dynamic params in the uart desc */
|
||||
int cpm_uart_init_portdesc(void)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
|
||||
u16 *addr;
|
||||
#endif
|
||||
pr_debug("CPM uart[-]:init portdesc\n");
|
||||
|
||||
cpm_uart_nr = 0;
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC1
|
||||
cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
|
||||
cpm_uart_ports[UART_SMC1].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SMC1].smcp;
|
||||
|
||||
cpm_uart_ports[UART_SMC1].smcup =
|
||||
(smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
|
||||
addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
|
||||
*addr = PROFF_SMC1;
|
||||
cpm2_unmap(addr);
|
||||
|
||||
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
|
||||
cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SMC2
|
||||
cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
|
||||
cpm_uart_ports[UART_SMC2].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SMC2].smcp;
|
||||
|
||||
cpm_uart_ports[UART_SMC2].smcup =
|
||||
(smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
|
||||
addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
|
||||
*addr = PROFF_SMC2;
|
||||
cpm2_unmap(addr);
|
||||
|
||||
cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
|
||||
cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC1
|
||||
cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
|
||||
cpm_uart_ports[UART_SCC1].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SCC1].sccp;
|
||||
cpm_uart_ports[UART_SCC1].sccup =
|
||||
(scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
|
||||
|
||||
cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC2
|
||||
cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
|
||||
cpm_uart_ports[UART_SCC2].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SCC2].sccp;
|
||||
cpm_uart_ports[UART_SCC2].sccup =
|
||||
(scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
|
||||
|
||||
cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC3
|
||||
cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
|
||||
cpm_uart_ports[UART_SCC3].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SCC3].sccp;
|
||||
cpm_uart_ports[UART_SCC3].sccup =
|
||||
(scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
|
||||
|
||||
cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_CPM_SCC4
|
||||
cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
|
||||
cpm_uart_ports[UART_SCC4].port.mapbase =
|
||||
(unsigned long)cpm_uart_ports[UART_SCC4].sccp;
|
||||
cpm_uart_ports[UART_SCC4].sccup =
|
||||
(scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
|
||||
|
||||
cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
|
||||
~(UART_SCCM_TX | UART_SCCM_RX);
|
||||
cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
|
||||
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports
|
||||
*
|
||||
*
|
||||
* definitions for cpm2
|
||||
*
|
||||
*/
|
||||
|
|
@ -12,16 +12,6 @@
|
|||
|
||||
#include <asm/cpm2.h>
|
||||
|
||||
/* defines for IRQs */
|
||||
#ifndef CONFIG_PPC_CPM_NEW_BINDING
|
||||
#define SMC1_IRQ SIU_INT_SMC1
|
||||
#define SMC2_IRQ SIU_INT_SMC2
|
||||
#define SCC1_IRQ SIU_INT_SCC1
|
||||
#define SCC2_IRQ SIU_INT_SCC2
|
||||
#define SCC3_IRQ SIU_INT_SCC3
|
||||
#define SCC4_IRQ SIU_INT_SCC4
|
||||
#endif
|
||||
|
||||
static inline void cpm_set_brg(int brg, int baud)
|
||||
{
|
||||
cpm_setbrg(brg, baud);
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ unsigned long r_alt_ser_baudrate_shadow = 0;
|
|||
|
||||
static struct e100_serial rs_table[] = {
|
||||
{ .baud = DEF_BAUD,
|
||||
.port = (unsigned char *)R_SERIAL0_CTRL,
|
||||
.ioport = (unsigned char *)R_SERIAL0_CTRL,
|
||||
.irq = 1U << 12, /* uses DMA 6 and 7 */
|
||||
.oclrintradr = R_DMA_CH6_CLR_INTR,
|
||||
.ofirstadr = R_DMA_CH6_FIRST,
|
||||
|
|
@ -288,7 +288,7 @@ static struct e100_serial rs_table[] = {
|
|||
}, /* ttyS0 */
|
||||
#ifndef CONFIG_SVINTO_SIM
|
||||
{ .baud = DEF_BAUD,
|
||||
.port = (unsigned char *)R_SERIAL1_CTRL,
|
||||
.ioport = (unsigned char *)R_SERIAL1_CTRL,
|
||||
.irq = 1U << 16, /* uses DMA 8 and 9 */
|
||||
.oclrintradr = R_DMA_CH8_CLR_INTR,
|
||||
.ofirstadr = R_DMA_CH8_FIRST,
|
||||
|
|
@ -344,7 +344,7 @@ static struct e100_serial rs_table[] = {
|
|||
}, /* ttyS1 */
|
||||
|
||||
{ .baud = DEF_BAUD,
|
||||
.port = (unsigned char *)R_SERIAL2_CTRL,
|
||||
.ioport = (unsigned char *)R_SERIAL2_CTRL,
|
||||
.irq = 1U << 4, /* uses DMA 2 and 3 */
|
||||
.oclrintradr = R_DMA_CH2_CLR_INTR,
|
||||
.ofirstadr = R_DMA_CH2_FIRST,
|
||||
|
|
@ -398,7 +398,7 @@ static struct e100_serial rs_table[] = {
|
|||
}, /* ttyS2 */
|
||||
|
||||
{ .baud = DEF_BAUD,
|
||||
.port = (unsigned char *)R_SERIAL3_CTRL,
|
||||
.ioport = (unsigned char *)R_SERIAL3_CTRL,
|
||||
.irq = 1U << 8, /* uses DMA 4 and 5 */
|
||||
.oclrintradr = R_DMA_CH4_CLR_INTR,
|
||||
.ofirstadr = R_DMA_CH4_FIRST,
|
||||
|
|
@ -939,7 +939,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
|
|||
/* Output */
|
||||
#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK)
|
||||
/* Input */
|
||||
#define E100_CTS_GET(info) ((info)->port[REG_STATUS] & E100_CTS_MASK)
|
||||
#define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK)
|
||||
|
||||
/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */
|
||||
/* Is an output */
|
||||
|
|
@ -968,7 +968,7 @@ static DEFINE_MUTEX(tmp_buf_mutex);
|
|||
/* Calculate the chartime depending on baudrate, numbor of bits etc. */
|
||||
static void update_char_time(struct e100_serial * info)
|
||||
{
|
||||
tcflag_t cflags = info->tty->termios->c_cflag;
|
||||
tcflag_t cflags = info->port.tty->termios->c_cflag;
|
||||
int bits;
|
||||
|
||||
/* calc. number of bits / data byte */
|
||||
|
|
@ -1092,7 +1092,7 @@ e100_rts(struct e100_serial *info, int set)
|
|||
local_irq_save(flags);
|
||||
info->rx_ctrl &= ~E100_RTS_MASK;
|
||||
info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */
|
||||
info->port[REG_REC_CTRL] = info->rx_ctrl;
|
||||
info->ioport[REG_REC_CTRL] = info->rx_ctrl;
|
||||
local_irq_restore(flags);
|
||||
#ifdef SERIAL_DEBUG_IO
|
||||
printk("ser%i rts %i\n", info->line, set);
|
||||
|
|
@ -1142,7 +1142,7 @@ e100_disable_rx(struct e100_serial *info)
|
|||
{
|
||||
#ifndef CONFIG_SVINTO_SIM
|
||||
/* disable the receiver */
|
||||
info->port[REG_REC_CTRL] =
|
||||
info->ioport[REG_REC_CTRL] =
|
||||
(info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1152,7 +1152,7 @@ e100_enable_rx(struct e100_serial *info)
|
|||
{
|
||||
#ifndef CONFIG_SVINTO_SIM
|
||||
/* enable the receiver */
|
||||
info->port[REG_REC_CTRL] =
|
||||
info->ioport[REG_REC_CTRL] =
|
||||
(info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1483,13 +1483,14 @@ rs_stop(struct tty_struct *tty)
|
|||
CIRC_CNT(info->xmit.head,
|
||||
info->xmit.tail,SERIAL_XMIT_SIZE)));
|
||||
|
||||
xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
|
||||
xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char,
|
||||
STOP_CHAR(info->port.tty));
|
||||
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
|
||||
if (tty->termios->c_iflag & IXON ) {
|
||||
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
|
||||
}
|
||||
|
||||
*((unsigned long *)&info->port[REG_XOFF]) = xoff;
|
||||
*((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
|
|
@ -1512,7 +1513,7 @@ rs_start(struct tty_struct *tty)
|
|||
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
|
||||
}
|
||||
|
||||
*((unsigned long *)&info->port[REG_XOFF]) = xoff;
|
||||
*((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
|
||||
if (!info->uses_dma_out &&
|
||||
info->xmit.head != info->xmit.tail && info->xmit.buf)
|
||||
e100_enable_serial_tx_ready_irq(info);
|
||||
|
|
@ -1772,7 +1773,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl
|
|||
|
||||
info->icount.rx++;
|
||||
} else {
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
tty_insert_flip_char(tty, data, flag);
|
||||
info->icount.rx++;
|
||||
}
|
||||
|
|
@ -1838,7 +1839,7 @@ static unsigned int handle_all_descr_data(struct e100_serial *info)
|
|||
descr->status = 0;
|
||||
|
||||
DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl);
|
||||
if (info->tty->stopped) {
|
||||
if (info->port.tty->stopped) {
|
||||
unsigned char *buf = phys_to_virt(descr->buf);
|
||||
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]);
|
||||
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]);
|
||||
|
|
@ -1872,7 +1873,7 @@ static void receive_chars_dma(struct e100_serial *info)
|
|||
IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
|
||||
IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty) /* Something wrong... */
|
||||
return;
|
||||
|
||||
|
|
@ -1887,7 +1888,7 @@ static void receive_chars_dma(struct e100_serial *info)
|
|||
handle_all_descr_data(info);
|
||||
|
||||
/* Read the status register to detect errors */
|
||||
rstat = info->port[REG_STATUS];
|
||||
rstat = info->ioport[REG_STATUS];
|
||||
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
|
||||
DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat));
|
||||
}
|
||||
|
|
@ -1896,7 +1897,7 @@ static void receive_chars_dma(struct e100_serial *info)
|
|||
/* If we got an error, we must reset it by reading the
|
||||
* data_in field
|
||||
*/
|
||||
unsigned char data = info->port[REG_DATA];
|
||||
unsigned char data = info->ioport[REG_DATA];
|
||||
|
||||
PROCSTAT(ser_stat[info->line].errors_cnt++);
|
||||
DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n",
|
||||
|
|
@ -2076,7 +2077,7 @@ static int force_eop_if_needed(struct e100_serial *info)
|
|||
/* We check data_avail bit to determine if data has
|
||||
* arrived since last time
|
||||
*/
|
||||
unsigned char rstat = info->port[REG_STATUS];
|
||||
unsigned char rstat = info->ioport[REG_STATUS];
|
||||
|
||||
/* error or datavail? */
|
||||
if (rstat & SER_ERROR_MASK) {
|
||||
|
|
@ -2095,7 +2096,7 @@ static int force_eop_if_needed(struct e100_serial *info)
|
|||
TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n",
|
||||
rstat | (info->line << 8)));
|
||||
/* Read data to clear status flags */
|
||||
(void)info->port[REG_DATA];
|
||||
(void)info->ioport[REG_DATA];
|
||||
|
||||
info->forced_eop = 0;
|
||||
START_FLUSH_FAST_TIMER(info, "magic");
|
||||
|
|
@ -2122,7 +2123,7 @@ static void flush_to_flip_buffer(struct e100_serial *info)
|
|||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
|
||||
if (!tty) {
|
||||
local_irq_restore(flags);
|
||||
|
|
@ -2287,7 +2288,7 @@ static
|
|||
struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
|
||||
{
|
||||
unsigned long data_read;
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
|
||||
if (!tty) {
|
||||
printk("!NO TTY!\n");
|
||||
|
|
@ -2295,7 +2296,7 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
|
|||
}
|
||||
|
||||
/* Read data and status at the same time */
|
||||
data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
|
||||
data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
|
||||
more_data:
|
||||
if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) {
|
||||
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
|
||||
|
|
@ -2350,7 +2351,7 @@ more_data:
|
|||
data_in, data_read);
|
||||
char flag = TTY_NORMAL;
|
||||
if (info->errorcode == ERRCODE_INSERT_BREAK) {
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
tty_insert_flip_char(tty, 0, flag);
|
||||
info->icount.rx++;
|
||||
}
|
||||
|
|
@ -2390,13 +2391,13 @@ more_data:
|
|||
|
||||
|
||||
info->icount.rx++;
|
||||
data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
|
||||
data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
|
||||
if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
|
||||
DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read));
|
||||
goto more_data;
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(info->tty);
|
||||
tty_flip_buffer_push(info->port.tty);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -2412,7 +2413,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
|
|||
return handle_ser_rx_interrupt_no_dma(info);
|
||||
}
|
||||
/* DMA is used */
|
||||
rstat = info->port[REG_STATUS];
|
||||
rstat = info->ioport[REG_STATUS];
|
||||
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
|
||||
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
|
||||
}
|
||||
|
|
@ -2425,7 +2426,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
|
|||
/* If we got an error, we must reset it by reading the
|
||||
* data_in field
|
||||
*/
|
||||
data = info->port[REG_DATA];
|
||||
data = info->ioport[REG_DATA];
|
||||
DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data));
|
||||
DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat));
|
||||
if (!data && (rstat & SER_FRAMING_ERR_MASK)) {
|
||||
|
|
@ -2527,10 +2528,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
|
|||
unsigned char rstat;
|
||||
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
|
||||
local_irq_save(flags);
|
||||
rstat = info->port[REG_STATUS];
|
||||
rstat = info->ioport[REG_STATUS];
|
||||
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
|
||||
|
||||
info->port[REG_TR_DATA] = info->x_char;
|
||||
info->ioport[REG_TR_DATA] = info->x_char;
|
||||
info->icount.tx++;
|
||||
info->x_char = 0;
|
||||
/* We must enable since it is disabled in ser_interrupt */
|
||||
|
|
@ -2544,11 +2545,11 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
|
|||
/* We only use normal tx interrupt when sending x_char */
|
||||
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
|
||||
local_irq_save(flags);
|
||||
rstat = info->port[REG_STATUS];
|
||||
rstat = info->ioport[REG_STATUS];
|
||||
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
|
||||
e100_disable_serial_tx_ready_irq(info);
|
||||
if (info->tty->stopped)
|
||||
rs_stop(info->tty);
|
||||
if (info->port.tty->stopped)
|
||||
rs_stop(info->port.tty);
|
||||
/* Enable the DMA channel and tell it to continue */
|
||||
e100_enable_txdma_channel(info);
|
||||
/* Wait 12 cycles before doing the DMA command */
|
||||
|
|
@ -2561,9 +2562,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
|
|||
}
|
||||
/* Normal char-by-char interrupt */
|
||||
if (info->xmit.head == info->xmit.tail
|
||||
|| info->tty->stopped
|
||||
|| info->tty->hw_stopped) {
|
||||
DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped));
|
||||
|| info->port.tty->stopped
|
||||
|| info->port.tty->hw_stopped) {
|
||||
DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n",
|
||||
info->port.tty->stopped));
|
||||
e100_disable_serial_tx_ready_irq(info);
|
||||
info->tr_running = 0;
|
||||
return;
|
||||
|
|
@ -2571,7 +2573,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
|
|||
DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
|
||||
/* Send a byte, rs485 timing is critical so turn of ints */
|
||||
local_irq_save(flags);
|
||||
info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
|
||||
info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
|
||||
info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
|
||||
info->icount.tx++;
|
||||
if (info->xmit.head == info->xmit.tail) {
|
||||
|
|
@ -2725,7 +2727,7 @@ do_softint(struct work_struct *work)
|
|||
|
||||
info = container_of(work, struct e100_serial, work);
|
||||
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
|
|
@ -2767,8 +2769,8 @@ startup(struct e100_serial * info)
|
|||
/* Bits and pieces collected from below. Better to have them
|
||||
in one ifdef:ed clause than to mix in a lot of ifdefs,
|
||||
right? */
|
||||
if (info->tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->xmit.head = info->xmit.tail = 0;
|
||||
info->first_recv_buffer = info->last_recv_buffer = NULL;
|
||||
|
|
@ -2825,8 +2827,8 @@ startup(struct e100_serial * info)
|
|||
e100_disable_txdma_channel(info);
|
||||
}
|
||||
|
||||
if (info->tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->xmit.head = info->xmit.tail = 0;
|
||||
info->first_recv_buffer = info->last_recv_buffer = NULL;
|
||||
|
|
@ -2846,7 +2848,7 @@ startup(struct e100_serial * info)
|
|||
|
||||
/* dummy read to reset any serial errors */
|
||||
|
||||
(void)info->port[REG_DATA];
|
||||
(void)info->ioport[REG_DATA];
|
||||
|
||||
/* enable the interrupts */
|
||||
if (info->uses_dma_out)
|
||||
|
|
@ -2895,7 +2897,7 @@ shutdown(struct e100_serial * info)
|
|||
/* shut down the transmitter and receiver */
|
||||
DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line));
|
||||
e100_disable_rx(info);
|
||||
info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
|
||||
info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
|
||||
|
||||
/* disable interrupts, reset dma channels */
|
||||
if (info->uses_dma_in) {
|
||||
|
|
@ -2940,14 +2942,14 @@ shutdown(struct e100_serial * info)
|
|||
descr[i].buf = 0;
|
||||
}
|
||||
|
||||
if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
|
||||
if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
|
||||
/* hang up DTR and RTS if HUPCL is enabled */
|
||||
e100_dtr(info, 0);
|
||||
e100_rts(info, 0); /* could check CRTSCTS before doing this */
|
||||
}
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->flags &= ~ASYNC_INITIALIZED;
|
||||
local_irq_restore(flags);
|
||||
|
|
@ -2964,12 +2966,12 @@ change_speed(struct e100_serial *info)
|
|||
unsigned long flags;
|
||||
/* first some safety checks */
|
||||
|
||||
if (!info->tty || !info->tty->termios)
|
||||
if (!info->port.tty || !info->port.tty->termios)
|
||||
return;
|
||||
if (!info->port)
|
||||
if (!info->ioport)
|
||||
return;
|
||||
|
||||
cflag = info->tty->termios->c_cflag;
|
||||
cflag = info->port.tty->termios->c_cflag;
|
||||
|
||||
/* possibly, the tx/rx should be disabled first to do this safely */
|
||||
|
||||
|
|
@ -3035,7 +3037,7 @@ change_speed(struct e100_serial *info)
|
|||
|
||||
info->baud = cflag_to_baud(cflag);
|
||||
#ifndef CONFIG_SVINTO_SIM
|
||||
info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
|
||||
info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag);
|
||||
#endif /* CONFIG_SVINTO_SIM */
|
||||
}
|
||||
|
||||
|
|
@ -3095,16 +3097,17 @@ change_speed(struct e100_serial *info)
|
|||
|
||||
/* actually write the control regs to the hardware */
|
||||
|
||||
info->port[REG_TR_CTRL] = info->tx_ctrl;
|
||||
info->port[REG_REC_CTRL] = info->rx_ctrl;
|
||||
xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
|
||||
info->ioport[REG_TR_CTRL] = info->tx_ctrl;
|
||||
info->ioport[REG_REC_CTRL] = info->rx_ctrl;
|
||||
xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
|
||||
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
|
||||
if (info->tty->termios->c_iflag & IXON ) {
|
||||
DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty)));
|
||||
if (info->port.tty->termios->c_iflag & IXON ) {
|
||||
DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n",
|
||||
STOP_CHAR(info->port.tty)));
|
||||
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
|
||||
}
|
||||
|
||||
*((unsigned long *)&info->port[REG_XOFF]) = xoff;
|
||||
*((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
|
||||
local_irq_restore(flags);
|
||||
#endif /* !CONFIG_SVINTO_SIM */
|
||||
|
||||
|
|
@ -3153,7 +3156,7 @@ static int rs_raw_write(struct tty_struct *tty,
|
|||
#ifdef SERIAL_DEBUG_DATA
|
||||
if (info->line == SERIAL_DEBUG_LINE)
|
||||
printk("rs_raw_write (%d), status %d\n",
|
||||
count, info->port[REG_STATUS]);
|
||||
count, info->ioport[REG_STATUS]);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SVINTO_SIM
|
||||
|
|
@ -3424,7 +3427,7 @@ get_serial_info(struct e100_serial * info,
|
|||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.type = info->type;
|
||||
tmp.line = info->line;
|
||||
tmp.port = (int)info->port;
|
||||
tmp.port = (int)info->ioport;
|
||||
tmp.irq = info->irq;
|
||||
tmp.flags = info->flags;
|
||||
tmp.baud_base = info->baud_base;
|
||||
|
|
@ -3475,7 +3478,7 @@ set_serial_info(struct e100_serial *info,
|
|||
info->type = new_serial.type;
|
||||
info->close_delay = new_serial.close_delay;
|
||||
info->closing_wait = new_serial.closing_wait;
|
||||
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
|
||||
check_and_exit:
|
||||
if (info->flags & ASYNC_INITIALIZED) {
|
||||
|
|
@ -3554,14 +3557,14 @@ char *get_control_state_str(int MLines, char *s)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
static int
|
||||
rs_break(struct tty_struct *tty, int break_state)
|
||||
{
|
||||
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (!info->port)
|
||||
return;
|
||||
if (!info->ioport)
|
||||
return -EIO;
|
||||
|
||||
local_irq_save(flags);
|
||||
if (break_state == -1) {
|
||||
|
|
@ -3572,8 +3575,9 @@ rs_break(struct tty_struct *tty, int break_state)
|
|||
/* Set bit 7 (txd) and 6 (tr_enable) */
|
||||
info->tx_ctrl |= (0x80 | 0x40);
|
||||
}
|
||||
info->port[REG_TR_CTRL] = info->tx_ctrl;
|
||||
info->ioport[REG_TR_CTRL] = info->tx_ctrl;
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -3811,7 +3815,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
|
|||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
if (info->close_delay)
|
||||
schedule_timeout_interruptible(info->close_delay);
|
||||
|
|
@ -3915,7 +3919,7 @@ rs_hangup(struct tty_struct *tty)
|
|||
info->event = 0;
|
||||
info->count = 0;
|
||||
info->flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
wake_up_interruptible(&info->open_wait);
|
||||
}
|
||||
|
||||
|
|
@ -4077,9 +4081,9 @@ rs_open(struct tty_struct *tty, struct file * filp)
|
|||
|
||||
info->count++;
|
||||
tty->driver_data = info;
|
||||
info->tty = tty;
|
||||
info->port.tty = tty;
|
||||
|
||||
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
|
||||
if (!tmp_buf) {
|
||||
page = get_zeroed_page(GFP_KERNEL);
|
||||
|
|
@ -4228,9 +4232,9 @@ static int line_info(char *buf, struct e100_serial *info)
|
|||
unsigned long tmp;
|
||||
|
||||
ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d",
|
||||
info->line, (unsigned long)info->port, info->irq);
|
||||
info->line, (unsigned long)info->ioport, info->irq);
|
||||
|
||||
if (!info->port || (info->type == PORT_UNKNOWN)) {
|
||||
if (!info->ioport || (info->type == PORT_UNKNOWN)) {
|
||||
ret += sprintf(buf+ret, "\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -4267,18 +4271,18 @@ static int line_info(char *buf, struct e100_serial *info)
|
|||
(unsigned long)info->max_recv_cnt);
|
||||
|
||||
#if 1
|
||||
if (info->tty) {
|
||||
if (info->port.tty) {
|
||||
|
||||
if (info->tty->stopped)
|
||||
if (info->port.tty->stopped)
|
||||
ret += sprintf(buf+ret, " stopped:%i",
|
||||
(int)info->tty->stopped);
|
||||
if (info->tty->hw_stopped)
|
||||
(int)info->port.tty->stopped);
|
||||
if (info->port.tty->hw_stopped)
|
||||
ret += sprintf(buf+ret, " hw_stopped:%i",
|
||||
(int)info->tty->hw_stopped);
|
||||
(int)info->port.tty->hw_stopped);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char rstat = info->port[REG_STATUS];
|
||||
unsigned char rstat = info->ioport[REG_STATUS];
|
||||
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) )
|
||||
ret += sprintf(buf+ret, " xoff_detect:1");
|
||||
}
|
||||
|
|
@ -4465,7 +4469,7 @@ rs_init(void)
|
|||
info->uses_dma_in = 0;
|
||||
info->uses_dma_out = 0;
|
||||
info->line = i;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
info->type = PORT_ETRAX;
|
||||
info->tr_running = 0;
|
||||
info->forced_eop = 0;
|
||||
|
|
@ -4499,7 +4503,7 @@ rs_init(void)
|
|||
|
||||
if (info->enabled) {
|
||||
printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
|
||||
serial_driver->name, info->line, (unsigned int)info->port);
|
||||
serial_driver->name, info->line, (unsigned int)info->ioport);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_ETRAX_FAST_TIMER
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ struct etrax_recv_buffer {
|
|||
};
|
||||
|
||||
struct e100_serial {
|
||||
struct tty_port port;
|
||||
int baud;
|
||||
volatile u8 *port; /* R_SERIALx_CTRL */
|
||||
volatile u8 *ioport; /* R_SERIALx_CTRL */
|
||||
u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */
|
||||
|
||||
/* Output registers */
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
|
|||
while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
|
||||
dport = &mux->dport[LINE(status)];
|
||||
uport = &dport->port;
|
||||
tty = uport->info->tty; /* point to the proper dev */
|
||||
tty = uport->info->port.tty; /* point to the proper dev */
|
||||
|
||||
ch = UCHAR(status); /* grab the char */
|
||||
flag = TTY_NORMAL;
|
||||
|
|
@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
|
|||
}
|
||||
for (i = 0; i < DZ_NB_PORT; i++)
|
||||
if (lines_rx[i])
|
||||
tty_flip_buffer_push(mux->dport[i].port.info->tty);
|
||||
tty_flip_buffer_push(mux->dport[i].port.info->port.tty);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -642,6 +642,26 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
|
|||
spin_unlock_irqrestore(&dport->port.lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hack alert!
|
||||
* Required solely so that the initial PROM-based console
|
||||
* works undisturbed in parallel with this one.
|
||||
*/
|
||||
static void dz_pm(struct uart_port *uport, unsigned int state,
|
||||
unsigned int oldstate)
|
||||
{
|
||||
struct dz_port *dport = to_dport(uport);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dport->port.lock, flags);
|
||||
if (state < 3)
|
||||
dz_start_tx(&dport->port);
|
||||
else
|
||||
dz_stop_tx(&dport->port);
|
||||
spin_unlock_irqrestore(&dport->port.lock, flags);
|
||||
}
|
||||
|
||||
|
||||
static const char *dz_type(struct uart_port *uport)
|
||||
{
|
||||
return "DZ";
|
||||
|
|
@ -738,6 +758,7 @@ static struct uart_ops dz_ops = {
|
|||
.startup = dz_startup,
|
||||
.shutdown = dz_shutdown,
|
||||
.set_termios = dz_set_termios,
|
||||
.pm = dz_pm,
|
||||
.type = dz_type,
|
||||
.release_port = dz_release_port,
|
||||
.request_port = dz_request_port,
|
||||
|
|
@ -861,7 +882,10 @@ static int __init dz_console_setup(struct console *co, char *options)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&dport->port.lock); /* For dz_pm(). */
|
||||
|
||||
dz_reset(dport);
|
||||
dz_pm(uport, 0, -1);
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
|
|
|||
|
|
@ -730,7 +730,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
|
|||
static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
|
||||
{
|
||||
short int count, rcv_buff;
|
||||
struct tty_struct *tty = icom_port->uart_port.info->tty;
|
||||
struct tty_struct *tty = icom_port->uart_port.info->port.tty;
|
||||
unsigned short int status;
|
||||
struct uart_icount *icount;
|
||||
unsigned long offset;
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/imx-uart.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/imx-uart.h>
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD0 0x0 /* Receiver Register */
|
||||
|
|
@ -372,7 +372,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
|
|||
{
|
||||
struct imx_port *sport = dev_id;
|
||||
unsigned int rx,flg,ignored = 0;
|
||||
struct tty_struct *tty = sport->port.info->tty;
|
||||
struct tty_struct *tty = sport->port.info->port.tty;
|
||||
unsigned long flags, temp;
|
||||
|
||||
spin_lock_irqsave(&sport->port.lock,flags);
|
||||
|
|
|
|||
|
|
@ -905,7 +905,7 @@ static void transmit_chars(struct uart_port *the_port)
|
|||
return;
|
||||
|
||||
info = the_port->info;
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
|
||||
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
|
||||
/* Nothing to do or hw stopped */
|
||||
|
|
@ -997,14 +997,14 @@ ioc3_change_speed(struct uart_port *the_port,
|
|||
|
||||
the_port->ignore_status_mask = N_ALL_INPUT;
|
||||
|
||||
info->tty->low_latency = 1;
|
||||
info->port.tty->low_latency = 1;
|
||||
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
|
||||
| N_FRAMING_ERROR);
|
||||
if (I_IGNBRK(info->tty)) {
|
||||
if (I_IGNBRK(info->port.tty)) {
|
||||
the_port->ignore_status_mask &= ~N_BREAK;
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
|
||||
}
|
||||
if (!(cflag & CREAD)) {
|
||||
|
|
@ -1399,14 +1399,14 @@ static int receive_chars(struct uart_port *the_port)
|
|||
/* Make sure all the pointers are "good" ones */
|
||||
if (!info)
|
||||
return 0;
|
||||
if (!info->tty)
|
||||
if (!info->port.tty)
|
||||
return 0;
|
||||
|
||||
if (!(port->ip_flags & INPUT_ENABLE))
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&the_port->lock, pflags);
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
|
||||
read_count = do_read(the_port, ch, MAX_CHARS);
|
||||
if (read_count > 0) {
|
||||
|
|
|
|||
|
|
@ -1635,7 +1635,7 @@ static void transmit_chars(struct uart_port *the_port)
|
|||
return;
|
||||
|
||||
info = the_port->info;
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
|
||||
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
|
||||
/* Nothing to do or hw stopped */
|
||||
|
|
@ -1738,14 +1738,14 @@ ioc4_change_speed(struct uart_port *the_port,
|
|||
|
||||
the_port->ignore_status_mask = N_ALL_INPUT;
|
||||
|
||||
info->tty->low_latency = 1;
|
||||
info->port.tty->low_latency = 1;
|
||||
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
|
||||
| N_FRAMING_ERROR);
|
||||
if (I_IGNBRK(info->tty)) {
|
||||
if (I_IGNBRK(info->port.tty)) {
|
||||
the_port->ignore_status_mask &= ~N_BREAK;
|
||||
if (I_IGNPAR(info->tty))
|
||||
if (I_IGNPAR(info->port.tty))
|
||||
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
|
||||
}
|
||||
if (!(cflag & CREAD)) {
|
||||
|
|
@ -1801,7 +1801,8 @@ static inline int ic4_startup_local(struct uart_port *the_port)
|
|||
ioc4_set_proto(port, the_port->mapbase);
|
||||
|
||||
/* set the speed of the serial port */
|
||||
ioc4_change_speed(the_port, info->tty->termios, (struct ktermios *)0);
|
||||
ioc4_change_speed(the_port, info->port.tty->termios,
|
||||
(struct ktermios *)0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2346,11 +2347,11 @@ static void receive_chars(struct uart_port *the_port)
|
|||
/* Make sure all the pointers are "good" ones */
|
||||
if (!info)
|
||||
return;
|
||||
if (!info->tty)
|
||||
if (!info->port.tty)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&the_port->lock, pflags);
|
||||
tty = info->tty;
|
||||
tty = info->port.tty;
|
||||
|
||||
request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
|
||||
|
||||
|
|
@ -2440,8 +2441,8 @@ static void ic4_shutdown(struct uart_port *the_port)
|
|||
|
||||
wake_up_interruptible(&info->delta_msr_wait);
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
spin_lock_irqsave(&the_port->lock, port_flags);
|
||||
set_notification(port, N_ALL, 0);
|
||||
|
|
|
|||
|
|
@ -257,8 +257,8 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up
|
|||
|
||||
tty = NULL;
|
||||
if (up->port.info != NULL &&
|
||||
up->port.info->tty != NULL)
|
||||
tty = up->port.info->tty;
|
||||
up->port.info->port.tty != NULL)
|
||||
tty = up->port.info->port.tty;
|
||||
|
||||
for (;;) {
|
||||
ch = readb(&channel->control);
|
||||
|
|
|
|||
|
|
@ -998,7 +998,7 @@ static void neo_param(struct jsm_channel *ch)
|
|||
{ 50, B50 },
|
||||
};
|
||||
|
||||
cflag = C_BAUD(ch->uart_port.info->tty);
|
||||
cflag = C_BAUD(ch->uart_port.info->port.tty);
|
||||
baud = 9600;
|
||||
for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
|
||||
if (baud_rates[i].cflag == cflag) {
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
|
|||
struct ktermios *termios;
|
||||
|
||||
spin_lock_irqsave(&port->lock, lock_flags);
|
||||
termios = port->info->tty->termios;
|
||||
termios = port->info->port.tty->termios;
|
||||
if (ch == termios->c_cc[VSTART])
|
||||
channel->ch_bd->bd_ops->send_start_character(channel);
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ static int jsm_tty_open(struct uart_port *port)
|
|||
channel->ch_cached_lsr = 0;
|
||||
channel->ch_stops_sent = 0;
|
||||
|
||||
termios = port->info->tty->termios;
|
||||
termios = port->info->port.tty->termios;
|
||||
channel->ch_c_cflag = termios->c_cflag;
|
||||
channel->ch_c_iflag = termios->c_iflag;
|
||||
channel->ch_c_oflag = termios->c_oflag;
|
||||
|
|
@ -272,7 +272,7 @@ static void jsm_tty_close(struct uart_port *port)
|
|||
jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
|
||||
|
||||
bd = channel->ch_bd;
|
||||
ts = channel->uart_port.info->tty->termios;
|
||||
ts = channel->uart_port.info->port.tty->termios;
|
||||
|
||||
channel->ch_flags &= ~(CH_STOPI);
|
||||
|
||||
|
|
@ -515,7 +515,7 @@ void jsm_input(struct jsm_channel *ch)
|
|||
if (!ch)
|
||||
return;
|
||||
|
||||
tp = ch->uart_port.info->tty;
|
||||
tp = ch->uart_port.info->port.tty;
|
||||
|
||||
bd = ch->ch_bd;
|
||||
if(!bd)
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
|
|||
|
||||
static void receive_chars(struct uart_sio_port *up, int *status)
|
||||
{
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned char ch;
|
||||
unsigned char flag;
|
||||
int max_count = 256;
|
||||
|
|
@ -1160,7 +1160,7 @@ static int __init m32r_sio_init(void)
|
|||
{
|
||||
int ret, i;
|
||||
|
||||
printk(KERN_INFO "Serial: M32R SIO driver $Revision: 1.11 $ ");
|
||||
printk(KERN_INFO "Serial: M32R SIO driver\n");
|
||||
|
||||
for (i = 0; i < NR_IRQS; i++)
|
||||
spin_lock_init(&irq_lists[i].lock);
|
||||
|
|
@ -1189,4 +1189,4 @@ EXPORT_SYMBOL(m32r_sio_suspend_port);
|
|||
EXPORT_SYMBOL(m32r_sio_resume_port);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Generic M32R SIO serial driver $Revision: 1.11 $");
|
||||
MODULE_DESCRIPTION("Generic M32R SIO serial driver");
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
|
|||
uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(port->info->tty);
|
||||
tty_flip_buffer_push(port->info->port.tty);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ static void mcfrs_start(struct tty_struct *tty)
|
|||
static inline void receive_chars(struct mcf_serial *info)
|
||||
{
|
||||
volatile unsigned char *uartp;
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
unsigned char status, ch, flag;
|
||||
|
||||
if (!tty)
|
||||
|
|
@ -382,7 +382,7 @@ static inline void transmit_chars(struct mcf_serial *info)
|
|||
info->stats.tx++;
|
||||
}
|
||||
|
||||
if ((info->xmit_cnt <= 0) || info->tty->stopped) {
|
||||
if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
|
||||
info->imr &= ~MCFUART_UIR_TXREADY;
|
||||
uartp[MCFUART_UIMR] = info->imr;
|
||||
return;
|
||||
|
|
@ -428,7 +428,7 @@ irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
|
|||
static void mcfrs_offintr(struct work_struct *work)
|
||||
{
|
||||
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
|
||||
if (tty)
|
||||
tty_wakeup(tty);
|
||||
|
|
@ -498,7 +498,7 @@ static void mcfrs_timer(void)
|
|||
static void do_serial_hangup(struct work_struct *work)
|
||||
{
|
||||
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
|
||||
struct tty_struct *tty = info->tty;
|
||||
struct tty_struct *tty = info->port.tty;
|
||||
|
||||
if (tty)
|
||||
tty_hangup(tty);
|
||||
|
|
@ -532,8 +532,8 @@ static int startup(struct mcf_serial * info)
|
|||
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
|
||||
mcfrs_setsignals(info, 1, 1);
|
||||
|
||||
if (info->tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
|
||||
/*
|
||||
|
|
@ -578,7 +578,7 @@ static void shutdown(struct mcf_serial * info)
|
|||
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
|
||||
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
|
||||
|
||||
if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
|
||||
if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
|
||||
mcfrs_setsignals(info, 0, 0);
|
||||
|
||||
if (info->xmit_buf) {
|
||||
|
|
@ -586,8 +586,8 @@ static void shutdown(struct mcf_serial * info)
|
|||
info->xmit_buf = 0;
|
||||
}
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
info->flags &= ~ASYNC_INITIALIZED;
|
||||
local_irq_restore(flags);
|
||||
|
|
@ -609,9 +609,9 @@ static void mcfrs_change_speed(struct mcf_serial *info)
|
|||
unsigned int fraction;
|
||||
#endif
|
||||
|
||||
if (!info->tty || !info->tty->termios)
|
||||
if (!info->port.tty || !info->port.tty->termios)
|
||||
return;
|
||||
cflag = info->tty->termios->c_cflag;
|
||||
cflag = info->port.tty->termios->c_cflag;
|
||||
if (info->addr == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -623,7 +623,7 @@ static void mcfrs_change_speed(struct mcf_serial *info)
|
|||
if (i & CBAUDEX) {
|
||||
i &= ~CBAUDEX;
|
||||
if (i < 1 || i > 4)
|
||||
info->tty->termios->c_cflag &= ~CBAUDEX;
|
||||
info->port.tty->termios->c_cflag &= ~CBAUDEX;
|
||||
else
|
||||
i += 15;
|
||||
}
|
||||
|
|
@ -1216,7 +1216,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
|
|||
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
#if 0
|
||||
if (tty->ldisc.num != ldiscs[N_TTY].num) {
|
||||
if (tty->ldisc.close)
|
||||
|
|
@ -1325,7 +1325,7 @@ void mcfrs_hangup(struct tty_struct *tty)
|
|||
info->event = 0;
|
||||
info->count = 0;
|
||||
info->flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
wake_up_interruptible(&info->open_wait);
|
||||
}
|
||||
|
||||
|
|
@ -1452,7 +1452,7 @@ int mcfrs_open(struct tty_struct *tty, struct file * filp)
|
|||
#endif
|
||||
info->count++;
|
||||
tty->driver_data = info;
|
||||
info->tty = tty;
|
||||
info->port.tty = tty;
|
||||
|
||||
/*
|
||||
* Start up serial port
|
||||
|
|
@ -1767,7 +1767,7 @@ mcfrs_init(void)
|
|||
for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) {
|
||||
info->magic = SERIAL_MAGIC;
|
||||
info->line = i;
|
||||
info->tty = 0;
|
||||
info->port.tty = NULL;
|
||||
info->custom_divisor = 16;
|
||||
info->close_delay = 50;
|
||||
info->closing_wait = 3000;
|
||||
|
|
|
|||
|
|
@ -732,7 +732,7 @@ static struct uart_ops mpc52xx_uart_ops = {
|
|||
static inline int
|
||||
mpc52xx_uart_int_rx_chars(struct uart_port *port)
|
||||
{
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned char ch, flag;
|
||||
unsigned short status;
|
||||
|
||||
|
|
|
|||
|
|
@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
static int serial_polled;
|
||||
#endif
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
|
|
@ -932,7 +936,7 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
|
|||
static int mpsc_rx_intr(struct mpsc_port_info *pi)
|
||||
{
|
||||
struct mpsc_rx_desc *rxre;
|
||||
struct tty_struct *tty = pi->port.info->tty;
|
||||
struct tty_struct *tty = pi->port.info->port.tty;
|
||||
u32 cmdstat, bytes_in, i;
|
||||
int rc = 0;
|
||||
u8 *bp;
|
||||
|
|
@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
|
|||
while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
|
||||
& SDMA_DESC_CMDSTAT_O)) {
|
||||
bytes_in = be16_to_cpu(rxre->bytecnt);
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* Following use of tty struct directly is deprecated */
|
||||
if (unlikely(tty_buffer_request_room(tty, bytes_in)
|
||||
< bytes_in)) {
|
||||
|
|
@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
|
|||
if (uart_handle_sysrq_char(&pi->port, *bp)) {
|
||||
bp++;
|
||||
bytes_in--;
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
goto next_frame;
|
||||
}
|
||||
|
||||
|
|
@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
|
|||
|
||||
return rc;
|
||||
}
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
/* Serial polling routines for writing and reading from the uart while
|
||||
* in an interrupt or debug context.
|
||||
*/
|
||||
|
||||
static char poll_buf[2048];
|
||||
static int poll_ptr;
|
||||
static int poll_cnt;
|
||||
static void mpsc_put_poll_char(struct uart_port *port,
|
||||
unsigned char c);
|
||||
|
||||
static int mpsc_get_poll_char(struct uart_port *port)
|
||||
{
|
||||
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
|
||||
struct mpsc_rx_desc *rxre;
|
||||
u32 cmdstat, bytes_in, i;
|
||||
u8 *bp;
|
||||
|
||||
if (!serial_polled)
|
||||
serial_polled = 1;
|
||||
|
||||
pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
|
||||
|
||||
if (poll_cnt) {
|
||||
poll_cnt--;
|
||||
return poll_buf[poll_ptr++];
|
||||
}
|
||||
poll_ptr = 0;
|
||||
poll_cnt = 0;
|
||||
|
||||
while (poll_cnt == 0) {
|
||||
rxre = (struct mpsc_rx_desc *)(pi->rxr +
|
||||
(pi->rxr_posn*MPSC_RXRE_SIZE));
|
||||
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||
MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
|
||||
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||
invalidate_dcache_range((ulong)rxre,
|
||||
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||
#endif
|
||||
/*
|
||||
* Loop through Rx descriptors handling ones that have
|
||||
* been completed.
|
||||
*/
|
||||
while (poll_cnt == 0 &&
|
||||
!((cmdstat = be32_to_cpu(rxre->cmdstat)) &
|
||||
SDMA_DESC_CMDSTAT_O)){
|
||||
bytes_in = be16_to_cpu(rxre->bytecnt);
|
||||
bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
|
||||
dma_cache_sync(pi->port.dev, (void *) bp,
|
||||
MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
|
||||
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||
invalidate_dcache_range((ulong)bp,
|
||||
(ulong)bp + MPSC_RXBE_SIZE);
|
||||
#endif
|
||||
if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
|
||||
SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
|
||||
!(cmdstat & pi->port.ignore_status_mask)) {
|
||||
poll_buf[poll_cnt] = *bp;
|
||||
poll_cnt++;
|
||||
} else {
|
||||
for (i = 0; i < bytes_in; i++) {
|
||||
poll_buf[poll_cnt] = *bp++;
|
||||
poll_cnt++;
|
||||
}
|
||||
pi->port.icount.rx += bytes_in;
|
||||
}
|
||||
rxre->bytecnt = cpu_to_be16(0);
|
||||
wmb();
|
||||
rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
|
||||
SDMA_DESC_CMDSTAT_EI |
|
||||
SDMA_DESC_CMDSTAT_F |
|
||||
SDMA_DESC_CMDSTAT_L);
|
||||
wmb();
|
||||
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||
MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
|
||||
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||
flush_dcache_range((ulong)rxre,
|
||||
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||
#endif
|
||||
|
||||
/* Advance to next descriptor */
|
||||
pi->rxr_posn = (pi->rxr_posn + 1) &
|
||||
(MPSC_RXR_ENTRIES - 1);
|
||||
rxre = (struct mpsc_rx_desc *)(pi->rxr +
|
||||
(pi->rxr_posn * MPSC_RXRE_SIZE));
|
||||
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||
MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
|
||||
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||
invalidate_dcache_range((ulong)rxre,
|
||||
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Restart rx engine, if its stopped */
|
||||
if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
|
||||
mpsc_start_rx(pi);
|
||||
}
|
||||
if (poll_cnt) {
|
||||
poll_cnt--;
|
||||
return poll_buf[poll_ptr++];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void mpsc_put_poll_char(struct uart_port *port,
|
||||
unsigned char c)
|
||||
{
|
||||
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
|
||||
u32 data;
|
||||
|
||||
data = readl(pi->mpsc_base + MPSC_MPCR);
|
||||
writeb(c, pi->mpsc_base + MPSC_CHR_1);
|
||||
mb();
|
||||
data = readl(pi->mpsc_base + MPSC_CHR_2);
|
||||
data |= MPSC_CHR_2_TTCS;
|
||||
writel(data, pi->mpsc_base + MPSC_CHR_2);
|
||||
mb();
|
||||
|
||||
while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct uart_ops mpsc_pops = {
|
||||
.tx_empty = mpsc_tx_empty,
|
||||
|
|
@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = {
|
|||
.request_port = mpsc_request_port,
|
||||
.config_port = mpsc_config_port,
|
||||
.verify_port = mpsc_verify_port,
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
.poll_get_char = mpsc_get_poll_char,
|
||||
.poll_put_char = mpsc_put_poll_char,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1972,7 +2118,7 @@ static int __init mpsc_drv_init(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
printk(KERN_INFO "Serial: MPSC driver $Revision: 1.00 $\n");
|
||||
printk(KERN_INFO "Serial: MPSC driver\n");
|
||||
|
||||
memset(mpsc_ports, 0, sizeof(mpsc_ports));
|
||||
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
|
||||
|
|
@ -2004,7 +2150,7 @@ module_init(mpsc_drv_init);
|
|||
module_exit(mpsc_drv_exit);
|
||||
|
||||
MODULE_AUTHOR("Mark A. Greer <[email protected]>");
|
||||
MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
|
||||
MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver");
|
||||
MODULE_VERSION(MPSC_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ static void mux_write(struct uart_port *port)
|
|||
static void mux_read(struct uart_port *port)
|
||||
{
|
||||
int data;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
__u32 start_count = port->icount.rx;
|
||||
|
||||
while(1) {
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/netx-regs.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/netx-regs.h>
|
||||
|
||||
/* We've been assigned a range on the "Low-density serial ports" major */
|
||||
#define SERIAL_NX_MAJOR 204
|
||||
|
|
@ -203,7 +203,7 @@ static void netx_txint(struct uart_port *port)
|
|||
static void netx_rxint(struct uart_port *port)
|
||||
{
|
||||
unsigned char rx, flg, status;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
|
||||
while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
|
||||
rx = readl(port->membase + UART_DR);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/of_platform.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
struct of_serial_info {
|
||||
|
|
|
|||
|
|
@ -242,12 +242,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
|
|||
}
|
||||
|
||||
/* Sanity check, make sure the old bug is no longer happening */
|
||||
if (uap->port.info == NULL || uap->port.info->tty == NULL) {
|
||||
if (uap->port.info == NULL || uap->port.info->port.tty == NULL) {
|
||||
WARN_ON(1);
|
||||
(void)read_zsdata(uap);
|
||||
return NULL;
|
||||
}
|
||||
tty = uap->port.info->tty;
|
||||
tty = uap->port.info->port.tty;
|
||||
|
||||
while (1) {
|
||||
error = 0;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port)
|
|||
|
||||
static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
|
||||
{
|
||||
struct tty_struct *tty = sport->port.info->tty;
|
||||
struct tty_struct *tty = sport->port.info->port.tty;
|
||||
unsigned int status, ch, flg;
|
||||
|
||||
status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
|
||||
|
|
@ -824,7 +824,7 @@ static int __init pnx8xxx_serial_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Serial: PNX8XXX driver $Revision: 1.2 $\n");
|
||||
printk(KERN_INFO "Serial: PNX8XXX driver\n");
|
||||
|
||||
pnx8xxx_init_ports();
|
||||
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@
|
|||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
|
||||
|
||||
struct uart_pxa_port {
|
||||
|
|
@ -101,7 +101,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
|
|||
|
||||
static inline void receive_chars(struct uart_pxa_port *up, int *status)
|
||||
{
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned int ch, flag;
|
||||
int max_count = 256;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: sa1100.c,v 1.50 2002/07/29 14:41:04 rmk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
|
|
@ -42,7 +39,7 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach/serial_sa1100.h>
|
||||
|
||||
/* We've been assigned a range on the "Low-density serial ports" major */
|
||||
|
|
@ -192,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port)
|
|||
static void
|
||||
sa1100_rx_chars(struct sa1100_port *sport)
|
||||
{
|
||||
struct tty_struct *tty = sport->port.info->tty;
|
||||
struct tty_struct *tty = sport->port.info->port.tty;
|
||||
unsigned int status, ch, flg;
|
||||
|
||||
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
|
||||
|
|
@ -892,7 +889,7 @@ static int __init sa1100_serial_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Serial: SA11x0 driver $Revision: 1.50 $\n");
|
||||
printk(KERN_INFO "Serial: SA11x0 driver\n");
|
||||
|
||||
sa1100_init_ports();
|
||||
|
||||
|
|
@ -915,7 +912,7 @@ module_init(sa1100_serial_init);
|
|||
module_exit(sa1100_serial_exit);
|
||||
|
||||
MODULE_AUTHOR("Deep Blue Solutions Ltd");
|
||||
MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.50 $");
|
||||
MODULE_DESCRIPTION("SA1100 generic serial port driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_SA1100_MAJOR);
|
||||
MODULE_ALIAS("platform:sa11x0-uart");
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@
|
|||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
|
|||
{
|
||||
struct s3c24xx_uart_port *ourport = dev_id;
|
||||
struct uart_port *port = &ourport->port;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned int ufcon, ch, flag, ufstat, uerstat;
|
||||
int max_count = 64;
|
||||
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport)
|
|||
uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(uport->info->tty);
|
||||
tty_flip_buffer_push(uport->info->port.tty);
|
||||
}
|
||||
|
||||
static void sbd_transmit_chars(struct sbd_port *sport)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
|
|||
u8 status;
|
||||
|
||||
if (port->info != NULL) /* Unopened serial console */
|
||||
tty = port->info->tty;
|
||||
tty = port->info->port.tty;
|
||||
|
||||
while (limit-- > 0) {
|
||||
status = READ_SC_PORT(port, SR);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static struct lock_class_key port_lock_key;
|
|||
|
||||
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
|
||||
|
||||
#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
|
||||
#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0))
|
||||
|
||||
#ifdef CONFIG_SERIAL_CORE_CONSOLE
|
||||
#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
|
||||
|
|
@ -113,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
|
|||
static void uart_tasklet_action(unsigned long data)
|
||||
{
|
||||
struct uart_state *state = (struct uart_state *)data;
|
||||
tty_wakeup(state->info->tty);
|
||||
tty_wakeup(state->info->port.tty);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -135,7 +135,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
|
|||
|
||||
/*
|
||||
* Startup the port. This will be called once per open. All calls
|
||||
* will be serialised by the per-port semaphore.
|
||||
* will be serialised by the per-port mutex.
|
||||
*/
|
||||
static int uart_startup(struct uart_state *state, int init_hw)
|
||||
{
|
||||
|
|
@ -152,7 +152,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
|||
* once we have successfully opened the port. Also set
|
||||
* up the tty->alt_speed kludge
|
||||
*/
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
if (port->type == PORT_UNKNOWN)
|
||||
return 0;
|
||||
|
|
@ -162,6 +162,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
|||
* buffer.
|
||||
*/
|
||||
if (!info->xmit.buf) {
|
||||
/* This is protected by the per port mutex */
|
||||
page = get_zeroed_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
|
@ -182,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
|||
* Setup the RTS and DTR signals once the
|
||||
* port is open and ready to respond.
|
||||
*/
|
||||
if (info->tty->termios->c_cflag & CBAUD)
|
||||
if (info->port.tty->termios->c_cflag & CBAUD)
|
||||
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
|
||||
}
|
||||
|
||||
if (info->flags & UIF_CTS_FLOW) {
|
||||
spin_lock_irq(&port->lock);
|
||||
if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
|
||||
info->tty->hw_stopped = 1;
|
||||
info->port.tty->hw_stopped = 1;
|
||||
spin_unlock_irq(&port->lock);
|
||||
}
|
||||
|
||||
info->flags |= UIF_INITIALIZED;
|
||||
|
||||
clear_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
}
|
||||
|
||||
if (retval && capable(CAP_SYS_ADMIN))
|
||||
|
|
@ -217,8 +218,8 @@ static void uart_shutdown(struct uart_state *state)
|
|||
/*
|
||||
* Set the TTY IO error marker
|
||||
*/
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
if (info->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
|
||||
|
||||
if (info->flags & UIF_INITIALIZED) {
|
||||
info->flags &= ~UIF_INITIALIZED;
|
||||
|
|
@ -226,7 +227,7 @@ static void uart_shutdown(struct uart_state *state)
|
|||
/*
|
||||
* Turn off DTR and RTS early.
|
||||
*/
|
||||
if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
|
||||
if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
|
||||
uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
|
||||
/*
|
||||
|
|
@ -426,7 +427,7 @@ EXPORT_SYMBOL(uart_get_divisor);
|
|||
static void
|
||||
uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
|
||||
{
|
||||
struct tty_struct *tty = state->info->tty;
|
||||
struct tty_struct *tty = state->info->port.tty;
|
||||
struct uart_port *port = state->port;
|
||||
struct ktermios *termios;
|
||||
|
||||
|
|
@ -573,6 +574,8 @@ static void uart_flush_buffer(struct tty_struct *tty)
|
|||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
uart_circ_clear(&state->info->xmit);
|
||||
if (port->ops->flush_buffer)
|
||||
port->ops->flush_buffer(port);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
|
@ -834,8 +837,8 @@ static int uart_set_info(struct uart_state *state,
|
|||
state->closing_wait = closing_wait;
|
||||
if (new_serial.xmit_fifo_size)
|
||||
port->fifosize = new_serial.xmit_fifo_size;
|
||||
if (state->info->tty)
|
||||
state->info->tty->low_latency =
|
||||
if (state->info->port.tty)
|
||||
state->info->port.tty->low_latency =
|
||||
(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
|
||||
|
||||
check_and_exit:
|
||||
|
|
@ -855,7 +858,7 @@ static int uart_set_info(struct uart_state *state,
|
|||
printk(KERN_NOTICE
|
||||
"%s sets custom speed on %s. This "
|
||||
"is deprecated.\n", current->comm,
|
||||
tty_name(state->info->tty, buf));
|
||||
tty_name(state->info->port.tty, buf));
|
||||
}
|
||||
uart_change_speed(state, NULL);
|
||||
}
|
||||
|
|
@ -887,7 +890,7 @@ static int uart_get_lsr_info(struct uart_state *state,
|
|||
*/
|
||||
if (port->x_char ||
|
||||
((uart_circ_chars_pending(&state->info->xmit) > 0) &&
|
||||
!state->info->tty->stopped && !state->info->tty->hw_stopped))
|
||||
!state->info->port.tty->stopped && !state->info->port.tty->hw_stopped))
|
||||
result &= ~TIOCSER_TEMT;
|
||||
|
||||
return put_user(result, value);
|
||||
|
|
@ -931,7 +934,7 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||
{
|
||||
struct uart_state *state = tty->driver_data;
|
||||
struct uart_port *port = state->port;
|
||||
|
|
@ -942,6 +945,7 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
|
|||
port->ops->break_ctl(port, break_state);
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uart_do_autoconfig(struct uart_state *state)
|
||||
|
|
@ -1237,7 +1241,7 @@ static void uart_set_termios(struct tty_struct *tty,
|
|||
*/
|
||||
if (!(old_termios->c_cflag & CLOCAL) &&
|
||||
(tty->termios->c_cflag & CLOCAL))
|
||||
wake_up_interruptible(&state->info->open_wait);
|
||||
wake_up_interruptible(&state->info->port.open_wait);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1318,9 +1322,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
|||
tty_ldisc_flush(tty);
|
||||
|
||||
tty->closing = 0;
|
||||
state->info->tty = NULL;
|
||||
state->info->port.tty = NULL;
|
||||
|
||||
if (state->info->blocked_open) {
|
||||
if (state->info->port.blocked_open) {
|
||||
if (state->close_delay)
|
||||
msleep_interruptible(state->close_delay);
|
||||
} else if (!uart_console(port)) {
|
||||
|
|
@ -1331,7 +1335,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
|||
* Wake up anyone trying to open this port.
|
||||
*/
|
||||
state->info->flags &= ~UIF_NORMAL_ACTIVE;
|
||||
wake_up_interruptible(&state->info->open_wait);
|
||||
wake_up_interruptible(&state->info->port.open_wait);
|
||||
|
||||
done:
|
||||
mutex_unlock(&state->mutex);
|
||||
|
|
@ -1415,8 +1419,8 @@ static void uart_hangup(struct tty_struct *tty)
|
|||
uart_shutdown(state);
|
||||
state->count = 0;
|
||||
state->info->flags &= ~UIF_NORMAL_ACTIVE;
|
||||
state->info->tty = NULL;
|
||||
wake_up_interruptible(&state->info->open_wait);
|
||||
state->info->port.tty = NULL;
|
||||
wake_up_interruptible(&state->info->port.open_wait);
|
||||
wake_up_interruptible(&state->info->delta_msr_wait);
|
||||
}
|
||||
mutex_unlock(&state->mutex);
|
||||
|
|
@ -1430,7 +1434,7 @@ static void uart_hangup(struct tty_struct *tty)
|
|||
*/
|
||||
static void uart_update_termios(struct uart_state *state)
|
||||
{
|
||||
struct tty_struct *tty = state->info->tty;
|
||||
struct tty_struct *tty = state->info->port.tty;
|
||||
struct uart_port *port = state->port;
|
||||
|
||||
if (uart_console(port) && port->cons->cflag) {
|
||||
|
|
@ -1469,17 +1473,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||
struct uart_port *port = state->port;
|
||||
unsigned int mctrl;
|
||||
|
||||
info->blocked_open++;
|
||||
info->port.blocked_open++;
|
||||
state->count--;
|
||||
|
||||
add_wait_queue(&info->open_wait, &wait);
|
||||
add_wait_queue(&info->port.open_wait, &wait);
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
/*
|
||||
* If we have been hung up, tell userspace/restart open.
|
||||
*/
|
||||
if (tty_hung_up_p(filp) || info->tty == NULL)
|
||||
if (tty_hung_up_p(filp) || info->port.tty == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -1498,8 +1502,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||
* have set TTY_IO_ERROR for a non-existant port.
|
||||
*/
|
||||
if ((filp->f_flags & O_NONBLOCK) ||
|
||||
(info->tty->termios->c_cflag & CLOCAL) ||
|
||||
(info->tty->flags & (1 << TTY_IO_ERROR)))
|
||||
(info->port.tty->termios->c_cflag & CLOCAL) ||
|
||||
(info->port.tty->flags & (1 << TTY_IO_ERROR)))
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -1507,7 +1511,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||
* not set RTS here - we want to make sure we catch
|
||||
* the data from the modem.
|
||||
*/
|
||||
if (info->tty->termios->c_cflag & CBAUD)
|
||||
if (info->port.tty->termios->c_cflag & CBAUD)
|
||||
uart_set_mctrl(port, TIOCM_DTR);
|
||||
|
||||
/*
|
||||
|
|
@ -1529,15 +1533,15 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&info->open_wait, &wait);
|
||||
remove_wait_queue(&info->port.open_wait, &wait);
|
||||
|
||||
state->count++;
|
||||
info->blocked_open--;
|
||||
info->port.blocked_open--;
|
||||
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!info->tty || tty_hung_up_p(filp))
|
||||
if (!info->port.tty || tty_hung_up_p(filp))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1560,10 +1564,13 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
|
|||
goto err_unlock;
|
||||
}
|
||||
|
||||
/* BKL: RACE HERE - LEAK */
|
||||
/* We should move this into the uart_state structure and kill off
|
||||
this whole complexity */
|
||||
if (!state->info) {
|
||||
state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL);
|
||||
if (state->info) {
|
||||
init_waitqueue_head(&state->info->open_wait);
|
||||
init_waitqueue_head(&state->info->port.open_wait);
|
||||
init_waitqueue_head(&state->info->delta_msr_wait);
|
||||
|
||||
/*
|
||||
|
|
@ -1620,7 +1627,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
* be re-entered while allocating the info structure, or while we
|
||||
* request any IRQs that the driver may need. This also has the nice
|
||||
* side-effect that it delays the action of uart_hangup, so we can
|
||||
* guarantee that info->tty will always contain something reasonable.
|
||||
* guarantee that info->port.tty will always contain something reasonable.
|
||||
*/
|
||||
state = uart_get(drv, line);
|
||||
if (IS_ERR(state)) {
|
||||
|
|
@ -1636,7 +1643,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
tty->driver_data = state;
|
||||
tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
|
||||
tty->alt_speed = 0;
|
||||
state->info->tty = tty;
|
||||
state->info->port.tty = tty;
|
||||
|
||||
/*
|
||||
* If the port is in the middle of closing, bail out now.
|
||||
|
|
@ -2099,8 +2106,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
|
|||
/*
|
||||
* If that's unset, use the tty termios setting.
|
||||
*/
|
||||
if (state->info && state->info->tty && termios.c_cflag == 0)
|
||||
termios = *state->info->tty->termios;
|
||||
if (state->info && state->info->port.tty && termios.c_cflag == 0)
|
||||
termios = *state->info->port.tty->termios;
|
||||
|
||||
uart_change_pm(state, 0);
|
||||
port->ops->set_termios(port, &termios, NULL);
|
||||
|
|
@ -2519,8 +2526,8 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
|
|||
tty_unregister_device(drv->tty_driver, port->line);
|
||||
|
||||
info = state->info;
|
||||
if (info && info->tty)
|
||||
tty_vhangup(info->tty);
|
||||
if (info && info->port.tty)
|
||||
tty_vhangup(info->port.tty);
|
||||
|
||||
/*
|
||||
* All users of this port should now be disconnected from
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/arch/regs-uart.h>
|
||||
#include <asm/arch/regs-irq.h>
|
||||
#include <mach/regs-uart.h>
|
||||
#include <mach/regs-irq.h>
|
||||
|
||||
#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
#define SUPPORT_SYSRQ
|
||||
|
|
@ -108,7 +108,7 @@ static void ks8695uart_disable_ms(struct uart_port *port)
|
|||
static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned int status, ch, lsr, flg, max_count = 256;
|
||||
|
||||
status = UART_GET_LSR(port); /* clears pending LSR interrupts */
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
|
|||
|
||||
static void lh7a40xuart_rx_chars (struct uart_port* port)
|
||||
{
|
||||
struct tty_struct* tty = port->info->tty;
|
||||
struct tty_struct* tty = port->info->port.tty;
|
||||
int cbRxMax = 256; /* (Gross) limit on receive */
|
||||
unsigned int data; /* Received data and status */
|
||||
unsigned int flag;
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ static void serial_txx9_initialize(struct uart_port *port)
|
|||
static inline void
|
||||
receive_chars(struct uart_txx9_port *up, unsigned int *status)
|
||||
{
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned char ch;
|
||||
unsigned int disr = *status;
|
||||
int max_count = 256;
|
||||
|
|
|
|||
|
|
@ -410,7 +410,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
|
|||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7785)
|
||||
static inline int scif_txroom(struct uart_port *port)
|
||||
|
|
@ -422,6 +421,22 @@ static inline int scif_rxroom(struct uart_port *port)
|
|||
{
|
||||
return sci_in(port, SCRFDR) & 0xff;
|
||||
}
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
static inline int scif_txroom(struct uart_port *port)
|
||||
{
|
||||
if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
|
||||
return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
|
||||
else /* SCIF2 */
|
||||
return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
|
||||
}
|
||||
|
||||
static inline int scif_rxroom(struct uart_port *port)
|
||||
{
|
||||
if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
|
||||
return sci_in(port, SCRFDR) & 0xff;
|
||||
else /* SCIF2 */
|
||||
return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
|
||||
}
|
||||
#else
|
||||
static inline int scif_txroom(struct uart_port *port)
|
||||
{
|
||||
|
|
@ -521,7 +536,7 @@ static void sci_transmit_chars(struct uart_port *port)
|
|||
static inline void sci_receive_chars(struct uart_port *port)
|
||||
{
|
||||
struct sci_port *sci_port = (struct sci_port *)port;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
int i, count, copied = 0;
|
||||
unsigned short status;
|
||||
unsigned char flag;
|
||||
|
|
@ -642,7 +657,7 @@ static inline int sci_handle_errors(struct uart_port *port)
|
|||
{
|
||||
int copied = 0;
|
||||
unsigned short status = sci_in(port, SCxSR);
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
|
||||
if (status & SCxSR_ORER(port)) {
|
||||
/* overrun error */
|
||||
|
|
@ -692,7 +707,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
|
|||
{
|
||||
int copied = 0;
|
||||
unsigned short status = sci_in(port, SCxSR);
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
struct sci_port *s = &sci_ports[port->line];
|
||||
|
||||
if (uart_handle_break(port))
|
||||
|
|
@ -762,7 +777,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
|
|||
} else {
|
||||
#if defined(SCIF_ORER)
|
||||
if((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
|
||||
sci_out(port, SCLSR, 0);
|
||||
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
|
||||
|
|
|
|||
|
|
@ -123,8 +123,9 @@
|
|||
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
|
||||
# define SCSPTR1 0xffe08024 /* 16 bit SCIF */
|
||||
# define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */
|
||||
# define SCIF_ORER 0x0001 /* overrun error bit */
|
||||
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
# define SCIF_ONLY
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
|
||||
# define SCSPTR0 0xff923020 /* 16 bit SCIF */
|
||||
|
|
@ -188,6 +189,7 @@
|
|||
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SHX3)
|
||||
|
|
@ -225,14 +227,21 @@
|
|||
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7721)
|
||||
#define SCIF_ORER 0x0200
|
||||
#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
|
||||
#define SCIF_RFDC_MASK 0x007f
|
||||
#define SCIF_TXROOM_MAX 64
|
||||
# define SCIF_ORER 0x0200
|
||||
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
|
||||
# define SCIF_RFDC_MASK 0x007f
|
||||
# define SCIF_TXROOM_MAX 64
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
|
||||
# define SCIF_RFDC_MASK 0x007f
|
||||
# define SCIF_TXROOM_MAX 64
|
||||
/* SH7763 SCIF2 support */
|
||||
# define SCIF2_RFDC_MASK 0x001f
|
||||
# define SCIF2_TXROOM_MAX 16
|
||||
#else
|
||||
#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
|
||||
#define SCIF_RFDC_MASK 0x001f
|
||||
#define SCIF_TXROOM_MAX 16
|
||||
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
|
||||
# define SCIF_RFDC_MASK 0x001f
|
||||
# define SCIF_TXROOM_MAX 16
|
||||
#endif
|
||||
|
||||
#if defined(SCI_ONLY)
|
||||
|
|
@ -442,7 +451,6 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
|
|||
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
|
||||
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7785)
|
||||
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
|
||||
|
|
@ -450,6 +458,14 @@ SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
|
|||
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
|
||||
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
|
||||
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
|
||||
SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
|
||||
SCIF_FNS(SCLSR2, 0, 0, 0x24, 16)
|
||||
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
|
||||
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
|
||||
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
|
||||
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
|
||||
#else
|
||||
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
|
||||
|
|
@ -652,6 +668,9 @@ static inline int sci_rxd_in(struct uart_port *port)
|
|||
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xffe08000)
|
||||
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xffe10000)
|
||||
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
|
||||
|
||||
return 1;
|
||||
}
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
|
||||
|
|
@ -764,8 +783,7 @@ static inline int sci_rxd_in(struct uart_port *port)
|
|||
* -- Mitch Davis - 15 Jul 2000
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7785)
|
||||
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
|
|||
|
||||
if (port->sc_port.info) {
|
||||
/* The serial_core stuffs are initilized, use them */
|
||||
tty = port->sc_port.info->tty;
|
||||
tty = port->sc_port.info->port.tty;
|
||||
}
|
||||
else {
|
||||
/* Not registered yet - can't pass to tty layer. */
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
|
|||
struct tty_struct *tty = NULL;
|
||||
|
||||
if (port->info != NULL) /* Unopened serial console */
|
||||
tty = port->info->tty;
|
||||
tty = port->info->port.tty;
|
||||
|
||||
if (sunhv_ops->receive_chars(port, tty))
|
||||
sun_do_break();
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ receive_chars(struct uart_sunsab_port *up,
|
|||
int i;
|
||||
|
||||
if (up->port.info != NULL) /* Unopened serial console */
|
||||
tty = up->port.info->tty;
|
||||
tty = up->port.info->port.tty;
|
||||
|
||||
/* Read number of BYTES (Character + Status) available. */
|
||||
if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
|
||||
/*
|
||||
* su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
|
||||
*
|
||||
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
|
|
@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
|
|||
static struct tty_struct *
|
||||
receive_chars(struct uart_sunsu_port *up, unsigned char *status)
|
||||
{
|
||||
struct tty_struct *tty = up->port.info->tty;
|
||||
struct tty_struct *tty = up->port.info->port.tty;
|
||||
unsigned char ch, flag;
|
||||
int max_count = 256;
|
||||
int saw_console_brk = 0;
|
||||
|
|
|
|||
|
|
@ -329,8 +329,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
|
|||
|
||||
tty = NULL;
|
||||
if (up->port.info != NULL && /* Unopened serial console */
|
||||
up->port.info->tty != NULL) /* Keyboard || mouse */
|
||||
tty = up->port.info->tty;
|
||||
up->port.info->port.tty != NULL) /* Keyboard || mouse */
|
||||
tty = up->port.info->port.tty;
|
||||
|
||||
for (;;) {
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS];
|
|||
|
||||
static int ulite_receive(struct uart_port *port, int stat)
|
||||
{
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
unsigned char ch = 0;
|
||||
char flag = TTY_NORMAL;
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
|
|||
busy |= ulite_transmit(port, stat);
|
||||
} while (busy);
|
||||
|
||||
tty_flip_buffer_push(port->info->tty);
|
||||
tty_flip_buffer_push(port->info->port.tty);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
|
|||
int i;
|
||||
unsigned char ch, *cp;
|
||||
struct uart_port *port = &qe_port->port;
|
||||
struct tty_struct *tty = port->info->tty;
|
||||
struct tty_struct *tty = port->info->port.tty;
|
||||
struct qe_bd *bdp;
|
||||
u16 status;
|
||||
unsigned int flg;
|
||||
|
|
|
|||
|
|
@ -1,548 +0,0 @@
|
|||
/*
|
||||
* drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
|
||||
*
|
||||
* Copyright (C) 2001,02,03 NEC Electronics Corporation
|
||||
* Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file COPYING in the main directory of this
|
||||
* archive for more details.
|
||||
*
|
||||
* Written by Miles Bader <miles@gnu.org>
|
||||
*/
|
||||
|
||||
/* This driver supports both the original V850E UART interface (called
|
||||
merely `UART' in the docs) and the newer `UARTB' interface, which is
|
||||
roughly a superset of the first one. The selection is made at
|
||||
configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
|
||||
presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
|
||||
can never have both.
|
||||
|
||||
The UARTB interface also has a 16-entry FIFO mode, which is not
|
||||
yet supported by this driver. */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
#include <asm/v850e_uart.h>
|
||||
|
||||
/* Initial UART state. This may be overridden by machine-dependent headers. */
|
||||
#ifndef V850E_UART_INIT_BAUD
|
||||
#define V850E_UART_INIT_BAUD 115200
|
||||
#endif
|
||||
#ifndef V850E_UART_INIT_CFLAGS
|
||||
#define V850E_UART_INIT_CFLAGS (B115200 | CS8 | CREAD)
|
||||
#endif
|
||||
|
||||
/* A string used for prefixing printed descriptions; since the same UART
|
||||
macro is actually used on other chips than the V850E. This must be a
|
||||
constant string. */
|
||||
#ifndef V850E_UART_CHIP_NAME
|
||||
#define V850E_UART_CHIP_NAME "V850E"
|
||||
#endif
|
||||
|
||||
#define V850E_UART_MINOR_BASE 64 /* First tty minor number */
|
||||
|
||||
|
||||
/* Low-level UART functions. */
|
||||
|
||||
/* Configure and turn on uart channel CHAN, using the termios `control
|
||||
modes' bits in CFLAGS, and a baud-rate of BAUD. */
|
||||
void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
|
||||
{
|
||||
int flags;
|
||||
v850e_uart_speed_t old_speed;
|
||||
v850e_uart_config_t old_config;
|
||||
v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
|
||||
v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);
|
||||
|
||||
/* Disable interrupts while we're twiddling the hardware. */
|
||||
local_irq_save (flags);
|
||||
|
||||
#ifdef V850E_UART_PRE_CONFIGURE
|
||||
V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
|
||||
#endif
|
||||
|
||||
old_config = V850E_UART_CONFIG (chan);
|
||||
old_speed = v850e_uart_speed (chan);
|
||||
|
||||
if (! v850e_uart_speed_eq (old_speed, new_speed)) {
|
||||
/* The baud rate has changed. First, disable the UART. */
|
||||
V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
|
||||
old_config = 0; /* Force the uart to be re-initialized. */
|
||||
|
||||
/* Reprogram the baud-rate generator. */
|
||||
v850e_uart_set_speed (chan, new_speed);
|
||||
}
|
||||
|
||||
if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
|
||||
/* If we are using the uart for the first time, start by
|
||||
enabling it, which must be done before turning on any
|
||||
other bits. */
|
||||
V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
|
||||
/* See the initial state. */
|
||||
old_config = V850E_UART_CONFIG (chan);
|
||||
}
|
||||
|
||||
if (new_config != old_config) {
|
||||
/* Which of the TXE/RXE bits we'll temporarily turn off
|
||||
before changing other control bits. */
|
||||
unsigned temp_disable = 0;
|
||||
/* Which of the TXE/RXE bits will be enabled. */
|
||||
unsigned enable = 0;
|
||||
unsigned changed_bits = new_config ^ old_config;
|
||||
|
||||
/* Which of RX/TX will be enabled in the new configuration. */
|
||||
if (new_config & V850E_UART_CONFIG_RX_BITS)
|
||||
enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
|
||||
if (new_config & V850E_UART_CONFIG_TX_BITS)
|
||||
enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);
|
||||
|
||||
/* Figure out which of RX/TX needs to be disabled; note
|
||||
that this will only happen if they're not already
|
||||
disabled. */
|
||||
if (changed_bits & V850E_UART_CONFIG_RX_BITS)
|
||||
temp_disable
|
||||
|= (old_config & V850E_UART_CONFIG_RX_ENABLE);
|
||||
if (changed_bits & V850E_UART_CONFIG_TX_BITS)
|
||||
temp_disable
|
||||
|= (old_config & V850E_UART_CONFIG_TX_ENABLE);
|
||||
|
||||
/* We have to turn off RX and/or TX mode before changing
|
||||
any associated control bits. */
|
||||
if (temp_disable)
|
||||
V850E_UART_CONFIG (chan) = old_config & ~temp_disable;
|
||||
|
||||
/* Write the new control bits, while RX/TX are disabled. */
|
||||
if (changed_bits & ~enable)
|
||||
V850E_UART_CONFIG (chan) = new_config & ~enable;
|
||||
|
||||
v850e_uart_config_delay (new_config, new_speed);
|
||||
|
||||
/* Write the final version, with enable bits turned on. */
|
||||
V850E_UART_CONFIG (chan) = new_config;
|
||||
}
|
||||
|
||||
local_irq_restore (flags);
|
||||
}
|
||||
|
||||
|
||||
/* Low-level console. */
|
||||
|
||||
#ifdef CONFIG_V850E_UART_CONSOLE
|
||||
|
||||
static void v850e_uart_cons_write (struct console *co,
|
||||
const char *s, unsigned count)
|
||||
{
|
||||
if (count > 0) {
|
||||
unsigned chan = co->index;
|
||||
unsigned irq = V850E_UART_TX_IRQ (chan);
|
||||
int irq_was_enabled, irq_was_pending, flags;
|
||||
|
||||
/* We don't want to get `transmission completed'
|
||||
interrupts, since we're busy-waiting, so we disable them
|
||||
while sending (we don't disable interrupts entirely
|
||||
because sending over a serial line is really slow). We
|
||||
save the status of the tx interrupt and restore it when
|
||||
we're done so that using printk doesn't interfere with
|
||||
normal serial transmission (other than interleaving the
|
||||
output, of course!). This should work correctly even if
|
||||
this function is interrupted and the interrupt printks
|
||||
something. */
|
||||
|
||||
/* Disable interrupts while fiddling with tx interrupt. */
|
||||
local_irq_save (flags);
|
||||
/* Get current tx interrupt status. */
|
||||
irq_was_enabled = v850e_intc_irq_enabled (irq);
|
||||
irq_was_pending = v850e_intc_irq_pending (irq);
|
||||
/* Disable tx interrupt if necessary. */
|
||||
if (irq_was_enabled)
|
||||
v850e_intc_disable_irq (irq);
|
||||
/* Turn interrupts back on. */
|
||||
local_irq_restore (flags);
|
||||
|
||||
/* Send characters. */
|
||||
while (count > 0) {
|
||||
int ch = *s++;
|
||||
|
||||
if (ch == '\n') {
|
||||
/* We don't have the benefit of a tty
|
||||
driver, so translate NL into CR LF. */
|
||||
v850e_uart_wait_for_xmit_ok (chan);
|
||||
v850e_uart_putc (chan, '\r');
|
||||
}
|
||||
|
||||
v850e_uart_wait_for_xmit_ok (chan);
|
||||
v850e_uart_putc (chan, ch);
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
/* Restore saved tx interrupt status. */
|
||||
if (irq_was_enabled) {
|
||||
/* Wait for the last character we sent to be
|
||||
completely transmitted (as we'll get an
|
||||
interrupt interrupt at that point). */
|
||||
v850e_uart_wait_for_xmit_done (chan);
|
||||
/* Clear pending interrupts received due
|
||||
to our transmission, unless there was already
|
||||
one pending, in which case we want the
|
||||
handler to be called. */
|
||||
if (! irq_was_pending)
|
||||
v850e_intc_clear_pending_irq (irq);
|
||||
/* ... and then turn back on handling. */
|
||||
v850e_intc_enable_irq (irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern struct uart_driver v850e_uart_driver;
|
||||
static struct console v850e_uart_cons =
|
||||
{
|
||||
.name = "ttyS",
|
||||
.write = v850e_uart_cons_write,
|
||||
.device = uart_console_device,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.cflag = V850E_UART_INIT_CFLAGS,
|
||||
.index = -1,
|
||||
.data = &v850e_uart_driver,
|
||||
};
|
||||
|
||||
void v850e_uart_cons_init (unsigned chan)
|
||||
{
|
||||
v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
|
||||
V850E_UART_INIT_BAUD);
|
||||
v850e_uart_cons.index = chan;
|
||||
register_console (&v850e_uart_cons);
|
||||
printk ("Console: %s on-chip UART channel %d\n",
|
||||
V850E_UART_CHIP_NAME, chan);
|
||||
}
|
||||
|
||||
/* This is what the init code actually calls. */
|
||||
static int v850e_uart_console_init (void)
|
||||
{
|
||||
v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
|
||||
return 0;
|
||||
}
|
||||
console_initcall(v850e_uart_console_init);
|
||||
|
||||
#define V850E_UART_CONSOLE &v850e_uart_cons
|
||||
|
||||
#else /* !CONFIG_V850E_UART_CONSOLE */
|
||||
#define V850E_UART_CONSOLE 0
|
||||
#endif /* CONFIG_V850E_UART_CONSOLE */
|
||||
|
||||
/* TX/RX interrupt handlers. */
|
||||
|
||||
static void v850e_uart_stop_tx (struct uart_port *port);
|
||||
|
||||
void v850e_uart_tx (struct uart_port *port)
|
||||
{
|
||||
struct circ_buf *xmit = &port->info->xmit;
|
||||
int stopped = uart_tx_stopped (port);
|
||||
|
||||
if (v850e_uart_xmit_ok (port->line)) {
|
||||
int tx_ch;
|
||||
|
||||
if (port->x_char) {
|
||||
tx_ch = port->x_char;
|
||||
port->x_char = 0;
|
||||
} else if (!uart_circ_empty (xmit) && !stopped) {
|
||||
tx_ch = xmit->buf[xmit->tail];
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
} else
|
||||
goto no_xmit;
|
||||
|
||||
v850e_uart_putc (port->line, tx_ch);
|
||||
port->icount.tx++;
|
||||
|
||||
if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup (port);
|
||||
}
|
||||
|
||||
no_xmit:
|
||||
if (uart_circ_empty (xmit) || stopped)
|
||||
v850e_uart_stop_tx (port, stopped);
|
||||
}
|
||||
|
||||
static irqreturn_t v850e_uart_tx_irq(int irq, void *data)
|
||||
{
|
||||
struct uart_port *port = data;
|
||||
v850e_uart_tx (port);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
|
||||
{
|
||||
struct uart_port *port = data;
|
||||
unsigned ch_stat = TTY_NORMAL;
|
||||
unsigned ch = v850e_uart_getc (port->line);
|
||||
unsigned err = v850e_uart_err (port->line);
|
||||
|
||||
if (err) {
|
||||
if (err & V850E_UART_ERR_OVERRUN) {
|
||||
ch_stat = TTY_OVERRUN;
|
||||
port->icount.overrun++;
|
||||
} else if (err & V850E_UART_ERR_FRAME) {
|
||||
ch_stat = TTY_FRAME;
|
||||
port->icount.frame++;
|
||||
} else if (err & V850E_UART_ERR_PARITY) {
|
||||
ch_stat = TTY_PARITY;
|
||||
port->icount.parity++;
|
||||
}
|
||||
}
|
||||
|
||||
port->icount.rx++;
|
||||
|
||||
tty_insert_flip_char (port->info->tty, ch, ch_stat);
|
||||
tty_schedule_flip (port->info->tty);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
/* Control functions for the serial framework. */
|
||||
|
||||
static void v850e_uart_nop (struct uart_port *port) { }
|
||||
static int v850e_uart_success (struct uart_port *port) { return 0; }
|
||||
|
||||
static unsigned v850e_uart_tx_empty (struct uart_port *port)
|
||||
{
|
||||
return TIOCSER_TEMT; /* Can't detect. */
|
||||
}
|
||||
|
||||
static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
|
||||
{
|
||||
#ifdef V850E_UART_SET_RTS
|
||||
V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned v850e_uart_get_mctrl (struct uart_port *port)
|
||||
{
|
||||
/* We don't support DCD or DSR, so consider them permanently active. */
|
||||
int mctrl = TIOCM_CAR | TIOCM_DSR;
|
||||
|
||||
/* We may support CTS. */
|
||||
#ifdef V850E_UART_CTS
|
||||
mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
|
||||
#else
|
||||
mctrl |= TIOCM_CTS;
|
||||
#endif
|
||||
|
||||
return mctrl;
|
||||
}
|
||||
|
||||
static void v850e_uart_start_tx (struct uart_port *port)
|
||||
{
|
||||
v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
|
||||
v850e_uart_tx (port);
|
||||
v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
|
||||
}
|
||||
|
||||
static void v850e_uart_stop_tx (struct uart_port *port)
|
||||
{
|
||||
v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
|
||||
}
|
||||
|
||||
static void v850e_uart_start_rx (struct uart_port *port)
|
||||
{
|
||||
v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
|
||||
}
|
||||
|
||||
static void v850e_uart_stop_rx (struct uart_port *port)
|
||||
{
|
||||
v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
|
||||
}
|
||||
|
||||
static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
|
||||
{
|
||||
/* Umm, do this later. */
|
||||
}
|
||||
|
||||
static int v850e_uart_startup (struct uart_port *port)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Alloc RX irq. */
|
||||
err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
|
||||
IRQF_DISABLED, "v850e_uart", port);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Alloc TX irq. */
|
||||
err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
|
||||
IRQF_DISABLED, "v850e_uart", port);
|
||||
if (err) {
|
||||
free_irq (V850E_UART_RX_IRQ (port->line), port);
|
||||
return err;
|
||||
}
|
||||
|
||||
v850e_uart_start_rx (port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void v850e_uart_shutdown (struct uart_port *port)
|
||||
{
|
||||
/* Disable port interrupts. */
|
||||
free_irq (V850E_UART_TX_IRQ (port->line), port);
|
||||
free_irq (V850E_UART_RX_IRQ (port->line), port);
|
||||
|
||||
/* Turn off xmit/recv enable bits. */
|
||||
V850E_UART_CONFIG (port->line)
|
||||
&= ~(V850E_UART_CONFIG_TX_ENABLE
|
||||
| V850E_UART_CONFIG_RX_ENABLE);
|
||||
/* Then reset the channel. */
|
||||
V850E_UART_CONFIG (port->line) = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
v850e_uart_set_termios (struct uart_port *port, struct ktermios *termios,
|
||||
struct ktermios *old)
|
||||
{
|
||||
unsigned cflags = termios->c_cflag;
|
||||
|
||||
/* Restrict flags to legal values. */
|
||||
if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
|
||||
/* The new value of CSIZE is invalid, use the old value. */
|
||||
cflags = (cflags & ~CSIZE)
|
||||
| (old ? (old->c_cflag & CSIZE) : CS8);
|
||||
|
||||
termios->c_cflag = cflags;
|
||||
|
||||
v850e_uart_configure (port->line, cflags,
|
||||
uart_get_baud_rate (port, termios, old,
|
||||
v850e_uart_min_baud(),
|
||||
v850e_uart_max_baud()));
|
||||
}
|
||||
|
||||
static const char *v850e_uart_type (struct uart_port *port)
|
||||
{
|
||||
return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
|
||||
}
|
||||
|
||||
static void v850e_uart_config_port (struct uart_port *port, int flags)
|
||||
{
|
||||
if (flags & UART_CONFIG_TYPE)
|
||||
port->type = PORT_V850E_UART;
|
||||
}
|
||||
|
||||
static int
|
||||
v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
|
||||
{
|
||||
if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
|
||||
return -EINVAL;
|
||||
if (ser->irq != V850E_UART_TX_IRQ (port->line))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct uart_ops v850e_uart_ops = {
|
||||
.tx_empty = v850e_uart_tx_empty,
|
||||
.get_mctrl = v850e_uart_get_mctrl,
|
||||
.set_mctrl = v850e_uart_set_mctrl,
|
||||
.start_tx = v850e_uart_start_tx,
|
||||
.stop_tx = v850e_uart_stop_tx,
|
||||
.stop_rx = v850e_uart_stop_rx,
|
||||
.enable_ms = v850e_uart_nop,
|
||||
.break_ctl = v850e_uart_break_ctl,
|
||||
.startup = v850e_uart_startup,
|
||||
.shutdown = v850e_uart_shutdown,
|
||||
.set_termios = v850e_uart_set_termios,
|
||||
.type = v850e_uart_type,
|
||||
.release_port = v850e_uart_nop,
|
||||
.request_port = v850e_uart_success,
|
||||
.config_port = v850e_uart_config_port,
|
||||
.verify_port = v850e_uart_verify_port,
|
||||
};
|
||||
|
||||
/* Initialization and cleanup. */
|
||||
|
||||
static struct uart_driver v850e_uart_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_name = "v850e_uart",
|
||||
.dev_name = "ttyS",
|
||||
.major = TTY_MAJOR,
|
||||
.minor = V850E_UART_MINOR_BASE,
|
||||
.nr = V850E_UART_NUM_CHANNELS,
|
||||
.cons = V850E_UART_CONSOLE,
|
||||
};
|
||||
|
||||
|
||||
static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];
|
||||
|
||||
static int __init v850e_uart_init (void)
|
||||
{
|
||||
int rval;
|
||||
|
||||
printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);
|
||||
|
||||
rval = uart_register_driver (&v850e_uart_driver);
|
||||
if (rval == 0) {
|
||||
unsigned chan;
|
||||
|
||||
for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
|
||||
struct uart_port *port = &v850e_uart_ports[chan];
|
||||
|
||||
memset (port, 0, sizeof *port);
|
||||
|
||||
port->ops = &v850e_uart_ops;
|
||||
port->line = chan;
|
||||
port->iotype = UPIO_MEM;
|
||||
port->flags = UPF_BOOT_AUTOCONF;
|
||||
|
||||
/* We actually use multiple IRQs, but the serial
|
||||
framework seems to mainly use this for
|
||||
informational purposes anyway. Here we use the TX
|
||||
irq. */
|
||||
port->irq = V850E_UART_TX_IRQ (chan);
|
||||
|
||||
/* The serial framework doesn't really use these
|
||||
membase/mapbase fields for anything useful, but
|
||||
it requires that they be something non-zero to
|
||||
consider the port `valid', and also uses them
|
||||
for informational purposes. */
|
||||
port->membase = (void *)V850E_UART_BASE_ADDR (chan);
|
||||
port->mapbase = V850E_UART_BASE_ADDR (chan);
|
||||
|
||||
/* The framework insists on knowing the uart's master
|
||||
clock freq, though it doesn't seem to do anything
|
||||
useful for us with it. We must make it at least
|
||||
higher than (the maximum baud rate * 16), otherwise
|
||||
the framework will puke during its internal
|
||||
calculations, and force the baud rate to be 9600.
|
||||
To be accurate though, just repeat the calculation
|
||||
we use when actually setting the speed. */
|
||||
port->uartclk = v850e_uart_max_clock() * 16;
|
||||
|
||||
uart_add_one_port (&v850e_uart_driver, port);
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void __exit v850e_uart_exit (void)
|
||||
{
|
||||
unsigned chan;
|
||||
|
||||
for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
|
||||
uart_remove_one_port (&v850e_uart_driver,
|
||||
&v850e_uart_ports[chan]);
|
||||
|
||||
uart_unregister_driver (&v850e_uart_driver);
|
||||
}
|
||||
|
||||
module_init (v850e_uart_init);
|
||||
module_exit (v850e_uart_exit);
|
||||
|
||||
MODULE_AUTHOR ("Miles Bader");
|
||||
MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
|
||||
MODULE_LICENSE ("GPL");
|
||||
|
|
@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status)
|
|||
char flag;
|
||||
int max_count = RX_MAX_COUNT;
|
||||
|
||||
tty = port->info->tty;
|
||||
tty = port->info->port.tty;
|
||||
lsr = *status;
|
||||
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ static void zs_receive_chars(struct zs_port *zport)
|
|||
uart_insert_char(uport, status, Rx_OVR, ch, flag);
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(uport->info->tty);
|
||||
tty_flip_buffer_push(uport->info->port.tty);
|
||||
}
|
||||
|
||||
static void zs_raw_transmit_chars(struct zs_port *zport)
|
||||
|
|
@ -787,7 +787,6 @@ static int zs_startup(struct uart_port *uport)
|
|||
zport->regs[1] &= ~RxINT_MASK;
|
||||
zport->regs[1] |= RxINT_ALL | TxINT_ENAB | EXT_INT_ENAB;
|
||||
zport->regs[3] |= RxENABLE;
|
||||
zport->regs[5] |= TxENAB;
|
||||
zport->regs[15] |= BRKIE;
|
||||
write_zsreg(zport, R1, zport->regs[1]);
|
||||
write_zsreg(zport, R3, zport->regs[3]);
|
||||
|
|
@ -814,7 +813,6 @@ static void zs_shutdown(struct uart_port *uport)
|
|||
|
||||
spin_lock_irqsave(&scc->zlock, flags);
|
||||
|
||||
zport->regs[5] &= ~TxENAB;
|
||||
zport->regs[3] &= ~RxENABLE;
|
||||
write_zsreg(zport, R5, zport->regs[5]);
|
||||
write_zsreg(zport, R3, zport->regs[3]);
|
||||
|
|
@ -959,6 +957,23 @@ static void zs_set_termios(struct uart_port *uport, struct ktermios *termios,
|
|||
spin_unlock_irqrestore(&scc->zlock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hack alert!
|
||||
* Required solely so that the initial PROM-based console
|
||||
* works undisturbed in parallel with this one.
|
||||
*/
|
||||
static void zs_pm(struct uart_port *uport, unsigned int state,
|
||||
unsigned int oldstate)
|
||||
{
|
||||
struct zs_port *zport = to_zport(uport);
|
||||
|
||||
if (state < 3)
|
||||
zport->regs[5] |= TxENAB;
|
||||
else
|
||||
zport->regs[5] &= ~TxENAB;
|
||||
write_zsreg(zport, R5, zport->regs[5]);
|
||||
}
|
||||
|
||||
|
||||
static const char *zs_type(struct uart_port *uport)
|
||||
{
|
||||
|
|
@ -1041,6 +1056,7 @@ static struct uart_ops zs_ops = {
|
|||
.startup = zs_startup,
|
||||
.shutdown = zs_shutdown,
|
||||
.set_termios = zs_set_termios,
|
||||
.pm = zs_pm,
|
||||
.type = zs_type,
|
||||
.release_port = zs_release_port,
|
||||
.request_port = zs_request_port,
|
||||
|
|
@ -1190,6 +1206,7 @@ static int __init zs_console_setup(struct console *co, char *options)
|
|||
return ret;
|
||||
|
||||
zs_reset(zport);
|
||||
zs_pm(uport, 0, -1);
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
|
|
|||
Loading…
Reference in a new issue