Ben Dooks 2008-08-08 21:10:12 +01:00
commit af7a535688
10414 changed files with 552605 additions and 479816 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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"

View file

@ -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>

View file

@ -119,3 +119,5 @@ int __init probe_serial_gsc(void)
}
module_init(probe_serial_gsc);
MODULE_LICENSE("GPL");

View file

@ -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,

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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];

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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 */

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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)

View file

@ -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");

View file

@ -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);
}
/****************************************************************************/

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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");

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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) || \

View file

@ -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. */

View file

@ -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();

View file

@ -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) {

View file

@ -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;

View file

@ -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 (;;) {

View file

@ -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;
}

View file

@ -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;

View file

@ -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");

View file

@ -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 {

View file

@ -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);