Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (79 commits) TTY: serial_core: Fix crash if DCD drop during suspend tty/serial: atmel_serial: bootconsole removed from auto-enumerates Revert "TTY: call tty_driver_lookup_tty unconditionally" tty/serial: atmel_serial: add device tree support tty/serial: atmel_serial: auto-enumerate ports tty/serial: atmel_serial: whitespace and braces modifications tty/serial: atmel_serial: change platform_data variable name tty/serial: RS485 bindings for device tree TTY: call tty_driver_lookup_tty unconditionally TTY: pty, release tty in all ptmx_open fail paths TTY: make tty_add_file non-failing TTY: drop driver reference in tty_open fail path 8250_pci: Fix kernel panic when pch_uart is disabled h8300: drivers/serial/Kconfig was moved parport_pc: release IO region properly if unsupported ITE887x card is found tty: Support compat_ioctl get/set termios_locked hvc_console: display printk messages on console. TTY: snyclinkmp: forever loop in tx_load_dma_buffer() tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case) ... Fix up Conflicts in: - drivers/tty/serial/8250_pci.c Trivial conflict with removed duplicate device ID - drivers/tty/serial/atmel_serial.c Annoying silly conflict between "specify the port num via platform_data" and other changes to atmel_console_init
This commit is contained in:
@@ -235,22 +235,6 @@ static void batten_down_hatches(void)
|
||||
|
||||
static void status_handle(struct m68k_serial *info, unsigned short status)
|
||||
{
|
||||
#if 0
|
||||
if(status & DCD) {
|
||||
if((info->port.tty->termios->c_cflag & CRTSCTS) &&
|
||||
((info->curregs[3] & AUTO_ENAB)==0)) {
|
||||
info->curregs[3] |= AUTO_ENAB;
|
||||
info->pendregs[3] |= AUTO_ENAB;
|
||||
write_zsreg(info->m68k_channel, 3, info->curregs[3]);
|
||||
}
|
||||
} else {
|
||||
if((info->curregs[3] & AUTO_ENAB)) {
|
||||
info->curregs[3] &= ~AUTO_ENAB;
|
||||
info->pendregs[3] &= ~AUTO_ENAB;
|
||||
write_zsreg(info->m68k_channel, 3, info->curregs[3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* If this is console input and this is a
|
||||
* 'break asserted' status change interrupt
|
||||
* see if we can drop into the debugger
|
||||
@@ -340,9 +324,6 @@ static void transmit_chars(struct m68k_serial *info)
|
||||
info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
|
||||
info->xmit_cnt--;
|
||||
|
||||
if (info->xmit_cnt < WAKEUP_CHARS)
|
||||
schedule_work(&info->tqueue);
|
||||
|
||||
if(info->xmit_cnt <= 0) {
|
||||
/* All done for now... TX ints off */
|
||||
uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
|
||||
@@ -378,21 +359,6 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!tty)
|
||||
return;
|
||||
#if 0
|
||||
if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int startup(struct m68k_serial * info)
|
||||
{
|
||||
m68328_uart *uart = &uart_addr[info->line];
|
||||
@@ -1324,7 +1290,6 @@ rs68328_init(void)
|
||||
info->event = 0;
|
||||
info->count = 0;
|
||||
info->blocked_open = 0;
|
||||
INIT_WORK(&info->tqueue, do_softint);
|
||||
init_waitqueue_head(&info->open_wait);
|
||||
init_waitqueue_head(&info->close_wait);
|
||||
info->line = i;
|
||||
@@ -1341,7 +1306,7 @@ rs68328_init(void)
|
||||
|
||||
if (request_irq(uart_irqs[i],
|
||||
rs_interrupt,
|
||||
IRQF_DISABLED,
|
||||
0,
|
||||
"M68328_UART", info))
|
||||
panic("Unable to attach 68328 serial interrupt\n");
|
||||
}
|
||||
|
@@ -158,7 +158,6 @@ struct m68k_serial {
|
||||
int xmit_head;
|
||||
int xmit_tail;
|
||||
int xmit_cnt;
|
||||
struct work_struct tqueue;
|
||||
wait_queue_head_t open_wait;
|
||||
wait_queue_head_t close_wait;
|
||||
};
|
||||
|
File diff ditekan karena terlalu besar
Load Diff
@@ -309,6 +309,13 @@ static const struct serial8250_config uart_config[] = {
|
||||
UART_FCR_T_TRIG_01,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_RTOIE,
|
||||
},
|
||||
[PORT_XR17D15X] = {
|
||||
.name = "XR17D15X",
|
||||
.fifo_size = 64,
|
||||
.tx_loadsz = 64,
|
||||
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MIPS_ALCHEMY)
|
||||
@@ -461,42 +468,6 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value)
|
||||
writeb(value, p->membase + offset);
|
||||
}
|
||||
|
||||
/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
|
||||
static inline void dwapb_save_out_value(struct uart_port *p, int offset,
|
||||
int value)
|
||||
{
|
||||
struct uart_8250_port *up =
|
||||
container_of(p, struct uart_8250_port, port);
|
||||
|
||||
if (offset == UART_LCR)
|
||||
up->lcr = value;
|
||||
}
|
||||
|
||||
/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
|
||||
static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
|
||||
{
|
||||
if (offset == UART_TX || offset == UART_IER)
|
||||
p->serial_in(p, UART_IER);
|
||||
}
|
||||
|
||||
static void dwapb_serial_out(struct uart_port *p, int offset, int value)
|
||||
{
|
||||
int save_offset = offset;
|
||||
offset = map_8250_out_reg(p, offset) << p->regshift;
|
||||
dwapb_save_out_value(p, save_offset, value);
|
||||
writeb(value, p->membase + offset);
|
||||
dwapb_check_clear_ier(p, save_offset);
|
||||
}
|
||||
|
||||
static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
|
||||
{
|
||||
int save_offset = offset;
|
||||
offset = map_8250_out_reg(p, offset) << p->regshift;
|
||||
dwapb_save_out_value(p, save_offset, value);
|
||||
writel(value, p->membase + offset);
|
||||
dwapb_check_clear_ier(p, save_offset);
|
||||
}
|
||||
|
||||
static unsigned int io_serial_in(struct uart_port *p, int offset)
|
||||
{
|
||||
offset = map_8250_in_reg(p, offset) << p->regshift;
|
||||
@@ -509,6 +480,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
|
||||
outb(value, p->iobase + offset);
|
||||
}
|
||||
|
||||
static int serial8250_default_handle_irq(struct uart_port *port);
|
||||
|
||||
static void set_io_from_upio(struct uart_port *p)
|
||||
{
|
||||
struct uart_8250_port *up =
|
||||
@@ -540,16 +513,6 @@ static void set_io_from_upio(struct uart_port *p)
|
||||
p->serial_out = tsi_serial_out;
|
||||
break;
|
||||
|
||||
case UPIO_DWAPB:
|
||||
p->serial_in = mem_serial_in;
|
||||
p->serial_out = dwapb_serial_out;
|
||||
break;
|
||||
|
||||
case UPIO_DWAPB32:
|
||||
p->serial_in = mem32_serial_in;
|
||||
p->serial_out = dwapb32_serial_out;
|
||||
break;
|
||||
|
||||
default:
|
||||
p->serial_in = io_serial_in;
|
||||
p->serial_out = io_serial_out;
|
||||
@@ -557,6 +520,7 @@ static void set_io_from_upio(struct uart_port *p)
|
||||
}
|
||||
/* Remember loaded iotype */
|
||||
up->cur_iotype = p->iotype;
|
||||
p->handle_irq = serial8250_default_handle_irq;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -567,8 +531,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
|
||||
case UPIO_MEM:
|
||||
case UPIO_MEM32:
|
||||
case UPIO_AU:
|
||||
case UPIO_DWAPB:
|
||||
case UPIO_DWAPB32:
|
||||
p->serial_out(p, offset, value);
|
||||
p->serial_in(p, UART_LCR); /* safe, no side-effects */
|
||||
break;
|
||||
@@ -1119,6 +1081,14 @@ static void autoconfig_16550a(struct uart_8250_port *up)
|
||||
}
|
||||
serial_outp(up, UART_IER, iersave);
|
||||
|
||||
/*
|
||||
* Exar uarts have EFR in a weird location
|
||||
*/
|
||||
if (up->port.flags & UPF_EXAR_EFR) {
|
||||
up->port.type = PORT_XR17D15X;
|
||||
up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We distinguish between 16550A and U6 16550A by counting
|
||||
* how many bytes are in the FIFO.
|
||||
@@ -1621,6 +1591,29 @@ static void serial8250_handle_port(struct uart_8250_port *up)
|
||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||
}
|
||||
|
||||
int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
|
||||
{
|
||||
struct uart_8250_port *up =
|
||||
container_of(port, struct uart_8250_port, port);
|
||||
|
||||
if (!(iir & UART_IIR_NO_INT)) {
|
||||
serial8250_handle_port(up);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_handle_irq);
|
||||
|
||||
static int serial8250_default_handle_irq(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up =
|
||||
container_of(port, struct uart_8250_port, port);
|
||||
unsigned int iir = serial_in(up, UART_IIR);
|
||||
|
||||
return serial8250_handle_irq(port, iir);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the serial driver's interrupt routine.
|
||||
*
|
||||
@@ -1648,30 +1641,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
|
||||
l = i->head;
|
||||
do {
|
||||
struct uart_8250_port *up;
|
||||
unsigned int iir;
|
||||
struct uart_port *port;
|
||||
|
||||
up = list_entry(l, struct uart_8250_port, list);
|
||||
port = &up->port;
|
||||
|
||||
iir = serial_in(up, UART_IIR);
|
||||
if (!(iir & UART_IIR_NO_INT)) {
|
||||
serial8250_handle_port(up);
|
||||
|
||||
if (port->handle_irq(port)) {
|
||||
handled = 1;
|
||||
|
||||
end = NULL;
|
||||
} else if ((up->port.iotype == UPIO_DWAPB ||
|
||||
up->port.iotype == UPIO_DWAPB32) &&
|
||||
(iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
|
||||
/* The DesignWare APB UART has an Busy Detect (0x07)
|
||||
* interrupt meaning an LCR write attempt occurred while the
|
||||
* UART was busy. The interrupt must be cleared by reading
|
||||
* the UART status register (USR) and the LCR re-written. */
|
||||
unsigned int status;
|
||||
status = *(volatile u32 *)up->port.private_data;
|
||||
serial_out(up, UART_LCR, up->lcr);
|
||||
|
||||
handled = 1;
|
||||
|
||||
end = NULL;
|
||||
} else if (end == NULL)
|
||||
end = l;
|
||||
@@ -2081,8 +2057,8 @@ static int serial8250_startup(struct uart_port *port)
|
||||
*/
|
||||
if (!(up->port.flags & UPF_BUGGY_UART) &&
|
||||
(serial_inp(up, UART_LSR) == 0xff)) {
|
||||
printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
|
||||
serial_index(&up->port));
|
||||
printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
|
||||
serial_index(&up->port));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -2458,7 +2434,10 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
efr |= UART_EFR_CTS;
|
||||
|
||||
serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
serial_outp(up, UART_EFR, efr);
|
||||
if (up->port.flags & UPF_EXAR_EFR)
|
||||
serial_outp(up, UART_XR_EFR, efr);
|
||||
else
|
||||
serial_outp(up, UART_EFR, efr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP
|
||||
@@ -2570,8 +2549,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
|
||||
case UPIO_TSI:
|
||||
case UPIO_MEM32:
|
||||
case UPIO_MEM:
|
||||
case UPIO_DWAPB:
|
||||
case UPIO_DWAPB32:
|
||||
if (!up->port.mapbase)
|
||||
break;
|
||||
|
||||
@@ -2608,8 +2585,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
|
||||
case UPIO_TSI:
|
||||
case UPIO_MEM32:
|
||||
case UPIO_MEM:
|
||||
case UPIO_DWAPB:
|
||||
case UPIO_DWAPB32:
|
||||
if (!up->port.mapbase)
|
||||
break;
|
||||
|
||||
@@ -3050,6 +3025,10 @@ int __init early_serial_setup(struct uart_port *port)
|
||||
p->serial_in = port->serial_in;
|
||||
if (port->serial_out)
|
||||
p->serial_out = port->serial_out;
|
||||
if (port->handle_irq)
|
||||
p->handle_irq = port->handle_irq;
|
||||
else
|
||||
p->handle_irq = serial8250_default_handle_irq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3118,6 +3097,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
|
||||
port.type = p->type;
|
||||
port.serial_in = p->serial_in;
|
||||
port.serial_out = p->serial_out;
|
||||
port.handle_irq = p->handle_irq;
|
||||
port.set_termios = p->set_termios;
|
||||
port.pm = p->pm;
|
||||
port.dev = &dev->dev;
|
||||
@@ -3283,6 +3263,8 @@ int serial8250_register_port(struct uart_port *port)
|
||||
uart->port.serial_in = port->serial_in;
|
||||
if (port->serial_out)
|
||||
uart->port.serial_out = port->serial_out;
|
||||
if (port->handle_irq)
|
||||
uart->port.handle_irq = port->handle_irq;
|
||||
/* Possibly override set_termios call */
|
||||
if (port->set_termios)
|
||||
uart->port.set_termios = port->set_termios;
|
||||
|
194
drivers/tty/serial/8250_dw.c
Normal file
194
drivers/tty/serial/8250_dw.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Synopsys DesignWare 8250 driver.
|
||||
*
|
||||
* Copyright 2011 Picochip, Jamie Iles.
|
||||
*
|
||||
* 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, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
|
||||
* LCR is written whilst busy. If it is, then a busy detect interrupt is
|
||||
* raised, the LCR needs to be rewritten and the uart status register read.
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
struct dw8250_data {
|
||||
int last_lcr;
|
||||
int line;
|
||||
};
|
||||
|
||||
static void dw8250_serial_out(struct uart_port *p, int offset, int value)
|
||||
{
|
||||
struct dw8250_data *d = p->private_data;
|
||||
|
||||
if (offset == UART_LCR)
|
||||
d->last_lcr = value;
|
||||
|
||||
offset <<= p->regshift;
|
||||
writeb(value, p->membase + offset);
|
||||
}
|
||||
|
||||
static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
|
||||
{
|
||||
offset <<= p->regshift;
|
||||
|
||||
return readb(p->membase + offset);
|
||||
}
|
||||
|
||||
static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
|
||||
{
|
||||
struct dw8250_data *d = p->private_data;
|
||||
|
||||
if (offset == UART_LCR)
|
||||
d->last_lcr = value;
|
||||
|
||||
offset <<= p->regshift;
|
||||
writel(value, p->membase + offset);
|
||||
}
|
||||
|
||||
static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
|
||||
{
|
||||
offset <<= p->regshift;
|
||||
|
||||
return readl(p->membase + offset);
|
||||
}
|
||||
|
||||
/* Offset for the DesignWare's UART Status Register. */
|
||||
#define UART_USR 0x1f
|
||||
|
||||
static int dw8250_handle_irq(struct uart_port *p)
|
||||
{
|
||||
struct dw8250_data *d = p->private_data;
|
||||
unsigned int iir = p->serial_in(p, UART_IIR);
|
||||
|
||||
if (serial8250_handle_irq(p, iir)) {
|
||||
return 1;
|
||||
} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
|
||||
/* Clear the USR and write the LCR again. */
|
||||
(void)p->serial_in(p, UART_USR);
|
||||
p->serial_out(p, d->last_lcr, UART_LCR);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit dw8250_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct uart_port port = {};
|
||||
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
u32 val;
|
||||
struct dw8250_data *data;
|
||||
|
||||
if (!regs || !irq) {
|
||||
dev_err(&pdev->dev, "no registers/irq defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
port.private_data = data;
|
||||
|
||||
spin_lock_init(&port.lock);
|
||||
port.mapbase = regs->start;
|
||||
port.irq = irq->start;
|
||||
port.handle_irq = dw8250_handle_irq;
|
||||
port.type = PORT_8250;
|
||||
port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
|
||||
UPF_FIXED_PORT | UPF_FIXED_TYPE;
|
||||
port.dev = &pdev->dev;
|
||||
|
||||
port.iotype = UPIO_MEM;
|
||||
port.serial_in = dw8250_serial_in;
|
||||
port.serial_out = dw8250_serial_out;
|
||||
if (!of_property_read_u32(np, "reg-io-width", &val)) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
break;
|
||||
case 4:
|
||||
port.iotype = UPIO_MEM32;
|
||||
port.serial_in = dw8250_serial_in32;
|
||||
port.serial_out = dw8250_serial_out32;
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(np, "reg-shift", &val))
|
||||
port.regshift = val;
|
||||
|
||||
if (of_property_read_u32(np, "clock-frequency", &val)) {
|
||||
dev_err(&pdev->dev, "no clock-frequency property set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
port.uartclk = val;
|
||||
|
||||
data->line = serial8250_register_port(&port);
|
||||
if (data->line < 0)
|
||||
return data->line;
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit dw8250_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dw8250_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
serial8250_unregister_port(data->line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id dw8250_match[] = {
|
||||
{ .compatible = "snps,dw-apb-uart" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dw8250_match);
|
||||
|
||||
static struct platform_driver dw8250_platform_driver = {
|
||||
.driver = {
|
||||
.name = "dw-apb-uart",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = dw8250_match,
|
||||
},
|
||||
.probe = dw8250_probe,
|
||||
.remove = __devexit_p(dw8250_remove),
|
||||
};
|
||||
|
||||
static int __init dw8250_init(void)
|
||||
{
|
||||
return platform_driver_register(&dw8250_platform_driver);
|
||||
}
|
||||
module_init(dw8250_init);
|
||||
|
||||
static void __exit dw8250_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&dw8250_platform_driver);
|
||||
}
|
||||
module_exit(dw8250_exit);
|
||||
|
||||
MODULE_AUTHOR("Jamie Iles");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
|
@@ -1101,6 +1101,15 @@ static int pci_eg20t_init(struct pci_dev *dev)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pci_xr17c154_setup(struct serial_private *priv,
|
||||
const struct pciserial_board *board,
|
||||
struct uart_port *port, int idx)
|
||||
{
|
||||
port->flags |= UPF_EXAR_EFR;
|
||||
return pci_default_setup(priv, board, port, idx);
|
||||
}
|
||||
|
||||
/* This should be in linux/pci_ids.h */
|
||||
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
|
||||
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
|
||||
@@ -1505,6 +1514,30 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_timedia_setup,
|
||||
},
|
||||
/*
|
||||
* Exar cards
|
||||
*/
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_EXAR,
|
||||
.device = PCI_DEVICE_ID_EXAR_XR17C152,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_xr17c154_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_EXAR,
|
||||
.device = PCI_DEVICE_ID_EXAR_XR17C154,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_xr17c154_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_EXAR,
|
||||
.device = PCI_DEVICE_ID_EXAR_XR17C158,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_xr17c154_setup,
|
||||
},
|
||||
/*
|
||||
* Xircom cards
|
||||
*/
|
||||
@@ -1558,46 +1591,55 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8811,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8812,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8813,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8814,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8027,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8028,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8029,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x800C,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x800D,
|
||||
.init = pci_eg20t_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
/*
|
||||
* Cronyx Omega PCI (PLX-chip based)
|
||||
|
@@ -267,6 +267,13 @@ config SERIAL_8250_RM9K
|
||||
port hardware found on MIPS RM9122 and similar processors.
|
||||
If unsure, say N.
|
||||
|
||||
config SERIAL_8250_DW
|
||||
tristate "Support for Synopsys DesignWare 8250 quirks"
|
||||
depends on SERIAL_8250 && OF
|
||||
help
|
||||
Selecting this option will enable handling of the extra features
|
||||
present in the Synopsys DesignWare APB UART.
|
||||
|
||||
comment "Non-8250 serial port support"
|
||||
|
||||
config SERIAL_AMBA_PL010
|
||||
@@ -522,8 +529,8 @@ config SERIAL_S3C6400
|
||||
|
||||
config SERIAL_S5PV210
|
||||
tristate "Samsung S5PV210 Serial port support"
|
||||
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
|
||||
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
|
||||
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
|
||||
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
|
||||
default y
|
||||
help
|
||||
Serial port support for Samsung's S5P Family of SoC's
|
||||
@@ -722,7 +729,7 @@ config SERIAL_BFIN
|
||||
Add support for the built-in UARTs on the Blackfin.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bfin_5xx.
|
||||
module is named bfin_uart.ko.
|
||||
|
||||
config SERIAL_BFIN_CONSOLE
|
||||
bool "Console on Blackfin serial port"
|
||||
@@ -1035,23 +1042,6 @@ config SERIAL_MCF_CONSOLE
|
||||
help
|
||||
Enable a ColdFire internal serial port to be the system console.
|
||||
|
||||
config SERIAL_68360_SMC
|
||||
bool "68360 SMC uart support"
|
||||
depends on M68360
|
||||
help
|
||||
This driver supports the SMC serial ports of the Motorola 68360 CPU.
|
||||
|
||||
config SERIAL_68360_SCC
|
||||
bool "68360 SCC uart support"
|
||||
depends on M68360
|
||||
help
|
||||
This driver supports the SCC serial ports of the Motorola 68360 CPU.
|
||||
|
||||
config SERIAL_68360
|
||||
bool
|
||||
depends on SERIAL_68360_SMC || SERIAL_68360_SCC
|
||||
default y
|
||||
|
||||
config SERIAL_PMACZILOG
|
||||
tristate "Mac or PowerMac z85c30 ESCC support"
|
||||
depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)
|
||||
|
@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
|
||||
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
|
||||
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
|
||||
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
|
||||
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
|
||||
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
|
||||
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
|
||||
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
|
||||
@@ -35,7 +36,7 @@ obj-$(CONFIG_SERIAL_PXA) += pxa.o
|
||||
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
|
||||
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
|
||||
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
|
||||
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
|
||||
obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o
|
||||
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
|
||||
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
|
||||
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
|
||||
@@ -49,7 +50,6 @@ obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
|
||||
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
|
||||
obj-$(CONFIG_SERIAL_MUX) += mux.o
|
||||
obj-$(CONFIG_SERIAL_68328) += 68328serial.o
|
||||
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
|
||||
obj-$(CONFIG_SERIAL_MCF) += mcf.o
|
||||
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
|
||||
obj-$(CONFIG_SERIAL_DZ) += dz.o
|
||||
|
@@ -218,7 +218,7 @@ static int altera_jtaguart_startup(struct uart_port *port)
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
ret = request_irq(port->irq, altera_jtaguart_interrupt, IRQF_DISABLED,
|
||||
ret = request_irq(port->irq, altera_jtaguart_interrupt, 0,
|
||||
DRV_NAME, port);
|
||||
if (ret) {
|
||||
pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d "
|
||||
|
@@ -315,7 +315,7 @@ static int altera_uart_startup(struct uart_port *port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED,
|
||||
ret = request_irq(port->irq, altera_uart_interrupt, 0,
|
||||
DRV_NAME, port);
|
||||
if (ret) {
|
||||
pr_err(DRV_NAME ": unable to attach Altera UART %d "
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
|
@@ -33,6 +33,8 @@
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/atmel_pdc.h>
|
||||
#include <linux/atmel_serial.h>
|
||||
@@ -157,11 +159,22 @@ struct atmel_uart_port {
|
||||
};
|
||||
|
||||
static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
|
||||
static unsigned long atmel_ports_in_use;
|
||||
|
||||
#ifdef SUPPORT_SYSRQ
|
||||
static struct console atmel_console;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id atmel_serial_dt_ids[] = {
|
||||
{ .compatible = "atmel,at91rm9200-usart" },
|
||||
{ .compatible = "atmel,at91sam9260-usart" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids);
|
||||
#endif
|
||||
|
||||
static inline struct atmel_uart_port *
|
||||
to_atmel_uart_port(struct uart_port *uart)
|
||||
{
|
||||
@@ -339,7 +352,8 @@ static void atmel_stop_tx(struct uart_port *port)
|
||||
/* Disable interrupts */
|
||||
UART_PUT_IDR(port, atmel_port->tx_done_mask);
|
||||
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED)
|
||||
if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
atmel_start_rx(port);
|
||||
}
|
||||
|
||||
@@ -356,7 +370,8 @@ static void atmel_start_tx(struct uart_port *port)
|
||||
really need this.*/
|
||||
return;
|
||||
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED)
|
||||
if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
atmel_stop_rx(port);
|
||||
|
||||
/* re-enable PDC transmit */
|
||||
@@ -680,7 +695,8 @@ static void atmel_tx_dma(struct uart_port *port)
|
||||
/* Enable interrupts */
|
||||
UART_PUT_IER(port, atmel_port->tx_done_mask);
|
||||
} else {
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
|
||||
if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) {
|
||||
/* DMA done, stop TX, start RX for RS485 */
|
||||
atmel_start_rx(port);
|
||||
}
|
||||
@@ -1407,6 +1423,48 @@ static struct uart_ops atmel_pops = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
|
||||
struct device_node *np)
|
||||
{
|
||||
u32 rs485_delay[2];
|
||||
|
||||
/* DMA/PDC usage specification */
|
||||
if (of_get_property(np, "atmel,use-dma-rx", NULL))
|
||||
atmel_port->use_dma_rx = 1;
|
||||
else
|
||||
atmel_port->use_dma_rx = 0;
|
||||
if (of_get_property(np, "atmel,use-dma-tx", NULL))
|
||||
atmel_port->use_dma_tx = 1;
|
||||
else
|
||||
atmel_port->use_dma_tx = 0;
|
||||
|
||||
/* rs485 properties */
|
||||
if (of_property_read_u32_array(np, "rs485-rts-delay",
|
||||
rs485_delay, 2) == 0) {
|
||||
struct serial_rs485 *rs485conf = &atmel_port->rs485;
|
||||
|
||||
rs485conf->delay_rts_before_send = rs485_delay[0];
|
||||
rs485conf->delay_rts_after_send = rs485_delay[1];
|
||||
rs485conf->flags = 0;
|
||||
|
||||
if (rs485conf->delay_rts_before_send == 0 &&
|
||||
rs485conf->delay_rts_after_send == 0) {
|
||||
rs485conf->flags |= SER_RS485_RTS_ON_SEND;
|
||||
} else {
|
||||
if (rs485conf->delay_rts_before_send)
|
||||
rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
|
||||
if (rs485conf->delay_rts_after_send)
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
}
|
||||
|
||||
if (of_get_property(np, "rs485-rx-during-tx", NULL))
|
||||
rs485conf->flags |= SER_RS485_RX_DURING_TX;
|
||||
|
||||
if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL))
|
||||
rs485conf->flags |= SER_RS485_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the port from the platform device resource info.
|
||||
*/
|
||||
@@ -1414,13 +1472,20 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct uart_port *port = &atmel_port->uart;
|
||||
struct atmel_uart_data *data = pdev->dev.platform_data;
|
||||
struct atmel_uart_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
atmel_of_init_port(atmel_port, pdev->dev.of_node);
|
||||
} else {
|
||||
atmel_port->use_dma_rx = pdata->use_dma_rx;
|
||||
atmel_port->use_dma_tx = pdata->use_dma_tx;
|
||||
atmel_port->rs485 = pdata->rs485;
|
||||
}
|
||||
|
||||
port->iotype = UPIO_MEM;
|
||||
port->flags = UPF_BOOT_AUTOCONF;
|
||||
port->ops = &atmel_pops;
|
||||
port->fifosize = 1;
|
||||
port->line = data->num;
|
||||
port->dev = &pdev->dev;
|
||||
port->mapbase = pdev->resource[0].start;
|
||||
port->irq = pdev->resource[1].start;
|
||||
@@ -1430,10 +1495,10 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||
|
||||
memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
|
||||
|
||||
if (data->regs)
|
||||
if (pdata && pdata->regs) {
|
||||
/* Already mapped by setup code */
|
||||
port->membase = data->regs;
|
||||
else {
|
||||
port->membase = pdata->regs;
|
||||
} else {
|
||||
port->flags |= UPF_IOREMAP;
|
||||
port->membase = NULL;
|
||||
}
|
||||
@@ -1447,9 +1512,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||
/* only enable clock when USART is in use */
|
||||
}
|
||||
|
||||
atmel_port->use_dma_rx = data->use_dma_rx;
|
||||
atmel_port->use_dma_tx = data->use_dma_tx;
|
||||
atmel_port->rs485 = data->rs485;
|
||||
/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED)
|
||||
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
|
||||
@@ -1611,10 +1673,14 @@ static int __init atmel_console_init(void)
|
||||
if (atmel_default_console_device) {
|
||||
struct atmel_uart_data *pdata =
|
||||
atmel_default_console_device->dev.platform_data;
|
||||
int id = pdata->num;
|
||||
struct atmel_uart_port *port = &atmel_ports[id];
|
||||
|
||||
add_preferred_console(ATMEL_DEVICENAME, pdata->num, NULL);
|
||||
atmel_init_port(&atmel_ports[pdata->num],
|
||||
atmel_default_console_device);
|
||||
port->backup_imr = 0;
|
||||
port->uart.line = id;
|
||||
|
||||
add_preferred_console(ATMEL_DEVICENAME, id, NULL);
|
||||
atmel_init_port(port, atmel_default_console_device);
|
||||
register_console(&atmel_console);
|
||||
}
|
||||
|
||||
@@ -1711,14 +1777,39 @@ static int atmel_serial_resume(struct platform_device *pdev)
|
||||
static int __devinit atmel_serial_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct atmel_uart_port *port;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct atmel_uart_data *pdata = pdev->dev.platform_data;
|
||||
void *data;
|
||||
int ret;
|
||||
int ret = -ENODEV;
|
||||
|
||||
BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
|
||||
|
||||
port = &atmel_ports[pdata->num];
|
||||
if (np)
|
||||
ret = of_alias_get_id(np, "serial");
|
||||
else
|
||||
if (pdata)
|
||||
ret = pdata->num;
|
||||
|
||||
if (ret < 0)
|
||||
/* port id not found in platform data nor device-tree aliases:
|
||||
* auto-enumerate it */
|
||||
ret = find_first_zero_bit(&atmel_ports_in_use,
|
||||
sizeof(atmel_ports_in_use));
|
||||
|
||||
if (ret > ATMEL_MAX_UART) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(ret, &atmel_ports_in_use)) {
|
||||
/* port already in use */
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
port = &atmel_ports[ret];
|
||||
port->backup_imr = 0;
|
||||
port->uart.line = ret;
|
||||
|
||||
atmel_init_port(port, pdev);
|
||||
|
||||
@@ -1764,7 +1855,7 @@ err_alloc_ring:
|
||||
clk_put(port->clk);
|
||||
port->clk = NULL;
|
||||
}
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1784,6 +1875,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
|
||||
|
||||
/* "port" is allocated statically, so we shouldn't free it */
|
||||
|
||||
clear_bit(port->line, &atmel_ports_in_use);
|
||||
|
||||
clk_put(atmel_port->clk);
|
||||
|
||||
return ret;
|
||||
@@ -1797,6 +1890,7 @@ static struct platform_driver atmel_serial_driver = {
|
||||
.driver = {
|
||||
.name = "atmel_usart",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(atmel_serial_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -294,7 +294,7 @@ static int sport_startup(struct uart_port *port)
|
||||
if (request_irq(gpio_to_irq(up->cts_pin),
|
||||
sport_mctrl_cts_int,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) {
|
||||
0, "BFIN_SPORT_UART_CTS", up)) {
|
||||
up->cts_pin = -1;
|
||||
dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n");
|
||||
}
|
||||
|
@@ -234,8 +234,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
|
||||
status = UART_GET_LSR(uart);
|
||||
UART_CLEAR_LSR(uart);
|
||||
|
||||
ch = UART_GET_CHAR(uart);
|
||||
uart->port.icount.rx++;
|
||||
ch = UART_GET_CHAR(uart);
|
||||
uart->port.icount.rx++;
|
||||
|
||||
#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
|
||||
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
|
||||
@@ -667,17 +667,17 @@ static int bfin_serial_startup(struct uart_port *port)
|
||||
kgdboc_break_enabled = 0;
|
||||
else {
|
||||
# endif
|
||||
if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
|
||||
if (request_irq(uart->rx_irq, bfin_serial_rx_int, 0,
|
||||
"BFIN_UART_RX", uart)) {
|
||||
printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (request_irq
|
||||
(uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED,
|
||||
(uart->tx_irq, bfin_serial_tx_int, 0,
|
||||
"BFIN_UART_TX", uart)) {
|
||||
printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n");
|
||||
free_irq(uart->port.irq, uart);
|
||||
free_irq(uart->rx_irq, uart);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ static int bfin_serial_startup(struct uart_port *port)
|
||||
*/
|
||||
unsigned uart_dma_ch_rx, uart_dma_ch_tx;
|
||||
|
||||
switch (uart->port.irq) {
|
||||
switch (uart->rx_irq) {
|
||||
case IRQ_UART3_RX:
|
||||
uart_dma_ch_rx = CH_UART3_RX;
|
||||
uart_dma_ch_tx = CH_UART3_TX;
|
||||
@@ -709,16 +709,16 @@ static int bfin_serial_startup(struct uart_port *port)
|
||||
if (uart_dma_ch_rx &&
|
||||
request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) {
|
||||
printk(KERN_NOTICE"Fail to attach UART interrupt\n");
|
||||
free_irq(uart->port.irq, uart);
|
||||
free_irq(uart->port.irq + 1, uart);
|
||||
free_irq(uart->rx_irq, uart);
|
||||
free_irq(uart->tx_irq, uart);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (uart_dma_ch_tx &&
|
||||
request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) {
|
||||
printk(KERN_NOTICE "Fail to attach UART interrupt\n");
|
||||
free_dma(uart_dma_ch_rx);
|
||||
free_irq(uart->port.irq, uart);
|
||||
free_irq(uart->port.irq + 1, uart);
|
||||
free_irq(uart->rx_irq, uart);
|
||||
free_irq(uart->tx_irq, uart);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
@@ -734,19 +734,18 @@ static int bfin_serial_startup(struct uart_port *port)
|
||||
if (request_irq(gpio_to_irq(uart->cts_pin),
|
||||
bfin_serial_mctrl_cts_int,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
|
||||
0, "BFIN_UART_CTS", uart)) {
|
||||
uart->cts_pin = -1;
|
||||
pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
|
||||
}
|
||||
}
|
||||
if (uart->rts_pin >= 0) {
|
||||
if (uart->rts_pin >= 0)
|
||||
gpio_direction_output(uart->rts_pin, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
|
||||
if (uart->cts_pin >= 0 && request_irq(uart->status_irq,
|
||||
bfin_serial_mctrl_cts_int,
|
||||
IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
|
||||
0, "BFIN_UART_MODEM_STATUS", uart)) {
|
||||
uart->cts_pin = -1;
|
||||
pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n");
|
||||
}
|
||||
@@ -786,8 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port)
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
free_irq(uart->port.irq, uart);
|
||||
free_irq(uart->port.irq+1, uart);
|
||||
free_irq(uart->rx_irq, uart);
|
||||
free_irq(uart->tx_irq, uart);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
|
||||
@@ -1091,10 +1090,18 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
|
||||
*parity = 'o';
|
||||
}
|
||||
switch (lcr & 0x03) {
|
||||
case 0: *bits = 5; break;
|
||||
case 1: *bits = 6; break;
|
||||
case 2: *bits = 7; break;
|
||||
case 3: *bits = 8; break;
|
||||
case 0:
|
||||
*bits = 5;
|
||||
break;
|
||||
case 1:
|
||||
*bits = 6;
|
||||
break;
|
||||
case 2:
|
||||
*bits = 7;
|
||||
break;
|
||||
case 3:
|
||||
*bits = 8;
|
||||
break;
|
||||
}
|
||||
/* Set DLAB in LCR to Access DLL and DLH */
|
||||
UART_SET_DLAB(uart);
|
||||
@@ -1183,7 +1190,7 @@ static struct console bfin_serial_console = {
|
||||
.index = -1,
|
||||
.data = &bfin_serial_reg,
|
||||
};
|
||||
#define BFIN_SERIAL_CONSOLE &bfin_serial_console
|
||||
#define BFIN_SERIAL_CONSOLE (&bfin_serial_console)
|
||||
#else
|
||||
#define BFIN_SERIAL_CONSOLE NULL
|
||||
#endif /* CONFIG_SERIAL_BFIN_CONSOLE */
|
||||
@@ -1312,14 +1319,22 @@ static int bfin_serial_probe(struct platform_device *pdev)
|
||||
}
|
||||
uart->port.mapbase = res->start;
|
||||
|
||||
uart->port.irq = platform_get_irq(pdev, 0);
|
||||
if (uart->port.irq < 0) {
|
||||
dev_err(&pdev->dev, "No uart RX/TX IRQ specified\n");
|
||||
uart->tx_irq = platform_get_irq(pdev, 0);
|
||||
if (uart->tx_irq < 0) {
|
||||
dev_err(&pdev->dev, "No uart TX IRQ specified\n");
|
||||
ret = -ENOENT;
|
||||
goto out_error_unmap;
|
||||
}
|
||||
|
||||
uart->status_irq = platform_get_irq(pdev, 1);
|
||||
uart->rx_irq = platform_get_irq(pdev, 1);
|
||||
if (uart->rx_irq < 0) {
|
||||
dev_err(&pdev->dev, "No uart RX IRQ specified\n");
|
||||
ret = -ENOENT;
|
||||
goto out_error_unmap;
|
||||
}
|
||||
uart->port.irq = uart->rx_irq;
|
||||
|
||||
uart->status_irq = platform_get_irq(pdev, 2);
|
||||
if (uart->status_irq < 0) {
|
||||
dev_err(&pdev->dev, "No uart status IRQ specified\n");
|
||||
ret = -ENOENT;
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
|
@@ -258,7 +258,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_out_enabled = 1,
|
||||
.dma_out_nbr = SER0_TX_DMA_NBR,
|
||||
.dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR,
|
||||
.dma_out_irq_flags = IRQF_DISABLED,
|
||||
.dma_out_irq_flags = 0,
|
||||
.dma_out_irq_description = "serial 0 dma tr",
|
||||
#else
|
||||
.dma_out_enabled = 0,
|
||||
@@ -271,7 +271,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_in_enabled = 1,
|
||||
.dma_in_nbr = SER0_RX_DMA_NBR,
|
||||
.dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR,
|
||||
.dma_in_irq_flags = IRQF_DISABLED,
|
||||
.dma_in_irq_flags = 0,
|
||||
.dma_in_irq_description = "serial 0 dma rec",
|
||||
#else
|
||||
.dma_in_enabled = 0,
|
||||
@@ -313,7 +313,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_out_enabled = 1,
|
||||
.dma_out_nbr = SER1_TX_DMA_NBR,
|
||||
.dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR,
|
||||
.dma_out_irq_flags = IRQF_DISABLED,
|
||||
.dma_out_irq_flags = 0,
|
||||
.dma_out_irq_description = "serial 1 dma tr",
|
||||
#else
|
||||
.dma_out_enabled = 0,
|
||||
@@ -326,7 +326,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_in_enabled = 1,
|
||||
.dma_in_nbr = SER1_RX_DMA_NBR,
|
||||
.dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR,
|
||||
.dma_in_irq_flags = IRQF_DISABLED,
|
||||
.dma_in_irq_flags = 0,
|
||||
.dma_in_irq_description = "serial 1 dma rec",
|
||||
#else
|
||||
.dma_in_enabled = 0,
|
||||
@@ -369,7 +369,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_out_enabled = 1,
|
||||
.dma_out_nbr = SER2_TX_DMA_NBR,
|
||||
.dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR,
|
||||
.dma_out_irq_flags = IRQF_DISABLED,
|
||||
.dma_out_irq_flags = 0,
|
||||
.dma_out_irq_description = "serial 2 dma tr",
|
||||
#else
|
||||
.dma_out_enabled = 0,
|
||||
@@ -382,7 +382,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_in_enabled = 1,
|
||||
.dma_in_nbr = SER2_RX_DMA_NBR,
|
||||
.dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR,
|
||||
.dma_in_irq_flags = IRQF_DISABLED,
|
||||
.dma_in_irq_flags = 0,
|
||||
.dma_in_irq_description = "serial 2 dma rec",
|
||||
#else
|
||||
.dma_in_enabled = 0,
|
||||
@@ -423,7 +423,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_out_enabled = 1,
|
||||
.dma_out_nbr = SER3_TX_DMA_NBR,
|
||||
.dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR,
|
||||
.dma_out_irq_flags = IRQF_DISABLED,
|
||||
.dma_out_irq_flags = 0,
|
||||
.dma_out_irq_description = "serial 3 dma tr",
|
||||
#else
|
||||
.dma_out_enabled = 0,
|
||||
@@ -436,7 +436,7 @@ static struct e100_serial rs_table[] = {
|
||||
.dma_in_enabled = 1,
|
||||
.dma_in_nbr = SER3_RX_DMA_NBR,
|
||||
.dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR,
|
||||
.dma_in_irq_flags = IRQF_DISABLED,
|
||||
.dma_in_irq_flags = 0,
|
||||
.dma_in_irq_description = "serial 3 dma rec",
|
||||
#else
|
||||
.dma_in_enabled = 0,
|
||||
@@ -1788,7 +1788,7 @@ static unsigned int handle_descr_data(struct e100_serial *info,
|
||||
struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer;
|
||||
|
||||
if (info->recv_cnt + recvl > 65536) {
|
||||
printk(KERN_CRIT
|
||||
printk(KERN_WARNING
|
||||
"%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl);
|
||||
return 0;
|
||||
}
|
||||
@@ -3813,13 +3813,13 @@ rs_close(struct tty_struct *tty, struct file * filp)
|
||||
* one, we've got real problems, since it means the
|
||||
* serial port won't be shutdown.
|
||||
*/
|
||||
printk(KERN_CRIT
|
||||
printk(KERN_ERR
|
||||
"rs_close: bad serial port count; tty->count is 1, "
|
||||
"info->count is %d\n", info->count);
|
||||
info->count = 1;
|
||||
}
|
||||
if (--info->count < 0) {
|
||||
printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n",
|
||||
printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n",
|
||||
info->line, info->count);
|
||||
info->count = 0;
|
||||
}
|
||||
@@ -4452,7 +4452,7 @@ static int __init rs_init(void)
|
||||
#if defined(CONFIG_ETRAX_RS485_ON_PA)
|
||||
if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit,
|
||||
rs485_pa_bit)) {
|
||||
printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
|
||||
printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
|
||||
"RS485 pin\n");
|
||||
put_tty_driver(driver);
|
||||
return -EBUSY;
|
||||
@@ -4461,7 +4461,7 @@ static int __init rs_init(void)
|
||||
#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
|
||||
if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit,
|
||||
rs485_port_g_bit)) {
|
||||
printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
|
||||
printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
|
||||
"RS485 pin\n");
|
||||
put_tty_driver(driver);
|
||||
return -EBUSY;
|
||||
@@ -4494,7 +4494,7 @@ static int __init rs_init(void)
|
||||
if (info->enabled) {
|
||||
if (cris_request_io_interface(info->io_if,
|
||||
info->io_if_description)) {
|
||||
printk(KERN_CRIT "ETRAX100LX async serial: "
|
||||
printk(KERN_ERR "ETRAX100LX async serial: "
|
||||
"Could not allocate IO pins for "
|
||||
"%s, port %d\n",
|
||||
info->io_if_description, i);
|
||||
@@ -4558,7 +4558,7 @@ static int __init rs_init(void)
|
||||
/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
|
||||
|
||||
if (request_irq(SERIAL_IRQ_NBR, ser_interrupt,
|
||||
IRQF_SHARED | IRQF_DISABLED, "serial ", driver))
|
||||
IRQF_SHARED, "serial ", driver))
|
||||
panic("%s: Failed to request irq8", __func__);
|
||||
|
||||
#endif
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
@@ -1554,7 +1554,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
|
||||
|
||||
/* save off irq and request irq line */
|
||||
if ( (retval = request_irq(dev->irq, icom_interrupt,
|
||||
IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
|
||||
IRQF_SHARED, ICOM_DRIVER_NAME,
|
||||
(void *) icom_adapter))) {
|
||||
goto probe_exit2;
|
||||
}
|
||||
|
@@ -508,8 +508,10 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
|
||||
if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
|
||||
continue;
|
||||
|
||||
if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
|
||||
if (rx & URXD_PRERR)
|
||||
if (unlikely(rx & URXD_ERR)) {
|
||||
if (rx & URXD_BRK)
|
||||
sport->port.icount.brk++;
|
||||
else if (rx & URXD_PRERR)
|
||||
sport->port.icount.parity++;
|
||||
else if (rx & URXD_FRMERR)
|
||||
sport->port.icount.frame++;
|
||||
@@ -524,7 +526,9 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
|
||||
|
||||
rx &= sport->port.read_status_mask;
|
||||
|
||||
if (rx & URXD_PRERR)
|
||||
if (rx & URXD_BRK)
|
||||
flg = TTY_BREAK;
|
||||
else if (rx & URXD_PRERR)
|
||||
flg = TTY_PARITY;
|
||||
else if (rx & URXD_FRMERR)
|
||||
flg = TTY_FRAME;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/serial_reg.h>
|
||||
|
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serialP.h>
|
||||
#include <linux/circ_buf.h>
|
||||
|
@@ -88,7 +88,6 @@ enum {
|
||||
|
||||
/* 4 extra for alignment play space */
|
||||
#define WRITEBUFLEN ((4096) + 4)
|
||||
#define MYFLIPLEN N_TTY_BUF_SIZE
|
||||
|
||||
#define JSM_VERSION "jsm: 1.2-1-INKERNEL"
|
||||
#define JSM_PARTNUM "40002438_A-INKERNEL"
|
||||
@@ -150,7 +149,6 @@ struct jsm_board
|
||||
u32 bd_uart_offset; /* Space between each UART */
|
||||
|
||||
struct jsm_channel *channels[MAXPORTS]; /* array of pointers to our channels. */
|
||||
char *flipbuf; /* Our flip buffer, alloced if board is found */
|
||||
|
||||
u32 bd_dividend; /* Board/UARTs specific dividend */
|
||||
|
||||
@@ -177,16 +175,13 @@ struct jsm_board
|
||||
#define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */
|
||||
#define CH_BREAK_SENDING 0x1000 /* Break is being sent */
|
||||
#define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */
|
||||
#define CH_FLIPBUF_IN_USE 0x4000 /* Channel's flipbuf is in use */
|
||||
#define CH_BAUD0 0x08000 /* Used for checking B0 transitions */
|
||||
|
||||
/* Our Read/Error/Write queue sizes */
|
||||
#define RQUEUEMASK 0x1FFF /* 8 K - 1 */
|
||||
#define EQUEUEMASK 0x1FFF /* 8 K - 1 */
|
||||
#define WQUEUEMASK 0x0FFF /* 4 K - 1 */
|
||||
#define RQUEUESIZE (RQUEUEMASK + 1)
|
||||
#define EQUEUESIZE RQUEUESIZE
|
||||
#define WQUEUESIZE (WQUEUEMASK + 1)
|
||||
|
||||
|
||||
/************************************************************************
|
||||
@@ -226,10 +221,6 @@ struct jsm_channel {
|
||||
u16 ch_e_head; /* Head location of the error queue */
|
||||
u16 ch_e_tail; /* Tail location of the error queue */
|
||||
|
||||
u8 *ch_wqueue; /* Our write queue buffer - malloc'ed */
|
||||
u16 ch_w_head; /* Head location of the write queue */
|
||||
u16 ch_w_tail; /* Tail location of the write queue */
|
||||
|
||||
u64 ch_rxcount; /* total of data received so far */
|
||||
u64 ch_txcount; /* total of data transmitted so far */
|
||||
|
||||
@@ -378,7 +369,6 @@ extern int jsm_debug;
|
||||
* Prototypes for non-static functions used in more than one module
|
||||
*
|
||||
*************************************************************************/
|
||||
int jsm_tty_write(struct uart_port *port);
|
||||
int jsm_tty_init(struct jsm_board *);
|
||||
int jsm_uart_port_init(struct jsm_board *);
|
||||
int jsm_remove_uart_port(struct jsm_board *);
|
||||
|
@@ -160,27 +160,10 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
|
||||
dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n",
|
||||
adapter_count, brd->rev, brd->irq);
|
||||
|
||||
/*
|
||||
* allocate flip buffer for board.
|
||||
*
|
||||
* Okay to malloc with GFP_KERNEL, we are not at interrupt
|
||||
* context, and there are no locks held.
|
||||
*/
|
||||
brd->flipbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
|
||||
if (!brd->flipbuf) {
|
||||
/* XXX: leaking all resources from jsm_tty_init and
|
||||
jsm_uart_port_init here! */
|
||||
dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
|
||||
rc = -ENOMEM;
|
||||
goto out_free_uart;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, brd);
|
||||
pci_save_state(pdev);
|
||||
|
||||
return 0;
|
||||
out_free_uart:
|
||||
jsm_remove_uart_port(brd);
|
||||
out_free_irq:
|
||||
jsm_remove_uart_port(brd);
|
||||
free_irq(brd->irq, brd);
|
||||
@@ -211,14 +194,12 @@ static void __devexit jsm_remove_one(struct pci_dev *pdev)
|
||||
if (brd->channels[i]) {
|
||||
kfree(brd->channels[i]->ch_rqueue);
|
||||
kfree(brd->channels[i]->ch_equeue);
|
||||
kfree(brd->channels[i]->ch_wqueue);
|
||||
kfree(brd->channels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
kfree(brd->flipbuf);
|
||||
kfree(brd);
|
||||
}
|
||||
|
||||
|
@@ -496,12 +496,15 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
|
||||
int s;
|
||||
int qlen;
|
||||
u32 len_written = 0;
|
||||
struct circ_buf *circ;
|
||||
|
||||
if (!ch)
|
||||
return;
|
||||
|
||||
circ = &ch->uart_port.state->xmit;
|
||||
|
||||
/* No data to write to the UART */
|
||||
if (ch->ch_w_tail == ch->ch_w_head)
|
||||
if (uart_circ_empty(circ))
|
||||
return;
|
||||
|
||||
/* If port is "stopped", don't send any data to the UART */
|
||||
@@ -517,11 +520,10 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
|
||||
if (ch->ch_cached_lsr & UART_LSR_THRE) {
|
||||
ch->ch_cached_lsr &= ~(UART_LSR_THRE);
|
||||
|
||||
writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx);
|
||||
writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
|
||||
jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev,
|
||||
"Tx data: %x\n", ch->ch_wqueue[ch->ch_w_head]);
|
||||
ch->ch_w_tail++;
|
||||
ch->ch_w_tail &= WQUEUEMASK;
|
||||
"Tx data: %x\n", circ->buf[circ->tail]);
|
||||
circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
ch->ch_txcount++;
|
||||
}
|
||||
return;
|
||||
@@ -536,36 +538,36 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
|
||||
n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
|
||||
|
||||
/* cache head and tail of queue */
|
||||
head = ch->ch_w_head & WQUEUEMASK;
|
||||
tail = ch->ch_w_tail & WQUEUEMASK;
|
||||
qlen = (head - tail) & WQUEUEMASK;
|
||||
head = circ->head & (UART_XMIT_SIZE - 1);
|
||||
tail = circ->tail & (UART_XMIT_SIZE - 1);
|
||||
qlen = uart_circ_chars_pending(circ);
|
||||
|
||||
/* Find minimum of the FIFO space, versus queue length */
|
||||
n = min(n, qlen);
|
||||
|
||||
while (n > 0) {
|
||||
|
||||
s = ((head >= tail) ? head : WQUEUESIZE) - tail;
|
||||
s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail;
|
||||
s = min(s, n);
|
||||
|
||||
if (s <= 0)
|
||||
break;
|
||||
|
||||
memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s);
|
||||
memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s);
|
||||
/* Add and flip queue if needed */
|
||||
tail = (tail + s) & WQUEUEMASK;
|
||||
tail = (tail + s) & (UART_XMIT_SIZE - 1);
|
||||
n -= s;
|
||||
ch->ch_txcount += s;
|
||||
len_written += s;
|
||||
}
|
||||
|
||||
/* Update the final tail */
|
||||
ch->ch_w_tail = tail & WQUEUEMASK;
|
||||
circ->tail = tail & (UART_XMIT_SIZE - 1);
|
||||
|
||||
if (len_written >= ch->ch_t_tlevel)
|
||||
ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
|
||||
|
||||
if (!jsm_tty_write(&ch->uart_port))
|
||||
if (uart_circ_empty(circ))
|
||||
uart_write_wakeup(&ch->uart_port);
|
||||
}
|
||||
|
||||
@@ -946,7 +948,6 @@ static void neo_param(struct jsm_channel *ch)
|
||||
if ((ch->ch_c_cflag & (CBAUD)) == 0) {
|
||||
ch->ch_r_head = ch->ch_r_tail = 0;
|
||||
ch->ch_e_head = ch->ch_e_tail = 0;
|
||||
ch->ch_w_head = ch->ch_w_tail = 0;
|
||||
|
||||
neo_flush_uart_write(ch);
|
||||
neo_flush_uart_read(ch);
|
||||
|
@@ -118,6 +118,19 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* jsm_tty_write()
|
||||
*
|
||||
* Take data from the user or kernel and send it out to the FEP.
|
||||
* In here exists all the Transparent Print magic as well.
|
||||
*/
|
||||
static void jsm_tty_write(struct uart_port *port)
|
||||
{
|
||||
struct jsm_channel *channel;
|
||||
channel = container_of(port, struct jsm_channel, uart_port);
|
||||
channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel);
|
||||
}
|
||||
|
||||
static void jsm_tty_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct jsm_channel *channel = (struct jsm_channel *)port;
|
||||
@@ -216,14 +229,6 @@ static int jsm_tty_open(struct uart_port *port)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (!channel->ch_wqueue) {
|
||||
channel->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);
|
||||
if (!channel->ch_wqueue) {
|
||||
jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
|
||||
"unable to allocate write queue buf");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
channel->ch_flags &= ~(CH_OPENING);
|
||||
/*
|
||||
@@ -237,7 +242,6 @@ static int jsm_tty_open(struct uart_port *port)
|
||||
*/
|
||||
channel->ch_r_head = channel->ch_r_tail = 0;
|
||||
channel->ch_e_head = channel->ch_e_tail = 0;
|
||||
channel->ch_w_head = channel->ch_w_tail = 0;
|
||||
|
||||
brd->bd_ops->flush_uart_write(channel);
|
||||
brd->bd_ops->flush_uart_read(channel);
|
||||
@@ -836,75 +840,3 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* jsm_tty_write()
|
||||
*
|
||||
* Take data from the user or kernel and send it out to the FEP.
|
||||
* In here exists all the Transparent Print magic as well.
|
||||
*/
|
||||
int jsm_tty_write(struct uart_port *port)
|
||||
{
|
||||
int bufcount;
|
||||
int data_count = 0,data_count1 =0;
|
||||
u16 head;
|
||||
u16 tail;
|
||||
u16 tmask;
|
||||
u32 remain;
|
||||
int temp_tail = port->state->xmit.tail;
|
||||
struct jsm_channel *channel = (struct jsm_channel *)port;
|
||||
|
||||
tmask = WQUEUEMASK;
|
||||
head = (channel->ch_w_head) & tmask;
|
||||
tail = (channel->ch_w_tail) & tmask;
|
||||
|
||||
if ((bufcount = tail - head - 1) < 0)
|
||||
bufcount += WQUEUESIZE;
|
||||
|
||||
bufcount = min(bufcount, 56);
|
||||
remain = WQUEUESIZE - head;
|
||||
|
||||
data_count = 0;
|
||||
if (bufcount >= remain) {
|
||||
bufcount -= remain;
|
||||
while ((port->state->xmit.head != temp_tail) &&
|
||||
(data_count < remain)) {
|
||||
channel->ch_wqueue[head++] =
|
||||
port->state->xmit.buf[temp_tail];
|
||||
|
||||
temp_tail++;
|
||||
temp_tail &= (UART_XMIT_SIZE - 1);
|
||||
data_count++;
|
||||
}
|
||||
if (data_count == remain) head = 0;
|
||||
}
|
||||
|
||||
data_count1 = 0;
|
||||
if (bufcount > 0) {
|
||||
remain = bufcount;
|
||||
while ((port->state->xmit.head != temp_tail) &&
|
||||
(data_count1 < remain)) {
|
||||
channel->ch_wqueue[head++] =
|
||||
port->state->xmit.buf[temp_tail];
|
||||
|
||||
temp_tail++;
|
||||
temp_tail &= (UART_XMIT_SIZE - 1);
|
||||
data_count1++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
port->state->xmit.tail = temp_tail;
|
||||
|
||||
data_count += data_count1;
|
||||
if (data_count) {
|
||||
head &= tmask;
|
||||
channel->ch_w_head = head;
|
||||
}
|
||||
|
||||
if (data_count) {
|
||||
channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel);
|
||||
}
|
||||
|
||||
return data_count;
|
||||
}
|
||||
|
@@ -338,21 +338,21 @@ lqasc_startup(struct uart_port *port)
|
||||
ASCCON_ROEN, port->membase + LTQ_ASC_CON);
|
||||
|
||||
retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
|
||||
IRQF_DISABLED, "asc_tx", port);
|
||||
0, "asc_tx", port);
|
||||
if (retval) {
|
||||
pr_err("failed to request lqasc_tx_int\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = request_irq(ltq_port->rx_irq, lqasc_rx_int,
|
||||
IRQF_DISABLED, "asc_rx", port);
|
||||
0, "asc_rx", port);
|
||||
if (retval) {
|
||||
pr_err("failed to request lqasc_rx_int\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
retval = request_irq(ltq_port->err_irq, lqasc_err_int,
|
||||
IRQF_DISABLED, "asc_err", port);
|
||||
0, "asc_err", port);
|
||||
if (retval) {
|
||||
pr_err("failed to request lqasc_err_int\n");
|
||||
goto err2;
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
|
@@ -47,6 +47,8 @@
|
||||
#include <linux/serial.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
|
||||
#include <linux/serial_max3100.h>
|
||||
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/freezer.h>
|
||||
|
@@ -380,7 +380,7 @@ static void mcf_config_port(struct uart_port *port, int flags)
|
||||
/* Clear mask, so no surprise interrupts. */
|
||||
writeb(0, port->membase + MCFUART_UIMR);
|
||||
|
||||
if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port))
|
||||
if (request_irq(port->irq, mcf_interrupt, 0, "UART", port))
|
||||
printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
|
||||
"interrupt vector=%d\n", port->line, port->irq);
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#define HSU_DMA_BUF_SIZE 2048
|
||||
|
||||
@@ -764,6 +765,8 @@ static int serial_hsu_startup(struct uart_port *port)
|
||||
container_of(port, struct uart_hsu_port, port);
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(up->dev);
|
||||
|
||||
/*
|
||||
* Clear the FIFO buffers and disable them.
|
||||
* (they will be reenabled in set_termios())
|
||||
@@ -871,6 +874,8 @@ static void serial_hsu_shutdown(struct uart_port *port)
|
||||
UART_FCR_CLEAR_RCVR |
|
||||
UART_FCR_CLEAR_XMIT);
|
||||
serial_out(up, UART_FCR, 0);
|
||||
|
||||
pm_runtime_put(up->dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1249,6 +1254,39 @@ static int serial_hsu_resume(struct pci_dev *pdev)
|
||||
#define serial_hsu_resume NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
static int serial_hsu_runtime_idle(struct device *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pm_schedule_suspend(dev, 500);
|
||||
if (err)
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_hsu_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_hsu_runtime_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define serial_hsu_runtime_idle NULL
|
||||
#define serial_hsu_runtime_suspend NULL
|
||||
#define serial_hsu_runtime_resume NULL
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops serial_hsu_pm_ops = {
|
||||
.runtime_suspend = serial_hsu_runtime_suspend,
|
||||
.runtime_resume = serial_hsu_runtime_resume,
|
||||
.runtime_idle = serial_hsu_runtime_idle,
|
||||
};
|
||||
|
||||
/* temp global pointer before we settle down on using one or four PCI dev */
|
||||
static struct hsu_port *phsu;
|
||||
|
||||
@@ -1315,6 +1353,9 @@ static int serial_hsu_probe(struct pci_dev *pdev,
|
||||
pci_set_drvdata(pdev, uport);
|
||||
}
|
||||
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
@@ -1411,6 +1452,9 @@ static void serial_hsu_remove(struct pci_dev *pdev)
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
pm_runtime_forbid(&pdev->dev);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
/* For port 0/1/2, priv is the address of uart_hsu_port */
|
||||
if (pdev->device != 0x081E) {
|
||||
up = priv;
|
||||
@@ -1423,7 +1467,7 @@ static void serial_hsu_remove(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
/* First 3 are UART ports, and the 4th is the DMA */
|
||||
static const struct pci_device_id pci_ids[] __devinitdata = {
|
||||
static const struct pci_device_id pci_ids[] __devinitconst = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) },
|
||||
@@ -1438,6 +1482,9 @@ static struct pci_driver hsu_pci_driver = {
|
||||
.remove = __devexit_p(serial_hsu_remove),
|
||||
.suspend = serial_hsu_suspend,
|
||||
.resume = serial_hsu_resume,
|
||||
.driver = {
|
||||
.pm = &serial_hsu_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init hsu_pci_init(void)
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/console.h>
|
||||
@@ -273,7 +274,7 @@ static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port,
|
||||
|
||||
static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np)
|
||||
{
|
||||
port->irqflags = IRQF_DISABLED;
|
||||
port->irqflags = 0;
|
||||
port->irq = irq_of_parse_and_map(np, 0);
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,10 @@
|
||||
* interrupt for a low speed UART device
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
#define SUPPORT_SYSRQ
|
||||
#endif
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/irq.h>
|
||||
@@ -73,9 +77,9 @@ struct uart_max3110 {
|
||||
/* global data structure, may need be removed */
|
||||
static struct uart_max3110 *pmax;
|
||||
|
||||
static void receive_chars(struct uart_max3110 *max,
|
||||
unsigned char *str, int len);
|
||||
static int max3110_read_multi(struct uart_max3110 *max, u8 *buf);
|
||||
static int receive_chars(struct uart_max3110 *max,
|
||||
unsigned short *str, int len);
|
||||
static int max3110_read_multi(struct uart_max3110 *max);
|
||||
static void max3110_con_receive(struct uart_max3110 *max);
|
||||
|
||||
static int max3110_write_then_read(struct uart_max3110 *max,
|
||||
@@ -108,7 +112,6 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
|
||||
{
|
||||
void *buf;
|
||||
u16 *obuf, *ibuf;
|
||||
u8 ch;
|
||||
int ret;
|
||||
|
||||
buf = kzalloc(8, GFP_KERNEL | GFP_DMA);
|
||||
@@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* If some valid data is read back */
|
||||
if (*ibuf & MAX3110_READ_DATA_AVAILABLE) {
|
||||
ch = *ibuf & 0xff;
|
||||
receive_chars(max, &ch, 1);
|
||||
}
|
||||
receive_chars(max, ibuf, 1);
|
||||
|
||||
exit:
|
||||
kfree(buf);
|
||||
@@ -142,12 +141,11 @@ exit:
|
||||
*
|
||||
* Return how many valide bytes are read back
|
||||
*/
|
||||
static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf)
|
||||
static int max3110_read_multi(struct uart_max3110 *max)
|
||||
{
|
||||
void *buf;
|
||||
u16 *obuf, *ibuf;
|
||||
u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH];
|
||||
int i, j, blen;
|
||||
int ret, blen;
|
||||
|
||||
blen = M3110_RX_FIFO_DEPTH * sizeof(u16);
|
||||
buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA);
|
||||
@@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If caller doesn't provide a buffer, then handle received char */
|
||||
pbuf = rxbuf ? rxbuf : valid_str;
|
||||
|
||||
for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) {
|
||||
if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
|
||||
pbuf[j++] = ibuf[i] & 0xff;
|
||||
}
|
||||
|
||||
if (j && (pbuf == valid_str))
|
||||
receive_chars(max, valid_str, j);
|
||||
ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH);
|
||||
|
||||
kfree(buf);
|
||||
return j;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void serial_m3110_con_putchar(struct uart_port *port, int ch)
|
||||
@@ -207,7 +196,7 @@ static void serial_m3110_con_write(struct console *co,
|
||||
uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar);
|
||||
|
||||
if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags))
|
||||
wake_up_process(pmax->main_thread);
|
||||
wake_up(&pmax->wq);
|
||||
}
|
||||
|
||||
static int __init
|
||||
@@ -276,8 +265,7 @@ static void send_circ_buf(struct uart_max3110 *max,
|
||||
{
|
||||
void *buf;
|
||||
u16 *obuf, *ibuf;
|
||||
u8 valid_str[WORDS_PER_XFER];
|
||||
int i, j, len, blen, dma_size, left, ret = 0;
|
||||
int i, len, blen, dma_size, left, ret = 0;
|
||||
|
||||
|
||||
dma_size = WORDS_PER_XFER * sizeof(u16) * 2;
|
||||
@@ -301,18 +289,13 @@ static void send_circ_buf(struct uart_max3110 *max,
|
||||
}
|
||||
|
||||
/* Fail to send msg to console is not very critical */
|
||||
|
||||
ret = max3110_write_then_read(max, obuf, ibuf, blen, 0);
|
||||
if (ret)
|
||||
pr_warning(PR_FMT "%s(): get err msg %d\n",
|
||||
__func__, ret);
|
||||
|
||||
for (i = 0, j = 0; i < len; i++) {
|
||||
if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
|
||||
valid_str[j++] = ibuf[i] & 0xff;
|
||||
}
|
||||
|
||||
if (j)
|
||||
receive_chars(max, valid_str, j);
|
||||
receive_chars(max, ibuf, len);
|
||||
|
||||
max->port.icount.tx += len;
|
||||
left -= len;
|
||||
@@ -349,33 +332,54 @@ static void serial_m3110_start_tx(struct uart_port *port)
|
||||
container_of(port, struct uart_max3110, port);
|
||||
|
||||
if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags))
|
||||
wake_up_process(max->main_thread);
|
||||
wake_up(&max->wq);
|
||||
}
|
||||
|
||||
static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
|
||||
static int
|
||||
receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
|
||||
{
|
||||
struct uart_port *port = &max->port;
|
||||
struct tty_struct *tty;
|
||||
int usable;
|
||||
char buf[M3110_RX_FIFO_DEPTH];
|
||||
int r, w, usable;
|
||||
|
||||
/* If uart is not opened, just return */
|
||||
if (!port->state)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
tty = port->state->port.tty;
|
||||
tty = tty_port_tty_get(&port->state->port);
|
||||
if (!tty)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
while (len) {
|
||||
usable = tty_buffer_request_room(tty, len);
|
||||
for (r = 0, w = 0; r < len; r++) {
|
||||
if (str[r] & MAX3110_BREAK &&
|
||||
uart_handle_break(port))
|
||||
continue;
|
||||
|
||||
if (str[r] & MAX3110_READ_DATA_AVAILABLE) {
|
||||
if (uart_handle_sysrq_char(port, str[r] & 0xff))
|
||||
continue;
|
||||
|
||||
buf[w++] = str[r] & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if (!w) {
|
||||
tty_kref_put(tty);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (r = 0; w; r += usable, w -= usable) {
|
||||
usable = tty_buffer_request_room(tty, w);
|
||||
if (usable) {
|
||||
tty_insert_flip_string(tty, str, usable);
|
||||
str += usable;
|
||||
tty_insert_flip_string(tty, buf + r, usable);
|
||||
port->icount.rx += usable;
|
||||
}
|
||||
len -= usable;
|
||||
}
|
||||
tty_flip_buffer_push(tty);
|
||||
tty_kref_put(tty);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -390,28 +394,15 @@ static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
|
||||
*/
|
||||
static void max3110_con_receive(struct uart_max3110 *max)
|
||||
{
|
||||
int loop = 1, num, total = 0;
|
||||
u8 recv_buf[512], *pbuf;
|
||||
int loop = 1, num;
|
||||
|
||||
pbuf = recv_buf;
|
||||
do {
|
||||
num = max3110_read_multi(max, pbuf);
|
||||
num = max3110_read_multi(max);
|
||||
|
||||
if (num) {
|
||||
loop = 5;
|
||||
pbuf += num;
|
||||
total += num;
|
||||
|
||||
if (total >= 504) {
|
||||
receive_chars(max, recv_buf, total);
|
||||
pbuf = recv_buf;
|
||||
total = 0;
|
||||
}
|
||||
}
|
||||
} while (--loop);
|
||||
|
||||
if (total)
|
||||
receive_chars(max, recv_buf, total);
|
||||
}
|
||||
|
||||
static int max3110_main_thread(void *_max)
|
||||
@@ -424,7 +415,8 @@ static int max3110_main_thread(void *_max)
|
||||
pr_info(PR_FMT "start main thread\n");
|
||||
|
||||
do {
|
||||
wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop());
|
||||
wait_event_interruptible(*wq,
|
||||
max->uart_flags || kthread_should_stop());
|
||||
|
||||
mutex_lock(&max->thread_mutex);
|
||||
|
||||
@@ -452,8 +444,9 @@ static irqreturn_t serial_m3110_irq(int irq, void *dev_id)
|
||||
|
||||
/* max3110's irq is a falling edge, not level triggered,
|
||||
* so no need to disable the irq */
|
||||
|
||||
if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags))
|
||||
wake_up_process(max->main_thread);
|
||||
wake_up(&max->wq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
/* status bits for all 4 MAX3110 operate modes */
|
||||
#define MAX3110_READ_DATA_AVAILABLE (1 << 15)
|
||||
#define MAX3110_WRITE_BUF_EMPTY (1 << 14)
|
||||
#define MAX3110_BREAK (1 << 10)
|
||||
|
||||
#define WC_TAG (3 << 14)
|
||||
#define RC_TAG (1 << 14)
|
||||
|
@@ -804,8 +804,6 @@ static int __init msm_console_setup(struct console *co, char *options)
|
||||
if (unlikely(!port->membase))
|
||||
return -ENXIO;
|
||||
|
||||
port->cons = co;
|
||||
|
||||
msm_init_clock(port);
|
||||
|
||||
if (options)
|
||||
|
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h> /* for udelay */
|
||||
#include <linux/device.h>
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dmi.h>
|
||||
|
@@ -100,6 +100,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
|
||||
int max_count = 256;
|
||||
|
||||
do {
|
||||
/* work around Errata #20 according to
|
||||
* Intel(R) PXA27x Processor Family
|
||||
* Specification Update (May 2005)
|
||||
*
|
||||
* Step 2
|
||||
* Disable the Reciever Time Out Interrupt via IER[RTOEI]
|
||||
*/
|
||||
up->ier &= ~UART_IER_RTOIE;
|
||||
serial_out(up, UART_IER, up->ier);
|
||||
|
||||
ch = serial_in(up, UART_RX);
|
||||
flag = TTY_NORMAL;
|
||||
up->port.icount.rx++;
|
||||
@@ -156,6 +166,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
|
||||
*status = serial_in(up, UART_LSR);
|
||||
} while ((*status & UART_LSR_DR) && (max_count-- > 0));
|
||||
tty_flip_buffer_push(tty);
|
||||
|
||||
/* work around Errata #20 according to
|
||||
* Intel(R) PXA27x Processor Family
|
||||
* Specification Update (May 2005)
|
||||
*
|
||||
* Step 6:
|
||||
* No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE]
|
||||
*/
|
||||
up->ier |= UART_IER_RTOIE;
|
||||
serial_out(up, UART_IER, up->ier);
|
||||
}
|
||||
|
||||
static void transmit_chars(struct uart_pxa_port *up)
|
||||
|
@@ -83,6 +83,16 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
|
||||
return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
|
||||
}
|
||||
|
||||
/*
|
||||
* s3c64xx and later SoC's include the interrupt mask and status registers in
|
||||
* the controller itself, unlike the s3c24xx SoC's which have these registers
|
||||
* in the interrupt controller. Check if the port type is s3c64xx or higher.
|
||||
*/
|
||||
static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
|
||||
{
|
||||
return to_ourport(port)->info->type == PORT_S3C6400;
|
||||
}
|
||||
|
||||
static void s3c24xx_serial_rx_enable(struct uart_port *port)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -126,7 +136,11 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
if (tx_enabled(port)) {
|
||||
disable_irq_nosync(ourport->tx_irq);
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
__set_bit(S3C64XX_UINTM_TXD,
|
||||
portaddrl(port, S3C64XX_UINTM));
|
||||
else
|
||||
disable_irq_nosync(ourport->tx_irq);
|
||||
tx_enabled(port) = 0;
|
||||
if (port->flags & UPF_CONS_FLOW)
|
||||
s3c24xx_serial_rx_enable(port);
|
||||
@@ -141,19 +155,26 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
|
||||
if (port->flags & UPF_CONS_FLOW)
|
||||
s3c24xx_serial_rx_disable(port);
|
||||
|
||||
enable_irq(ourport->tx_irq);
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
__clear_bit(S3C64XX_UINTM_TXD,
|
||||
portaddrl(port, S3C64XX_UINTM));
|
||||
else
|
||||
enable_irq(ourport->tx_irq);
|
||||
tx_enabled(port) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void s3c24xx_serial_stop_rx(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
if (rx_enabled(port)) {
|
||||
dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
|
||||
disable_irq_nosync(ourport->rx_irq);
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
__set_bit(S3C64XX_UINTM_RXD,
|
||||
portaddrl(port, S3C64XX_UINTM));
|
||||
else
|
||||
disable_irq_nosync(ourport->rx_irq);
|
||||
rx_enabled(port) = 0;
|
||||
}
|
||||
}
|
||||
@@ -320,6 +341,28 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* interrupt handler for s3c64xx and later SoC's.*/
|
||||
static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = id;
|
||||
struct uart_port *port = &ourport->port;
|
||||
unsigned int pend = rd_regl(port, S3C64XX_UINTP);
|
||||
unsigned long flags;
|
||||
irqreturn_t ret = IRQ_HANDLED;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (pend & S3C64XX_UINTM_RXD_MSK) {
|
||||
ret = s3c24xx_serial_rx_chars(irq, id);
|
||||
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
|
||||
}
|
||||
if (pend & S3C64XX_UINTM_TXD_MSK) {
|
||||
ret = s3c24xx_serial_tx_chars(irq, id);
|
||||
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
|
||||
@@ -377,18 +420,25 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
if (ourport->tx_claimed) {
|
||||
free_irq(ourport->tx_irq, ourport);
|
||||
if (!s3c24xx_serial_has_interrupt_mask(port))
|
||||
free_irq(ourport->tx_irq, ourport);
|
||||
tx_enabled(port) = 0;
|
||||
ourport->tx_claimed = 0;
|
||||
}
|
||||
|
||||
if (ourport->rx_claimed) {
|
||||
free_irq(ourport->rx_irq, ourport);
|
||||
if (!s3c24xx_serial_has_interrupt_mask(port))
|
||||
free_irq(ourport->rx_irq, ourport);
|
||||
ourport->rx_claimed = 0;
|
||||
rx_enabled(port) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear pending interrupts and mask all interrupts */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
wr_regl(port, S3C64XX_UINTP, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTM, 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
static int s3c24xx_serial_startup(struct uart_port *port)
|
||||
{
|
||||
@@ -436,6 +486,33 @@ static int s3c24xx_serial_startup(struct uart_port *port)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s3c64xx_serial_startup(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
int ret;
|
||||
|
||||
dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n",
|
||||
port->mapbase, port->membase);
|
||||
|
||||
ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED,
|
||||
s3c24xx_serial_portname(port), ourport);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "cannot get irq %d\n", port->irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For compatibility with s3c24xx Soc's */
|
||||
rx_enabled(port) = 1;
|
||||
ourport->rx_claimed = 1;
|
||||
tx_enabled(port) = 0;
|
||||
ourport->tx_claimed = 1;
|
||||
|
||||
/* Enable Rx Interrupt */
|
||||
__clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM));
|
||||
dbg("s3c64xx_serial_startup ok\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power power management control */
|
||||
|
||||
static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
|
||||
@@ -879,7 +956,6 @@ static struct uart_ops s3c24xx_serial_ops = {
|
||||
.verify_port = s3c24xx_serial_verify_port,
|
||||
};
|
||||
|
||||
|
||||
static struct uart_driver s3c24xx_uart_drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_name = "s3c2410_serial",
|
||||
@@ -895,7 +971,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
|
||||
.port = {
|
||||
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
|
||||
.iotype = UPIO_MEM,
|
||||
.irq = IRQ_S3CUART_RX0,
|
||||
.uartclk = 0,
|
||||
.fifosize = 16,
|
||||
.ops = &s3c24xx_serial_ops,
|
||||
@@ -907,7 +982,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
|
||||
.port = {
|
||||
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
|
||||
.iotype = UPIO_MEM,
|
||||
.irq = IRQ_S3CUART_RX1,
|
||||
.uartclk = 0,
|
||||
.fifosize = 16,
|
||||
.ops = &s3c24xx_serial_ops,
|
||||
@@ -921,7 +995,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
|
||||
.port = {
|
||||
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
|
||||
.iotype = UPIO_MEM,
|
||||
.irq = IRQ_S3CUART_RX2,
|
||||
.uartclk = 0,
|
||||
.fifosize = 16,
|
||||
.ops = &s3c24xx_serial_ops,
|
||||
@@ -935,7 +1008,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
|
||||
.port = {
|
||||
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),
|
||||
.iotype = UPIO_MEM,
|
||||
.irq = IRQ_S3CUART_RX3,
|
||||
.uartclk = 0,
|
||||
.fifosize = 16,
|
||||
.ops = &s3c24xx_serial_ops,
|
||||
@@ -1077,6 +1149,10 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
port->dev = &platdev->dev;
|
||||
ourport->info = info;
|
||||
|
||||
/* Startup sequence is different for s3c64xx and higher SoC's */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
|
||||
|
||||
/* copy the info in from provided structure */
|
||||
ourport->port.fifosize = info->fifosize;
|
||||
|
||||
@@ -1116,6 +1192,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
|
||||
ourport->clk = clk_get(&platdev->dev, "uart");
|
||||
|
||||
/* Keep all interrupts masked and cleared */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
wr_regl(port, S3C64XX_UINTM, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTP, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTSP, 0xf);
|
||||
}
|
||||
|
||||
dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
|
||||
port->mapbase, port->membase, port->irq,
|
||||
ourport->rx_irq, ourport->tx_irq, port->uartclk);
|
||||
|
@@ -61,6 +61,7 @@ struct s3c24xx_uart_port {
|
||||
/* register access controls */
|
||||
|
||||
#define portaddr(port, reg) ((port)->membase + (reg))
|
||||
#define portaddrl(port, reg) ((unsigned long *)((port)->membase + (reg)))
|
||||
|
||||
#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
|
||||
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
@@ -57,7 +57,7 @@ static struct lock_class_key port_lock_key;
|
||||
|
||||
static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
|
||||
struct ktermios *old_termios);
|
||||
static void __uart_wait_until_sent(struct uart_port *port, int timeout);
|
||||
static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
|
||||
static void uart_change_pm(struct uart_state *state, int pm_state);
|
||||
|
||||
/*
|
||||
@@ -72,7 +72,7 @@ void uart_write_wakeup(struct uart_port *port)
|
||||
* closed. No cookie for you.
|
||||
*/
|
||||
BUG_ON(!state);
|
||||
tasklet_schedule(&state->tlet);
|
||||
tty_wakeup(state->port.tty);
|
||||
}
|
||||
|
||||
static void uart_stop(struct tty_struct *tty)
|
||||
@@ -107,12 +107,6 @@ static void uart_start(struct tty_struct *tty)
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static void uart_tasklet_action(unsigned long data)
|
||||
{
|
||||
struct uart_state *state = (struct uart_state *)data;
|
||||
tty_wakeup(state->port.tty);
|
||||
}
|
||||
|
||||
static inline void
|
||||
uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
|
||||
{
|
||||
@@ -255,9 +249,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
|
||||
}
|
||||
|
||||
/*
|
||||
* kill off our tasklet
|
||||
* It's possible for shutdown to be called after suspend if we get
|
||||
* a DCD drop (hangup) at just the right time. Clear suspended bit so
|
||||
* we don't try to resume a port that has been shutdown.
|
||||
*/
|
||||
tasklet_kill(&state->tlet);
|
||||
clear_bit(ASYNCB_SUSPENDED, &port->flags);
|
||||
|
||||
/*
|
||||
* Free the transmit buffer page.
|
||||
@@ -1261,8 +1257,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
struct uart_port *uport;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!tty_locked());
|
||||
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
@@ -1271,12 +1265,11 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
|
||||
pr_debug("uart_close(%d) called\n", uport->line);
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
if (tty_hung_up_p(filp)) {
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tty->count == 1) && (port->count != 1)) {
|
||||
@@ -1298,7 +1291,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
}
|
||||
if (port->count) {
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1306,19 +1299,13 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
* the line discipline to only process XON/XOFF characters by
|
||||
* setting tty->closing.
|
||||
*/
|
||||
set_bit(ASYNCB_CLOSING, &port->flags);
|
||||
tty->closing = 1;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
|
||||
/*
|
||||
* hack: open-coded tty_wait_until_sent to avoid
|
||||
* recursive tty_lock
|
||||
*/
|
||||
long timeout = msecs_to_jiffies(port->closing_wait);
|
||||
if (wait_event_interruptible_timeout(tty->write_wait,
|
||||
!tty_chars_in_buffer(tty), timeout) >= 0)
|
||||
__uart_wait_until_sent(uport, timeout);
|
||||
}
|
||||
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
tty_wait_until_sent_from_close(tty,
|
||||
msecs_to_jiffies(port->closing_wait));
|
||||
|
||||
/*
|
||||
* At this point, we stop accepting input. To do this, we
|
||||
@@ -1334,9 +1321,10 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
* has completely drained; this is especially
|
||||
* important if there is a transmit FIFO!
|
||||
*/
|
||||
__uart_wait_until_sent(uport, uport->timeout);
|
||||
uart_wait_until_sent(tty, uport->timeout);
|
||||
}
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
uart_shutdown(tty, state);
|
||||
uart_flush_buffer(tty);
|
||||
|
||||
@@ -1361,15 +1349,18 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||
* Wake up anyone trying to open this port.
|
||||
*/
|
||||
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
|
||||
clear_bit(ASYNCB_CLOSING, &port->flags);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
wake_up_interruptible(&port->open_wait);
|
||||
wake_up_interruptible(&port->close_wait);
|
||||
|
||||
done:
|
||||
mutex_unlock(&port->mutex);
|
||||
}
|
||||
|
||||
static void __uart_wait_until_sent(struct uart_port *port, int timeout)
|
||||
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
{
|
||||
struct uart_state *state = tty->driver_data;
|
||||
struct uart_port *port = state->uart_port;
|
||||
unsigned long char_time, expire;
|
||||
|
||||
if (port->type == PORT_UNKNOWN || port->fifosize == 0)
|
||||
@@ -1421,16 +1412,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout)
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
{
|
||||
struct uart_state *state = tty->driver_data;
|
||||
struct uart_port *port = state->uart_port;
|
||||
|
||||
tty_lock();
|
||||
__uart_wait_until_sent(port, timeout);
|
||||
tty_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called with the BKL held in
|
||||
* linux/drivers/char/tty_io.c:do_tty_hangup()
|
||||
@@ -1443,7 +1424,6 @@ static void uart_hangup(struct tty_struct *tty)
|
||||
struct tty_port *port = &state->port;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!tty_locked());
|
||||
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
@@ -1530,7 +1510,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
||||
struct tty_port *port;
|
||||
int retval, line = tty->index;
|
||||
|
||||
BUG_ON(!tty_locked());
|
||||
pr_debug("uart_open(%d) called\n", line);
|
||||
|
||||
/*
|
||||
@@ -2008,6 +1987,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
|
||||
if (port->tty && port->tty->termios && termios.c_cflag == 0)
|
||||
termios = *(port->tty->termios);
|
||||
|
||||
if (console_suspend_enabled)
|
||||
uart_change_pm(state, 0);
|
||||
uport->ops->set_termios(uport, &termios, NULL);
|
||||
if (console_suspend_enabled)
|
||||
console_start(uport->cons);
|
||||
@@ -2068,8 +2049,6 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
|
||||
case UPIO_MEM32:
|
||||
case UPIO_AU:
|
||||
case UPIO_TSI:
|
||||
case UPIO_DWAPB:
|
||||
case UPIO_DWAPB32:
|
||||
snprintf(address, sizeof(address),
|
||||
"MMIO 0x%llx", (unsigned long long)port->mapbase);
|
||||
break;
|
||||
@@ -2298,8 +2277,6 @@ int uart_register_driver(struct uart_driver *drv)
|
||||
port->ops = &uart_port_ops;
|
||||
port->close_delay = 500; /* .5 seconds */
|
||||
port->closing_wait = 30000; /* 30 seconds */
|
||||
tasklet_init(&state->tlet, uart_tasklet_action,
|
||||
(unsigned long)state);
|
||||
}
|
||||
|
||||
retval = tty_register_driver(normal);
|
||||
@@ -2460,11 +2437,6 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
|
||||
*/
|
||||
uport->type = PORT_UNKNOWN;
|
||||
|
||||
/*
|
||||
* Kill the tasklet, and free resources.
|
||||
*/
|
||||
tasklet_kill(&state->tlet);
|
||||
|
||||
state->uart_port = NULL;
|
||||
mutex_unlock(&port_mutex);
|
||||
|
||||
@@ -2489,8 +2461,6 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
|
||||
case UPIO_MEM32:
|
||||
case UPIO_AU:
|
||||
case UPIO_TSI:
|
||||
case UPIO_DWAPB:
|
||||
case UPIO_DWAPB32:
|
||||
return (port1->mapbase == port2->mapbase);
|
||||
}
|
||||
return 0;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
@@ -336,19 +337,19 @@ static int ks8695uart_startup(struct uart_port *port)
|
||||
/*
|
||||
* Allocate the IRQ
|
||||
*/
|
||||
retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, IRQF_DISABLED, "UART TX", port);
|
||||
retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, 0, "UART TX", port);
|
||||
if (retval)
|
||||
goto err_tx;
|
||||
|
||||
retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, IRQF_DISABLED, "UART RX", port);
|
||||
retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, 0, "UART RX", port);
|
||||
if (retval)
|
||||
goto err_rx;
|
||||
|
||||
retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, IRQF_DISABLED, "UART LineStatus", port);
|
||||
retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, 0, "UART LineStatus", port);
|
||||
if (retval)
|
||||
goto err_ls;
|
||||
|
||||
retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, IRQF_DISABLED, "UART ModemStatus", port);
|
||||
retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, 0, "UART ModemStatus", port);
|
||||
if (retval)
|
||||
goto err_ms;
|
||||
|
||||
|
@@ -28,6 +28,8 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
@@ -1976,7 +1976,7 @@ static int __devinit sci_init_single(struct platform_device *dev,
|
||||
* For the muxed case there's nothing more to do.
|
||||
*/
|
||||
port->irq = p->irqs[SCIx_RXI_IRQ];
|
||||
port->irqflags = IRQF_DISABLED;
|
||||
port->irqflags = 0;
|
||||
|
||||
port->serial_in = sci_serial_in;
|
||||
port->serial_out = sci_serial_out;
|
||||
|
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/module.h>
|
||||
@@ -737,7 +738,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
|
||||
DPRINTF("sn_console: switching to interrupt driven console\n");
|
||||
|
||||
if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
|
||||
IRQF_DISABLED | IRQF_SHARED,
|
||||
IRQF_SHARED,
|
||||
"SAL console driver", port) >= 0) {
|
||||
spin_lock_irqsave(&port->sc_port.lock, flags);
|
||||
port->sc_port.irq = SGI_UART_VECTOR;
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ioport.h>
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
|
@@ -20,8 +20,10 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@@ -12,9 +12,11 @@
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
@@ -63,6 +63,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
Reference in New Issue
Block a user