Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial: (21 commits) [SERIAL] add PNP IDs for FPI based touchscreens [SERIAL] Magic SysRq SAK does nothing on serial consoles [SERIAL] tickle NMI watchdog on serial output. [SERIAL] Fix oops when removing suspended serial port [SERIAL] Fix resume handling bug [SERIAL] Remove wrong asm/serial.h inclusions [SERIAL] CONFIG_PM=n slim: drivers/serial/8250_pci.c [SERIAL] OMAP1510 serial fix for 115200 baud [SERIAL] returning proper error from serial core driver [SERIAL] Make uart_line_info() correctly tell MMIO from I/O port [SERIAL] suspend/resume handlers don't have level arg anymore [SERIAL] 8250 resourse management fixes [SERIAL] serial_cs: Add quirk for brainboxes 2-port RS232 card [SERIAL] serial_cs: handle Nokia multi->single port bodge via config quirk [SERIAL] serial_cs: add configuration quirk [SERIAL] serial_cs: Convert Oxford 950 / Possio GCC wakeup quirk [SERIAL] serial_cs: convert IBM post-init handling to a quirk [SERIAL] serial_cs: allow wildcarded quirks [SERIAL] serial_cs: convert multi-port table to quirk table [SERIAL] serial_cs: Use clean up multiport card detection ...
This commit is contained in:
Коммит
6f3a28f7d1
|
@ -31,7 +31,6 @@
|
|||
#include <linux/serial_reg.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/serial.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/sal.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/serial.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/system.h>
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/gt64120.h>
|
||||
#include <asm/serial.h>
|
||||
|
||||
#include <asm/mach-cobalt/cobalt.h>
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <asm/cpu.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/serial.h>
|
||||
#include <asm/lasat/lasat.h>
|
||||
#include <asm/lasat/serial.h>
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/serial.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/serial.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
|
|
@ -1896,6 +1896,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
|
|||
serial_outp(up, UART_EFR, efr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
|
||||
if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
|
||||
if (baud == 115200) {
|
||||
quot = 1;
|
||||
serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
|
||||
} else
|
||||
serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (up->capabilities & UART_NATSEMI) {
|
||||
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
|
||||
serial_outp(up, UART_LCR, 0xe0);
|
||||
|
@ -1949,6 +1960,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
|
|||
case UPIO_AU:
|
||||
size = 0x100000;
|
||||
/* fall thru */
|
||||
case UPIO_TSI:
|
||||
case UPIO_MEM32:
|
||||
case UPIO_MEM:
|
||||
if (!up->port.mapbase)
|
||||
break;
|
||||
|
@ -1984,6 +1997,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
|
|||
case UPIO_AU:
|
||||
size = 0x100000;
|
||||
/* fall thru */
|
||||
case UPIO_TSI:
|
||||
case UPIO_MEM32:
|
||||
case UPIO_MEM:
|
||||
if (!up->port.mapbase)
|
||||
break;
|
||||
|
@ -2007,17 +2022,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
|
|||
{
|
||||
unsigned long start = UART_RSA_BASE << up->port.regshift;
|
||||
unsigned int size = 8 << up->port.regshift;
|
||||
int ret = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (up->port.iotype) {
|
||||
case UPIO_MEM:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
start += up->port.iobase;
|
||||
if (!request_region(start, size, "serial-rsa"))
|
||||
if (request_region(start, size, "serial-rsa"))
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
@ -2031,9 +2044,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
|
|||
unsigned int size = 8 << up->port.regshift;
|
||||
|
||||
switch (up->port.iotype) {
|
||||
case UPIO_MEM:
|
||||
break;
|
||||
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
release_region(up->port.iobase + offset, size);
|
||||
|
@ -2222,9 +2232,10 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
|
|||
/* Wait up to 1s for flow control if necessary */
|
||||
if (up->port.flags & UPF_CONS_FLOW) {
|
||||
tmout = 1000000;
|
||||
while (--tmout &&
|
||||
((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
|
||||
while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
|
||||
udelay(1);
|
||||
touch_nmi_watchdog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2397,7 +2408,6 @@ int __init early_serial_setup(struct uart_port *port)
|
|||
/**
|
||||
* serial8250_suspend_port - suspend one serial port
|
||||
* @line: serial line number
|
||||
* @level: the level of port suspension, as per uart_suspend_port
|
||||
*
|
||||
* Suspend one serial port.
|
||||
*/
|
||||
|
@ -2409,7 +2419,6 @@ void serial8250_suspend_port(int line)
|
|||
/**
|
||||
* serial8250_resume_port - resume one serial port
|
||||
* @line: serial line number
|
||||
* @level: the level of port resumption, as per uart_resume_port
|
||||
*
|
||||
* Resume one serial port.
|
||||
*/
|
||||
|
|
|
@ -1789,6 +1789,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
|
|||
pci_disable_device(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
|
||||
{
|
||||
struct serial_private *priv = pci_get_drvdata(dev);
|
||||
|
@ -1818,6 +1819,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pci_device_id serial_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
|
||||
|
@ -2375,8 +2377,10 @@ static struct pci_driver serial_pci_driver = {
|
|||
.name = "serial",
|
||||
.probe = pciserial_init_one,
|
||||
.remove = __devexit_p(pciserial_remove_one),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = pciserial_suspend_one,
|
||||
.resume = pciserial_resume_one,
|
||||
#endif
|
||||
.id_table = serial_pci_tbl,
|
||||
};
|
||||
|
||||
|
|
|
@ -327,6 +327,19 @@ static const struct pnp_device_id pnp_dev_table[] = {
|
|||
{ "WACF004", 0 },
|
||||
{ "WACF005", 0 },
|
||||
{ "WACF006", 0 },
|
||||
/* Compaq touchscreen */
|
||||
{ "FPI2002", 0 },
|
||||
/* Fujitsu Stylistic touchscreens */
|
||||
{ "FUJ02B2", 0 },
|
||||
{ "FUJ02B3", 0 },
|
||||
/* Fujitsu Stylistic LT touchscreens */
|
||||
{ "FUJ02B4", 0 },
|
||||
/* Passive Fujitsu Stylistic touchscreens */
|
||||
{ "FUJ02B6", 0 },
|
||||
{ "FUJ02B7", 0 },
|
||||
{ "FUJ02B8", 0 },
|
||||
{ "FUJ02B9", 0 },
|
||||
{ "FUJ02BC", 0 },
|
||||
/* Rockwell's (PORALiNK) 33600 INT PNP */
|
||||
{ "WCI0003", 0 },
|
||||
/* Unkown PnP modems */
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
*/
|
||||
#define is_real_interrupt(irq) ((irq) != 0)
|
||||
|
||||
#include <asm/serial.h>
|
||||
#define BASE_BAUD 115200
|
||||
|
||||
/* Standard COM flags */
|
||||
#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
|
||||
|
@ -86,7 +86,6 @@
|
|||
* standard enumeration mechanism. Platforms that can find all
|
||||
* serial ports via mechanisms like ACPI or PCI need not supply it.
|
||||
*/
|
||||
#undef SERIAL_PORT_DFNS
|
||||
#if defined(CONFIG_PLAT_USRV)
|
||||
|
||||
#define SERIAL_PORT_DFNS \
|
||||
|
@ -109,7 +108,7 @@
|
|||
#endif /* !CONFIG_PLAT_USRV */
|
||||
|
||||
static struct old_serial_port old_serial_port[] = {
|
||||
SERIAL_PORT_DFNS /* defined in asm/serial.h */
|
||||
SERIAL_PORT_DFNS
|
||||
};
|
||||
|
||||
#define UART_NR ARRAY_SIZE(old_serial_port)
|
||||
|
|
|
@ -792,6 +792,7 @@ static int uart_set_info(struct uart_state *state,
|
|||
* We failed anyway.
|
||||
*/
|
||||
retval = -EBUSY;
|
||||
goto exit; // Added to return the correct error -Ram Gupta
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1662,16 +1663,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
|
|||
struct uart_port *port = state->port;
|
||||
char stat_buf[32];
|
||||
unsigned int status;
|
||||
int ret;
|
||||
int mmio, ret;
|
||||
|
||||
if (!port)
|
||||
return 0;
|
||||
|
||||
mmio = port->iotype >= UPIO_MEM;
|
||||
ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
|
||||
port->line, uart_type(port),
|
||||
port->iotype == UPIO_MEM ? "mmio:0x" : "port:",
|
||||
port->iotype == UPIO_MEM ? port->mapbase :
|
||||
(unsigned long) port->iobase,
|
||||
mmio ? "mmio:0x" : "port:",
|
||||
mmio ? port->mapbase : (unsigned long) port->iobase,
|
||||
port->irq);
|
||||
|
||||
if (port->type == PORT_UNKNOWN) {
|
||||
|
@ -1939,6 +1940,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
|
|||
if (state->info && state->info->flags & UIF_INITIALIZED) {
|
||||
const struct uart_ops *ops = port->ops;
|
||||
|
||||
state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
|
||||
| UIF_SUSPENDED;
|
||||
|
||||
spin_lock_irq(&port->lock);
|
||||
ops->stop_tx(port);
|
||||
ops->set_mctrl(port, 0);
|
||||
|
@ -2005,7 +2009,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
|
|||
console_start(port->cons);
|
||||
}
|
||||
|
||||
if (state->info && state->info->flags & UIF_INITIALIZED) {
|
||||
if (state->info && state->info->flags & UIF_SUSPENDED) {
|
||||
const struct uart_ops *ops = port->ops;
|
||||
int ret;
|
||||
|
||||
|
@ -2017,15 +2021,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
|
|||
ops->set_mctrl(port, port->mctrl);
|
||||
ops->start_tx(port);
|
||||
spin_unlock_irq(&port->lock);
|
||||
state->info->flags |= UIF_INITIALIZED;
|
||||
} else {
|
||||
/*
|
||||
* Failed to resume - maybe hardware went away?
|
||||
* Clear the "initialized" flag so we won't try
|
||||
* to call the low level drivers shutdown method.
|
||||
*/
|
||||
state->info->flags &= ~UIF_INITIALIZED;
|
||||
uart_shutdown(state);
|
||||
}
|
||||
|
||||
state->info->flags &= ~UIF_SUSPENDED;
|
||||
}
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
|
|
|
@ -80,23 +80,16 @@ module_param(buggy_uart, int, 0444);
|
|||
|
||||
/* Table of multi-port card ID's */
|
||||
|
||||
struct multi_id {
|
||||
u_short manfid;
|
||||
u_short prodid;
|
||||
struct serial_quirk {
|
||||
unsigned int manfid;
|
||||
unsigned int prodid;
|
||||
int multi; /* 1 = multifunction, > 1 = # ports */
|
||||
void (*config)(struct pcmcia_device *);
|
||||
void (*setup)(struct pcmcia_device *, struct uart_port *);
|
||||
void (*wakeup)(struct pcmcia_device *);
|
||||
int (*post)(struct pcmcia_device *);
|
||||
};
|
||||
|
||||
static const struct multi_id multi_id[] = {
|
||||
{ MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
|
||||
{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
|
||||
{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
|
||||
{ MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
|
||||
{ MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 },
|
||||
{ MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 },
|
||||
{ MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 }
|
||||
};
|
||||
#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
|
||||
|
||||
struct serial_info {
|
||||
struct pcmcia_device *p_dev;
|
||||
int ndev;
|
||||
|
@ -107,6 +100,7 @@ struct serial_info {
|
|||
int c950ctrl;
|
||||
dev_node_t node[4];
|
||||
int line[4];
|
||||
const struct serial_quirk *quirk;
|
||||
};
|
||||
|
||||
struct serial_cfg_mem {
|
||||
|
@ -115,37 +109,165 @@ struct serial_cfg_mem {
|
|||
u_char buf[256];
|
||||
};
|
||||
|
||||
/*
|
||||
* vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
|
||||
* manfid 0x0160, 0x0104
|
||||
* This card appears to have a 14.7456MHz clock.
|
||||
*/
|
||||
static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
|
||||
{
|
||||
port->uartclk = 14745600;
|
||||
}
|
||||
|
||||
static int quirk_post_ibm(struct pcmcia_device *link)
|
||||
{
|
||||
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
|
||||
int last_ret, last_fn;
|
||||
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value = reg.Value | 1;
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nokia cards are not really multiport cards. Shouldn't this
|
||||
* be handled by setting the quirk entry .multi = 0 | 1 ?
|
||||
*/
|
||||
static void quirk_config_nokia(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
|
||||
if (info->multi > 1)
|
||||
info->multi = 1;
|
||||
}
|
||||
|
||||
static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
|
||||
outb(12, info->c950ctrl + 1);
|
||||
}
|
||||
|
||||
/* request_region? oxsemi branch does no request_region too... */
|
||||
/*
|
||||
* This sequence is needed to properly initialize MC45 attached to OXCF950.
|
||||
* I tried decreasing these msleep()s, but it worked properly (survived
|
||||
* 1000 stop/start operations) with these timeouts (or bigger).
|
||||
*/
|
||||
static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
unsigned int ctrl = info->c950ctrl;
|
||||
|
||||
outb(0xA, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(300);
|
||||
outb(0xC, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(200);
|
||||
outb(0xF, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xC, ctrl + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Socket Dual IO: this enables irq's for second port
|
||||
*/
|
||||
static void quirk_config_socket(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
|
||||
if (info->multi) {
|
||||
link->conf.Present |= PRESENT_EXT_STATUS;
|
||||
link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct serial_quirk quirks[] = {
|
||||
{
|
||||
.manfid = 0x0160,
|
||||
.prodid = 0x0104,
|
||||
.multi = -1,
|
||||
.setup = quirk_setup_brainboxes_0104,
|
||||
}, {
|
||||
.manfid = MANFID_IBM,
|
||||
.prodid = ~0,
|
||||
.multi = -1,
|
||||
.post = quirk_post_ibm,
|
||||
}, {
|
||||
.manfid = MANFID_INTEL,
|
||||
.prodid = PRODID_INTEL_DUAL_RS232,
|
||||
.multi = 2,
|
||||
}, {
|
||||
.manfid = MANFID_NATINST,
|
||||
.prodid = PRODID_NATINST_QUAD_RS232,
|
||||
.multi = 4,
|
||||
}, {
|
||||
.manfid = MANFID_NOKIA,
|
||||
.prodid = ~0,
|
||||
.multi = -1,
|
||||
.config = quirk_config_nokia,
|
||||
}, {
|
||||
.manfid = MANFID_OMEGA,
|
||||
.prodid = PRODID_OMEGA_QSP_100,
|
||||
.multi = 4,
|
||||
}, {
|
||||
.manfid = MANFID_OXSEMI,
|
||||
.prodid = ~0,
|
||||
.multi = -1,
|
||||
.wakeup = quirk_wakeup_oxsemi,
|
||||
}, {
|
||||
.manfid = MANFID_POSSIO,
|
||||
.prodid = PRODID_POSSIO_GCC,
|
||||
.multi = -1,
|
||||
.wakeup = quirk_wakeup_possio_gcc,
|
||||
}, {
|
||||
.manfid = MANFID_QUATECH,
|
||||
.prodid = PRODID_QUATECH_DUAL_RS232,
|
||||
.multi = 2,
|
||||
}, {
|
||||
.manfid = MANFID_QUATECH,
|
||||
.prodid = PRODID_QUATECH_DUAL_RS232_D1,
|
||||
.multi = 2,
|
||||
}, {
|
||||
.manfid = MANFID_QUATECH,
|
||||
.prodid = PRODID_QUATECH_QUAD_RS232,
|
||||
.multi = 4,
|
||||
}, {
|
||||
.manfid = MANFID_SOCKET,
|
||||
.prodid = PRODID_SOCKET_DUAL_RS232,
|
||||
.multi = 2,
|
||||
.config = quirk_config_socket,
|
||||
}, {
|
||||
.manfid = MANFID_SOCKET,
|
||||
.prodid = ~0,
|
||||
.multi = -1,
|
||||
.config = quirk_config_socket,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int serial_config(struct pcmcia_device * link);
|
||||
|
||||
|
||||
static void wakeup_card(struct serial_info *info)
|
||||
{
|
||||
int ctrl = info->c950ctrl;
|
||||
|
||||
if (info->manfid == MANFID_OXSEMI) {
|
||||
outb(12, ctrl + 1);
|
||||
} else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
|
||||
/* request_region? oxsemi branch does no request_region too... */
|
||||
/* This sequence is needed to properly initialize MC45 attached to OXCF950.
|
||||
* I tried decreasing these msleep()s, but it worked properly (survived
|
||||
* 1000 stop/start operations) with these timeouts (or bigger). */
|
||||
outb(0xA, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(300);
|
||||
outb(0xC, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(200);
|
||||
outb(0xF, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xC, ctrl + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
After a card is removed, serial_remove() will unregister
|
||||
|
@ -185,14 +307,14 @@ static int serial_suspend(struct pcmcia_device *link)
|
|||
|
||||
static int serial_resume(struct pcmcia_device *link)
|
||||
{
|
||||
if (pcmcia_dev_present(link)) {
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_resume_port(info->line[i]);
|
||||
wakeup_card(info);
|
||||
}
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_resume_port(info->line[i]);
|
||||
|
||||
if (info->quirk && info->quirk->wakeup)
|
||||
info->quirk->wakeup(link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -278,6 +400,10 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
|
|||
port.dev = &handle_to_dev(handle);
|
||||
if (buggy_uart)
|
||||
port.flags |= UPF_BUGGY_UART;
|
||||
|
||||
if (info->quirk && info->quirk->setup)
|
||||
info->quirk->setup(handle, &port);
|
||||
|
||||
line = serial8250_register_port(&port);
|
||||
if (line < 0) {
|
||||
printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
|
||||
|
@ -433,6 +559,13 @@ next_entry:
|
|||
}
|
||||
if (info->multi && (info->manfid == MANFID_3COM))
|
||||
link->conf.ConfigIndex &= ~(0x08);
|
||||
|
||||
/*
|
||||
* Apply any configuration quirks.
|
||||
*/
|
||||
if (info->quirk && info->quirk->config)
|
||||
info->quirk->config(link);
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
|
@ -521,11 +654,13 @@ static int multi_config(struct pcmcia_device * link)
|
|||
cs_error(link, RequestIRQ, i);
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
/* Socket Dual IO: this enables irq's for second port */
|
||||
if (info->multi && (info->manfid == MANFID_SOCKET)) {
|
||||
link->conf.Present |= PRESENT_EXT_STATUS;
|
||||
link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply any configuration quirks.
|
||||
*/
|
||||
if (info->quirk && info->quirk->config)
|
||||
info->quirk->config(link);
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
|
@ -550,17 +685,19 @@ static int multi_config(struct pcmcia_device * link)
|
|||
link->irq.AssignedIRQ);
|
||||
}
|
||||
info->c950ctrl = base2;
|
||||
wakeup_card(info);
|
||||
|
||||
/*
|
||||
* FIXME: We really should wake up the port prior to
|
||||
* handing it over to the serial layer.
|
||||
*/
|
||||
if (info->quirk && info->quirk->wakeup)
|
||||
info->quirk->wakeup(link);
|
||||
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
||||
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
/* The Nokia cards are not really multiport cards */
|
||||
if (info->manfid == MANFID_NOKIA) {
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
for (i = 0; i < info->multi - 1; i++)
|
||||
setup_serial(link, info, base2 + (8 * i),
|
||||
link->irq.AssignedIRQ);
|
||||
|
@ -622,13 +759,16 @@ static int serial_config(struct pcmcia_device * link)
|
|||
tuple->DesiredTuple = CISTPL_MANFID;
|
||||
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
|
||||
info->manfid = parse->manfid.manf;
|
||||
info->prodid = le16_to_cpu(buf[1]);
|
||||
for (i = 0; i < MULTI_COUNT; i++)
|
||||
if ((info->manfid == multi_id[i].manfid) &&
|
||||
(parse->manfid.card == multi_id[i].prodid))
|
||||
info->prodid = parse->manfid.card;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(quirks); i++)
|
||||
if ((quirks[i].manfid == ~0 ||
|
||||
quirks[i].manfid == info->manfid) &&
|
||||
(quirks[i].prodid == ~0 ||
|
||||
quirks[i].prodid == info->prodid)) {
|
||||
info->quirk = &quirks[i];
|
||||
break;
|
||||
if (i < MULTI_COUNT)
|
||||
info->multi = multi_id[i].multi;
|
||||
}
|
||||
}
|
||||
|
||||
/* Another check for dual-serial cards: look for either serial or
|
||||
|
@ -648,6 +788,12 @@ static int serial_config(struct pcmcia_device * link)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply any multi-port quirk.
|
||||
*/
|
||||
if (info->quirk && info->quirk->multi != -1)
|
||||
info->multi = info->quirk->multi;
|
||||
|
||||
if (info->multi > 1)
|
||||
multi_config(link);
|
||||
else
|
||||
|
@ -656,21 +802,13 @@ static int serial_config(struct pcmcia_device * link)
|
|||
if (info->ndev == 0)
|
||||
goto failed;
|
||||
|
||||
if (info->manfid == MANFID_IBM) {
|
||||
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value = reg.Value | 1;
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Apply any post-init quirk. FIXME: This should really happen
|
||||
* before we register the port, since it might already be in use.
|
||||
*/
|
||||
if (info->quirk && info->quirk->post)
|
||||
if (info->quirk->post(link))
|
||||
goto failed;
|
||||
|
||||
link->dev_node = &info->node[0];
|
||||
kfree(cfg_mem);
|
||||
|
|
|
@ -990,7 +990,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
|
|||
/**
|
||||
* serial_txx9_suspend_port - suspend one serial port
|
||||
* @line: serial line number
|
||||
* @level: the level of port suspension, as per uart_suspend_port
|
||||
*
|
||||
* Suspend one serial port.
|
||||
*/
|
||||
|
@ -1002,7 +1001,6 @@ static void serial_txx9_suspend_port(int line)
|
|||
/**
|
||||
* serial_txx9_resume_port - resume one serial port
|
||||
* @line: serial line number
|
||||
* @level: the level of port resumption, as per uart_resume_port
|
||||
*
|
||||
* Resume one serial port.
|
||||
*/
|
||||
|
|
|
@ -319,6 +319,7 @@ struct uart_info {
|
|||
#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
|
||||
#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
|
||||
#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
|
||||
#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
|
||||
|
||||
int blocked_open;
|
||||
|
||||
|
@ -414,7 +415,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
|
|||
#ifdef SUPPORT_SYSRQ
|
||||
if (port->sysrq) {
|
||||
if (ch && time_before(jiffies, port->sysrq)) {
|
||||
handle_sysrq(ch, regs, NULL);
|
||||
handle_sysrq(ch, regs, port->info->tty);
|
||||
port->sysrq = 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче