M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+115
View File
@@ -0,0 +1,115 @@
/*
* Driver for 8250/16550-type serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
*
* Copyright (C) 2001 Russell King.
*
* 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.
*/
#include <linux/serial_8250.h>
struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
unsigned short capabilities; /* port capabilities */
unsigned short bugs; /* port bugs */
unsigned int tx_loadsz; /* transmit fifo load size */
unsigned char acr;
unsigned char ier;
unsigned char lcr;
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
unsigned char cur_iotype; /* Running I/O type */
/*
* Some bits in registers are cleared on a read, so they must
* be saved whenever the register is read but the bits will not
* be immediately processed.
*/
#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
unsigned char lsr_saved_flags;
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
unsigned char msr_saved_flags;
};
struct old_serial_port {
unsigned int uart;
unsigned int baud_base;
unsigned int port;
unsigned int irq;
unsigned int flags;
unsigned char hub6;
unsigned char io_type;
unsigned char *iomem_base;
unsigned short iomem_reg_shift;
unsigned long irqflags;
};
/*
* This replaces serial_uart_config in include/linux/serial.h
*/
struct serial8250_config {
const char *name;
unsigned short fifo_size;
unsigned short tx_loadsz;
unsigned char fcr;
unsigned int flags;
};
#define UART_CAP_FIFO (1 << 8) /* UART has FIFO */
#define UART_CAP_EFR (1 << 9) /* UART has EFR */
#define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
#define PROBE_RSA (1 << 0)
#define PROBE_ANY (~0)
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
#define SERIAL8250_SHARE_IRQS 1
#else
#define SERIAL8250_SHARE_IRQS 0
#endif
static inline int serial_in(struct uart_8250_port *up, int offset)
{
return up->port.serial_in(&up->port, offset);
}
static inline void serial_out(struct uart_8250_port *up, int offset, int value)
{
up->port.serial_out(&up->port, offset, value);
}
#if defined(__alpha__) && !defined(CONFIG_PCI)
/*
* Digital did something really horribly wrong with the OUT1 and OUT2
* lines on at least some ALPHA's. The failure mode is that if either
* is cleared, the machine locks up with endless interrupts.
*/
#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1)
#elif defined(CONFIG_SBC8560)
/*
* WindRiver did something similarly broken on their SBC8560 board. The
* UART tristates its IRQ output while OUT2 is clear, but they pulled
* the interrupt line _up_ instead of down, so if we register the IRQ
* while the UART is in that state, we die in an IRQ storm. */
#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2)
#else
#define ALPHA_KLUDGE_MCR 0
#endif
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF, \
}
static struct plat_serial8250_port accent_data[] = {
PORT(0x330, 4),
PORT(0x338, 4),
{ },
};
static struct platform_device accent_device = {
.name = "serial8250",
.id = PLAT8250_DEV_ACCENT,
.dev = {
.platform_data = accent_data,
},
};
static int __init accent_init(void)
{
return platform_device_register(&accent_device);
}
module_init(accent_init);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards");
MODULE_LICENSE("GPL");
+141
View File
@@ -0,0 +1,141 @@
/*
* linux/drivers/serial/acorn.c
*
* Copyright (C) 1996-2003 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/ecard.h>
#include <asm/string.h>
#include "8250.h"
#define MAX_PORTS 3
struct serial_card_type {
unsigned int num_ports;
unsigned int uartclk;
unsigned int type;
unsigned int offset[MAX_PORTS];
};
struct serial_card_info {
unsigned int num_ports;
int ports[MAX_PORTS];
void __iomem *vaddr;
};
static int __devinit
serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct serial_card_info *info;
struct serial_card_type *type = id->data;
struct uart_port port;
unsigned long bus_addr;
unsigned int i;
info = kzalloc(sizeof(struct serial_card_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->num_ports = type->num_ports;
bus_addr = ecard_resource_start(ec, type->type);
info->vaddr = ecardm_iomap(ec, type->type, 0, 0);
if (!info->vaddr) {
kfree(info);
return -ENOMEM;
}
ecard_set_drvdata(ec, info);
memset(&port, 0, sizeof(struct uart_port));
port.irq = ec->irq;
port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
port.uartclk = type->uartclk;
port.iotype = UPIO_MEM;
port.regshift = 2;
port.dev = &ec->dev;
for (i = 0; i < info->num_ports; i ++) {
port.membase = info->vaddr + type->offset[i];
port.mapbase = bus_addr + type->offset[i];
info->ports[i] = serial8250_register_port(&port);
}
return 0;
}
static void __devexit serial_card_remove(struct expansion_card *ec)
{
struct serial_card_info *info = ecard_get_drvdata(ec);
int i;
ecard_set_drvdata(ec, NULL);
for (i = 0; i < info->num_ports; i++)
if (info->ports[i] > 0)
serial8250_unregister_port(info->ports[i]);
kfree(info);
}
static struct serial_card_type atomwide_type = {
.num_ports = 3,
.uartclk = 7372800,
.type = ECARD_RES_IOCSLOW,
.offset = { 0x2800, 0x2400, 0x2000 },
};
static struct serial_card_type serport_type = {
.num_ports = 2,
.uartclk = 3686400,
.type = ECARD_RES_IOCSLOW,
.offset = { 0x2000, 0x2020 },
};
static const struct ecard_id serial_cids[] = {
{ MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, &atomwide_type },
{ MANU_SERPORT, PROD_SERPORT_DSPORT, &serport_type },
{ 0xffff, 0xffff }
};
static struct ecard_driver serial_card_driver = {
.probe = serial_card_probe,
.remove = __devexit_p(serial_card_remove),
.id_table = serial_cids,
.drv = {
.name = "8250_acorn",
},
};
static int __init serial_card_init(void)
{
return ecard_register_driver(&serial_card_driver);
}
static void __exit serial_card_exit(void)
{
ecard_remove_driver(&serial_card_driver);
}
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("Acorn 8250-compatible serial port expansion card driver");
MODULE_LICENSE("GPL");
module_init(serial_card_init);
module_exit(serial_card_exit);
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF, \
}
static struct plat_serial8250_port boca_data[] = {
PORT(0x100, 12),
PORT(0x108, 12),
PORT(0x110, 12),
PORT(0x118, 12),
PORT(0x120, 12),
PORT(0x128, 12),
PORT(0x130, 12),
PORT(0x138, 12),
PORT(0x140, 12),
PORT(0x148, 12),
PORT(0x150, 12),
PORT(0x158, 12),
PORT(0x160, 12),
PORT(0x168, 12),
PORT(0x170, 12),
PORT(0x178, 12),
{ },
};
static struct platform_device boca_device = {
.name = "serial8250",
.id = PLAT8250_DEV_BOCA,
.dev = {
.platform_data = boca_data,
},
};
static int __init boca_init(void)
{
return platform_device_register(&boca_device);
}
module_init(boca_init);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("8250 serial probe module for Boca cards");
MODULE_LICENSE("GPL");
+184
View File
@@ -0,0 +1,184 @@
/*
* 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),
};
module_platform_driver(dw8250_platform_driver);
MODULE_AUTHOR("Jamie Iles");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
+287
View File
@@ -0,0 +1,287 @@
/*
* Early serial console for 8250/16550 devices
*
* (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Based on the 8250.c serial driver, Copyright (C) 2001 Russell King,
* and on early_printk.c by Andi Kleen.
*
* This is for use before the serial driver has initialized, in
* particular, before the UARTs have been discovered and named.
* Instead of specifying the console device as, e.g., "ttyS0",
* we locate the device directly by its MMIO or I/O port address.
*
* The user can specify the device directly, e.g.,
* earlycon=uart8250,io,0x3f8,9600n8
* earlycon=uart8250,mmio,0xff5e0000,115200n8
* earlycon=uart8250,mmio32,0xff5e0000,115200n8
* or
* console=uart8250,io,0x3f8,9600n8
* console=uart8250,mmio,0xff5e0000,115200n8
* console=uart8250,mmio32,0xff5e0000,115200n8
*/
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <asm/io.h>
#include <asm/serial.h>
#ifdef CONFIG_FIX_EARLYCON_MEM
#include <asm/pgtable.h>
#include <asm/fixmap.h>
#endif
struct early_serial8250_device {
struct uart_port port;
char options[16]; /* e.g., 115200n8 */
unsigned int baud;
};
static struct early_serial8250_device early_device;
static unsigned int __init serial_in(struct uart_port *port, int offset)
{
switch (port->iotype) {
case UPIO_MEM:
return readb(port->membase + offset);
case UPIO_MEM32:
return readl(port->membase + (offset << 2));
case UPIO_PORT:
return inb(port->iobase + offset);
default:
return 0;
}
}
static void __init serial_out(struct uart_port *port, int offset, int value)
{
switch (port->iotype) {
case UPIO_MEM:
writeb(value, port->membase + offset);
break;
case UPIO_MEM32:
writel(value, port->membase + (offset << 2));
break;
case UPIO_PORT:
outb(value, port->iobase + offset);
break;
}
}
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
static void __init wait_for_xmitr(struct uart_port *port)
{
unsigned int status;
for (;;) {
status = serial_in(port, UART_LSR);
if ((status & BOTH_EMPTY) == BOTH_EMPTY)
return;
cpu_relax();
}
}
static void __init serial_putc(struct uart_port *port, int c)
{
wait_for_xmitr(port);
serial_out(port, UART_TX, c);
}
static void __init early_serial8250_write(struct console *console,
const char *s, unsigned int count)
{
struct uart_port *port = &early_device.port;
unsigned int ier;
/* Save the IER and disable interrupts */
ier = serial_in(port, UART_IER);
serial_out(port, UART_IER, 0);
uart_console_write(port, s, count, serial_putc);
/* Wait for transmitter to become empty and restore the IER */
wait_for_xmitr(port);
serial_out(port, UART_IER, ier);
}
static unsigned int __init probe_baud(struct uart_port *port)
{
unsigned char lcr, dll, dlm;
unsigned int quot;
lcr = serial_in(port, UART_LCR);
serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
dll = serial_in(port, UART_DLL);
dlm = serial_in(port, UART_DLM);
serial_out(port, UART_LCR, lcr);
quot = (dlm << 8) | dll;
return (port->uartclk / 16) / quot;
}
static void __init init_port(struct early_serial8250_device *device)
{
struct uart_port *port = &device->port;
unsigned int divisor;
unsigned char c;
serial_out(port, UART_LCR, 0x3); /* 8n1 */
serial_out(port, UART_IER, 0); /* no interrupt */
serial_out(port, UART_FCR, 0); /* no fifo */
serial_out(port, UART_MCR, 0x3); /* DTR + RTS */
divisor = port->uartclk / (16 * device->baud);
c = serial_in(port, UART_LCR);
serial_out(port, UART_LCR, c | UART_LCR_DLAB);
serial_out(port, UART_DLL, divisor & 0xff);
serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
}
static int __init parse_options(struct early_serial8250_device *device,
char *options)
{
struct uart_port *port = &device->port;
int mmio, mmio32, length;
if (!options)
return -ENODEV;
port->uartclk = BASE_BAUD * 16;
mmio = !strncmp(options, "mmio,", 5);
mmio32 = !strncmp(options, "mmio32,", 7);
if (mmio || mmio32) {
port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
&options, 0);
if (mmio32)
port->regshift = 2;
#ifdef CONFIG_FIX_EARLYCON_MEM
set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
port->mapbase & PAGE_MASK);
port->membase =
(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
port->membase += port->mapbase & ~PAGE_MASK;
#else
port->membase = ioremap_nocache(port->mapbase, 64);
if (!port->membase) {
printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
__func__,
(unsigned long long) port->mapbase);
return -ENOMEM;
}
#endif
} else if (!strncmp(options, "io,", 3)) {
port->iotype = UPIO_PORT;
port->iobase = simple_strtoul(options + 3, &options, 0);
mmio = 0;
} else
return -EINVAL;
options = strchr(options, ',');
if (options) {
options++;
device->baud = simple_strtoul(options, NULL, 0);
length = min(strcspn(options, " "), sizeof(device->options));
strncpy(device->options, options, length);
} else {
device->baud = probe_baud(port);
snprintf(device->options, sizeof(device->options), "%u",
device->baud);
}
if (mmio || mmio32)
printk(KERN_INFO
"Early serial console at MMIO%s 0x%llx (options '%s')\n",
mmio32 ? "32" : "",
(unsigned long long)port->mapbase,
device->options);
else
printk(KERN_INFO
"Early serial console at I/O port 0x%lx (options '%s')\n",
port->iobase,
device->options);
return 0;
}
static struct console early_serial8250_console __initdata = {
.name = "uart",
.write = early_serial8250_write,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
static int __init early_serial8250_setup(char *options)
{
struct early_serial8250_device *device = &early_device;
int err;
if (device->port.membase || device->port.iobase)
return 0;
err = parse_options(device, options);
if (err < 0)
return err;
init_port(device);
return 0;
}
int __init setup_early_serial8250_console(char *cmdline)
{
char *options;
int err;
options = strstr(cmdline, "uart8250,");
if (!options) {
options = strstr(cmdline, "uart,");
if (!options)
return 0;
}
options = strchr(cmdline, ',') + 1;
err = early_serial8250_setup(options);
if (err < 0)
return err;
register_console(&early_serial8250_console);
return 0;
}
int serial8250_find_port_for_earlycon(void)
{
struct early_serial8250_device *device = &early_device;
struct uart_port *port = &device->port;
int line;
int ret;
if (!device->port.membase && !device->port.iobase)
return -ENODEV;
line = serial8250_find_port(port);
if (line < 0)
return -ENODEV;
ret = update_console_cmdline("uart", 8250,
"ttyS", line, device->options);
if (ret < 0)
ret = update_console_cmdline("uart", 0,
"ttyS", line, device->options);
return ret;
}
early_param("earlycon", setup_early_serial8250_console);
@@ -0,0 +1,50 @@
/*
* Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
* Based on 8250_boca.
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF, \
}
static struct plat_serial8250_port exar_data[] = {
PORT(0x100, 5),
PORT(0x108, 5),
PORT(0x110, 5),
PORT(0x118, 5),
{ },
};
static struct platform_device exar_device = {
.name = "serial8250",
.id = PLAT8250_DEV_EXAR_ST16C554,
.dev = {
.platform_data = exar_data,
},
};
static int __init exar_init(void)
{
return platform_device_register(&exar_device);
}
module_init(exar_init);
MODULE_AUTHOR("Paul B Schroeder");
MODULE_DESCRIPTION("8250 serial probe module for Exar cards");
MODULE_LICENSE("GPL");
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF | UPF_FOURPORT, \
}
static struct plat_serial8250_port fourport_data[] = {
PORT(0x1a0, 9),
PORT(0x1a8, 9),
PORT(0x1b0, 9),
PORT(0x1b8, 9),
PORT(0x2a0, 5),
PORT(0x2a8, 5),
PORT(0x2b0, 5),
PORT(0x2b8, 5),
{ },
};
static struct platform_device fourport_device = {
.name = "serial8250",
.id = PLAT8250_DEV_FOURPORT,
.dev = {
.platform_data = fourport_data,
},
};
static int __init fourport_init(void)
{
return platform_device_register(&fourport_device);
}
module_init(fourport_init);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards");
MODULE_LICENSE("GPL");
+63
View File
@@ -0,0 +1,63 @@
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include "8250.h"
/*
* Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This isn't a full driver; it just provides an alternate IRQ
* handler to deal with an errata. Everything else is just
* using the bog standard 8250 support.
*
* We follow code flow of serial8250_default_handle_irq() but add
* a check for a break and insert a dummy read on the Rx for the
* immediately following IRQ event.
*
* We re-use the already existing "bug handling" lsr_saved_flags
* field to carry the "what we just did" information from the one
* IRQ event to the next one.
*/
int fsl8250_handle_irq(struct uart_port *port)
{
unsigned char lsr, orig_lsr;
unsigned long flags;
unsigned int iir;
struct uart_8250_port *up =
container_of(port, struct uart_8250_port, port);
spin_lock_irqsave(&up->port.lock, flags);
iir = port->serial_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT) {
spin_unlock_irqrestore(&up->port.lock, flags);
return 0;
}
/* This is the WAR; if last event was BRK, then read and return */
if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
up->lsr_saved_flags &= ~UART_LSR_BI;
port->serial_in(port, UART_RX);
spin_unlock_irqrestore(&up->port.lock, flags);
return 1;
}
lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
if (lsr & (UART_LSR_DR | UART_LSR_BI))
lsr = serial8250_rx_chars(up, lsr);
serial8250_modem_status(up);
if (lsr & UART_LSR_THRE)
serial8250_tx_chars(up);
up->lsr_saved_flags = orig_lsr;
spin_unlock_irqrestore(&up->port.lock, flags);
return 1;
}
+122
View File
@@ -0,0 +1,122 @@
/*
* Serial Device Initialisation for Lasi/Asp/Wax/Dino
*
* (c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002
*
* 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.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/serial_core.h>
#include <linux/signal.h>
#include <linux/types.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/io.h>
#include "8250.h"
static int __init serial_init_chip(struct parisc_device *dev)
{
struct uart_port port;
unsigned long address;
int err;
if (!dev->irq) {
/* We find some unattached serial ports by walking native
* busses. These should be silently ignored. Otherwise,
* what we have here is a missing parent device, so tell
* the user what they're missing.
*/
if (parisc_parent(dev)->id.hw_type != HPHW_IOA)
printk(KERN_INFO
"Serial: device 0x%llx not configured.\n"
"Enable support for Wax, Lasi, Asp or Dino.\n",
(unsigned long long)dev->hpa.start);
return -ENODEV;
}
address = dev->hpa.start;
if (dev->id.sversion != 0x8d)
address += 0x800;
memset(&port, 0, sizeof(port));
port.iotype = UPIO_MEM;
/* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */
port.uartclk = 7272727;
port.mapbase = address;
port.membase = ioremap_nocache(address, 16);
port.irq = dev->irq;
port.flags = UPF_BOOT_AUTOCONF;
port.dev = &dev->dev;
err = serial8250_register_port(&port);
if (err < 0) {
printk(KERN_WARNING
"serial8250_register_port returned error %d\n", err);
iounmap(port.membase);
return err;
}
return 0;
}
static struct parisc_device_id serial_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
{ 0 }
};
/* Hack. Some machines have SERIAL_0 attached to Lasi and SERIAL_1
* attached to Dino. Unfortunately, Dino appears before Lasi in the device
* tree. To ensure that ttyS0 == SERIAL_0, we register two drivers; one
* which only knows about Lasi and then a second which will find all the
* other serial ports. HPUX ignores this problem.
*/
static struct parisc_device_id lasi_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */
{ 0 }
};
MODULE_DEVICE_TABLE(parisc, serial_tbl);
static struct parisc_driver lasi_driver = {
.name = "serial_1",
.id_table = lasi_tbl,
.probe = serial_init_chip,
};
static struct parisc_driver serial_driver = {
.name = "serial",
.id_table = serial_tbl,
.probe = serial_init_chip,
};
static int __init probe_serial_gsc(void)
{
register_parisc_driver(&lasi_driver);
register_parisc_driver(&serial_driver);
return 0;
}
module_init(probe_serial_gsc);
MODULE_LICENSE("GPL");
+327
View File
@@ -0,0 +1,327 @@
/*
* Driver for the 98626/98644/internal serial interface on hp300/hp400
* (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs)
*
* Ported from 2.2 and modified to use the normal 8250 driver
* by Kars de Jong <jongk@linux-m68k.org>, May 2004.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/delay.h>
#include <linux/dio.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "8250.h"
#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
#warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
#endif
#ifdef CONFIG_HPAPCI
struct hp300_port
{
struct hp300_port *next; /* next port */
int line; /* line (tty) number */
};
static struct hp300_port *hp300_ports;
#endif
#ifdef CONFIG_HPDCA
static int __devinit hpdca_init_one(struct dio_dev *d,
const struct dio_device_id *ent);
static void __devexit hpdca_remove_one(struct dio_dev *d);
static struct dio_device_id hpdca_dio_tbl[] = {
{ DIO_ID_DCA0 },
{ DIO_ID_DCA0REM },
{ DIO_ID_DCA1 },
{ DIO_ID_DCA1REM },
{ 0 }
};
static struct dio_driver hpdca_driver = {
.name = "hpdca",
.id_table = hpdca_dio_tbl,
.probe = hpdca_init_one,
.remove = __devexit_p(hpdca_remove_one),
};
#endif
static unsigned int num_ports;
extern int hp300_uart_scode;
/* Offset to UART registers from base of DCA */
#define UART_OFFSET 17
#define DCA_ID 0x01 /* ID (read), reset (write) */
#define DCA_IC 0x03 /* Interrupt control */
/* Interrupt control */
#define DCA_IC_IE 0x80 /* Master interrupt enable */
#define HPDCA_BAUD_BASE 153600
/* Base address of the Frodo part */
#define FRODO_BASE (0x41c000)
/*
* Where we find the 8250-like APCI ports, and how far apart they are.
*/
#define FRODO_APCIBASE 0x0
#define FRODO_APCISPACE 0x20
#define FRODO_APCI_OFFSET(x) (FRODO_APCIBASE + ((x) * FRODO_APCISPACE))
#define HPAPCI_BAUD_BASE 500400
#ifdef CONFIG_SERIAL_8250_CONSOLE
/*
* Parse the bootinfo to find descriptions for headless console and
* debug serial ports and register them with the 8250 driver.
* This function should be called before serial_console_init() is called
* to make sure the serial console will be available for use. IA-64 kernel
* calls this function from setup_arch() after the EFI and ACPI tables have
* been parsed.
*/
int __init hp300_setup_serial_console(void)
{
int scode;
struct uart_port port;
memset(&port, 0, sizeof(port));
if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX)
return 0;
if (DIO_SCINHOLE(hp300_uart_scode))
return 0;
scode = hp300_uart_scode;
/* Memory mapped I/O */
port.iotype = UPIO_MEM;
port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
port.type = PORT_UNKNOWN;
/* Check for APCI console */
if (scode == 256) {
#ifdef CONFIG_HPAPCI
printk(KERN_INFO "Serial console is HP APCI 1\n");
port.uartclk = HPAPCI_BAUD_BASE * 16;
port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1));
port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
port.regshift = 2;
add_preferred_console("ttyS", port.line, "9600n8");
#else
printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n");
return 0;
#endif
} else {
#ifdef CONFIG_HPDCA
unsigned long pa = dio_scodetophysaddr(scode);
if (!pa)
return 0;
printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode);
port.uartclk = HPDCA_BAUD_BASE * 16;
port.mapbase = (pa + UART_OFFSET);
port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
port.regshift = 1;
port.irq = DIO_IPL(pa + DIO_VIRADDRBASE);
/* Enable board-interrupts */
out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80)
add_preferred_console("ttyS", port.line, "9600n8");
#else
printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n");
return 0;
#endif
}
if (early_serial_setup(&port) < 0)
printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n");
return 0;
}
#endif /* CONFIG_SERIAL_8250_CONSOLE */
#ifdef CONFIG_HPDCA
static int __devinit hpdca_init_one(struct dio_dev *d,
const struct dio_device_id *ent)
{
struct uart_port port;
int line;
#ifdef CONFIG_SERIAL_8250_CONSOLE
if (hp300_uart_scode == d->scode) {
/* Already got it. */
return 0;
}
#endif
memset(&port, 0, sizeof(struct uart_port));
/* Memory mapped I/O */
port.iotype = UPIO_MEM;
port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
port.irq = d->ipl;
port.uartclk = HPDCA_BAUD_BASE * 16;
port.mapbase = (d->resource.start + UART_OFFSET);
port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
port.regshift = 1;
port.dev = &d->dev;
line = serial8250_register_port(&port);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
" irq %d failed\n", d->scode, port.irq);
return -ENOMEM;
}
/* Enable board-interrupts */
out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
dio_set_drvdata(d, (void *)line);
/* Reset the DCA */
out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff);
udelay(100);
num_ports++;
return 0;
}
#endif
static int __init hp300_8250_init(void)
{
static int called;
#ifdef CONFIG_HPAPCI
int line;
unsigned long base;
struct uart_port uport;
struct hp300_port *port;
int i;
#endif
if (called)
return -ENODEV;
called = 1;
if (!MACH_IS_HP300)
return -ENODEV;
#ifdef CONFIG_HPDCA
dio_register_driver(&hpdca_driver);
#endif
#ifdef CONFIG_HPAPCI
if (hp300_model < HP_400) {
if (!num_ports)
return -ENODEV;
return 0;
}
/* These models have the Frodo chip.
* Port 0 is reserved for the Apollo Domain keyboard.
* Port 1 is either the console or the DCA.
*/
for (i = 1; i < 4; i++) {
/* Port 1 is the console on a 425e, on other machines it's
* mapped to DCA.
*/
#ifdef CONFIG_SERIAL_8250_CONSOLE
if (i == 1)
continue;
#endif
/* Create new serial device */
port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL);
if (!port)
return -ENOMEM;
memset(&uport, 0, sizeof(struct uart_port));
base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
/* Memory mapped I/O */
uport.iotype = UPIO_MEM;
uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
| UPF_BOOT_AUTOCONF;
/* XXX - no interrupt support yet */
uport.irq = 0;
uport.uartclk = HPAPCI_BAUD_BASE * 16;
uport.mapbase = base;
uport.membase = (char *)(base + DIO_VIRADDRBASE);
uport.regshift = 2;
line = serial8250_register_port(&uport);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() APCI"
" %d irq %d failed\n", i, uport.irq);
kfree(port);
continue;
}
port->line = line;
port->next = hp300_ports;
hp300_ports = port;
num_ports++;
}
#endif
/* Any boards found? */
if (!num_ports)
return -ENODEV;
return 0;
}
#ifdef CONFIG_HPDCA
static void __devexit hpdca_remove_one(struct dio_dev *d)
{
int line;
line = (int) dio_get_drvdata(d);
if (d->resource.start) {
/* Disable board-interrupts */
out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
}
serial8250_unregister_port(line);
}
#endif
static void __exit hp300_8250_exit(void)
{
#ifdef CONFIG_HPAPCI
struct hp300_port *port, *to_free;
for (port = hp300_ports; port; ) {
serial8250_unregister_port(port->line);
to_free = port;
port = port->next;
kfree(to_free);
}
hp300_ports = NULL;
#endif
#ifdef CONFIG_HPDCA
dio_unregister_driver(&hpdca_driver);
#endif
}
module_init(hp300_8250_init);
module_exit(hp300_8250_exit);
MODULE_DESCRIPTION("HP DCA/APCI serial driver");
MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>");
MODULE_LICENSE("GPL");
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#define HUB6(card,port) \
{ \
.iobase = 0x302, \
.irq = 3, \
.uartclk = 1843200, \
.iotype = UPIO_HUB6, \
.flags = UPF_BOOT_AUTOCONF, \
.hub6 = (card) << 6 | (port) << 3 | 1, \
}
static struct plat_serial8250_port hub6_data[] = {
HUB6(0, 0),
HUB6(0, 1),
HUB6(0, 2),
HUB6(0, 3),
HUB6(0, 4),
HUB6(0, 5),
HUB6(1, 0),
HUB6(1, 1),
HUB6(1, 2),
HUB6(1, 3),
HUB6(1, 4),
HUB6(1, 5),
{ },
};
static struct platform_device hub6_device = {
.name = "serial8250",
.id = PLAT8250_DEV_HUB6,
.dev = {
.platform_data = hub6_data,
},
};
static int __init hub6_init(void)
{
return platform_device_register(&hub6_device);
}
module_init(hub6_init);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards");
MODULE_LICENSE("GPL");
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mca.h>
#include <linux/serial_8250.h>
/*
* FIXME: Should we be doing AUTO_IRQ here?
*/
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ
#else
#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
#endif
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = MCA_FLAGS, \
}
static struct plat_serial8250_port mca_data[] = {
PORT(0x3220, 3),
PORT(0x3228, 3),
PORT(0x4220, 3),
PORT(0x4228, 3),
PORT(0x5220, 3),
PORT(0x5228, 3),
{ },
};
static struct platform_device mca_device = {
.name = "serial8250",
.id = PLAT8250_DEV_MCA,
.dev = {
.platform_data = mca_data,
},
};
static int __init mca_init(void)
{
if (!MCA_bus)
return -ENODEV;
return platform_device_register(&mca_device);
}
module_init(mca_init);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("8250 serial probe module for MCA ports");
MODULE_LICENSE("GPL");
File diff suppressed because it is too large Load Diff
+524
View File
@@ -0,0 +1,524 @@
/*
* Probe module for 8250/16550-type ISAPNP serial ports.
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
*
* Copyright (C) 2001 Russell King, All Rights Reserved.
*
* Ported to the Linux PnP Layer - (C) Adam Belay.
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pnp.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/serial_core.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
#include "8250.h"
#define UNKNOWN_DEV 0x3000
static const struct pnp_device_id pnp_dev_table[] = {
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
{ "AAC000F", 0 },
/* Anchor Datacomm BV */
/* SXPro 144 External Data Fax Modem Plug & Play */
{ "ADC0001", 0 },
/* SXPro 288 External Data Fax Modem Plug & Play */
{ "ADC0002", 0 },
/* PROLiNK 1456VH ISA PnP K56flex Fax Modem */
{ "AEI0250", 0 },
/* Actiontec ISA PNP 56K X2 Fax Modem */
{ "AEI1240", 0 },
/* Rockwell 56K ACF II Fax+Data+Voice Modem */
{ "AKY1021", 0 /*SPCI_FL_NO_SHIRQ*/ },
/* AZT3005 PnP SOUND DEVICE */
{ "AZT4001", 0 },
/* Best Data Products Inc. Smart One 336F PnP Modem */
{ "BDP3336", 0 },
/* Boca Research */
/* Boca Complete Ofc Communicator 14.4 Data-FAX */
{ "BRI0A49", 0 },
/* Boca Research 33,600 ACF Modem */
{ "BRI1400", 0 },
/* Boca 33.6 Kbps Internal FD34FSVD */
{ "BRI3400", 0 },
/* Boca 33.6 Kbps Internal FD34FSVD */
{ "BRI0A49", 0 },
/* Best Data Products Inc. Smart One 336F PnP Modem */
{ "BDP3336", 0 },
/* Computer Peripherals Inc */
/* EuroViVa CommCenter-33.6 SP PnP */
{ "CPI4050", 0 },
/* Creative Labs */
/* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
{ "CTL3001", 0 },
/* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
{ "CTL3011", 0 },
/* Davicom ISA 33.6K Modem */
{ "DAV0336", 0 },
/* Creative */
/* Creative Modem Blaster Flash56 DI5601-1 */
{ "DMB1032", 0 },
/* Creative Modem Blaster V.90 DI5660 */
{ "DMB2001", 0 },
/* E-Tech */
/* E-Tech CyberBULLET PC56RVP */
{ "ETT0002", 0 },
/* FUJITSU */
/* Fujitsu 33600 PnP-I2 R Plug & Play */
{ "FUJ0202", 0 },
/* Fujitsu FMV-FX431 Plug & Play */
{ "FUJ0205", 0 },
/* Fujitsu 33600 PnP-I4 R Plug & Play */
{ "FUJ0206", 0 },
/* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
{ "FUJ0209", 0 },
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
{ "GVC000F", 0 },
/* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
{ "GVC0303", 0 },
/* Hayes */
/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
{ "HAY0001", 0 },
/* Hayes Optima 336 V.34 + FAX + Voice PnP */
{ "HAY000C", 0 },
/* Hayes Optima 336B V.34 + FAX + Voice PnP */
{ "HAY000D", 0 },
/* Hayes Accura 56K Ext Fax Modem PnP */
{ "HAY5670", 0 },
/* Hayes Accura 56K Ext Fax Modem PnP */
{ "HAY5674", 0 },
/* Hayes Accura 56K Fax Modem PnP */
{ "HAY5675", 0 },
/* Hayes 288, V.34 + FAX */
{ "HAYF000", 0 },
/* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
{ "HAYF001", 0 },
/* IBM */
/* IBM Thinkpad 701 Internal Modem Voice */
{ "IBM0033", 0 },
/* Intermec */
/* Intermec CV60 touchscreen port */
{ "PNP4972", 0 },
/* Intertex */
/* Intertex 28k8 33k6 Voice EXT PnP */
{ "IXDC801", 0 },
/* Intertex 33k6 56k Voice EXT PnP */
{ "IXDC901", 0 },
/* Intertex 28k8 33k6 Voice SP EXT PnP */
{ "IXDD801", 0 },
/* Intertex 33k6 56k Voice SP EXT PnP */
{ "IXDD901", 0 },
/* Intertex 28k8 33k6 Voice SP INT PnP */
{ "IXDF401", 0 },
/* Intertex 28k8 33k6 Voice SP EXT PnP */
{ "IXDF801", 0 },
/* Intertex 33k6 56k Voice SP EXT PnP */
{ "IXDF901", 0 },
/* Kortex International */
/* KORTEX 28800 Externe PnP */
{ "KOR4522", 0 },
/* KXPro 33.6 Vocal ASVD PnP */
{ "KORF661", 0 },
/* Lasat */
/* LASAT Internet 33600 PnP */
{ "LAS4040", 0 },
/* Lasat Safire 560 PnP */
{ "LAS4540", 0 },
/* Lasat Safire 336 PnP */
{ "LAS5440", 0 },
/* Microcom, Inc. */
/* Microcom TravelPorte FAST V.34 Plug & Play */
{ "MNP0281", 0 },
/* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
{ "MNP0336", 0 },
/* Microcom DeskPorte FAST EP 28.8 Plug & Play */
{ "MNP0339", 0 },
/* Microcom DeskPorte 28.8P Plug & Play */
{ "MNP0342", 0 },
/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
{ "MNP0500", 0 },
/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
{ "MNP0501", 0 },
/* Microcom DeskPorte 28.8S Internal Plug & Play */
{ "MNP0502", 0 },
/* Motorola */
/* Motorola BitSURFR Plug & Play */
{ "MOT1105", 0 },
/* Motorola TA210 Plug & Play */
{ "MOT1111", 0 },
/* Motorola HMTA 200 (ISDN) Plug & Play */
{ "MOT1114", 0 },
/* Motorola BitSURFR Plug & Play */
{ "MOT1115", 0 },
/* Motorola Lifestyle 28.8 Internal */
{ "MOT1190", 0 },
/* Motorola V.3400 Plug & Play */
{ "MOT1501", 0 },
/* Motorola Lifestyle 28.8 V.34 Plug & Play */
{ "MOT1502", 0 },
/* Motorola Power 28.8 V.34 Plug & Play */
{ "MOT1505", 0 },
/* Motorola ModemSURFR External 28.8 Plug & Play */
{ "MOT1509", 0 },
/* Motorola Premier 33.6 Desktop Plug & Play */
{ "MOT150A", 0 },
/* Motorola VoiceSURFR 56K External PnP */
{ "MOT150F", 0 },
/* Motorola ModemSURFR 56K External PnP */
{ "MOT1510", 0 },
/* Motorola ModemSURFR 56K Internal PnP */
{ "MOT1550", 0 },
/* Motorola ModemSURFR Internal 28.8 Plug & Play */
{ "MOT1560", 0 },
/* Motorola Premier 33.6 Internal Plug & Play */
{ "MOT1580", 0 },
/* Motorola OnlineSURFR 28.8 Internal Plug & Play */
{ "MOT15B0", 0 },
/* Motorola VoiceSURFR 56K Internal PnP */
{ "MOT15F0", 0 },
/* Com 1 */
/* Deskline K56 Phone System PnP */
{ "MVX00A1", 0 },
/* PC Rider K56 Phone System PnP */
{ "MVX00F2", 0 },
/* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
{ "nEC8241", 0 },
/* Pace 56 Voice Internal Plug & Play Modem */
{ "PMC2430", 0 },
/* Generic */
/* Generic standard PC COM port */
{ "PNP0500", 0 },
/* Generic 16550A-compatible COM port */
{ "PNP0501", 0 },
/* Compaq 14400 Modem */
{ "PNPC000", 0 },
/* Compaq 2400/9600 Modem */
{ "PNPC001", 0 },
/* Dial-Up Networking Serial Cable between 2 PCs */
{ "PNPC031", 0 },
/* Dial-Up Networking Parallel Cable between 2 PCs */
{ "PNPC032", 0 },
/* Standard 9600 bps Modem */
{ "PNPC100", 0 },
/* Standard 14400 bps Modem */
{ "PNPC101", 0 },
/* Standard 28800 bps Modem*/
{ "PNPC102", 0 },
/* Standard Modem*/
{ "PNPC103", 0 },
/* Standard 9600 bps Modem*/
{ "PNPC104", 0 },
/* Standard 14400 bps Modem*/
{ "PNPC105", 0 },
/* Standard 28800 bps Modem*/
{ "PNPC106", 0 },
/* Standard Modem */
{ "PNPC107", 0 },
/* Standard 9600 bps Modem */
{ "PNPC108", 0 },
/* Standard 14400 bps Modem */
{ "PNPC109", 0 },
/* Standard 28800 bps Modem */
{ "PNPC10A", 0 },
/* Standard Modem */
{ "PNPC10B", 0 },
/* Standard 9600 bps Modem */
{ "PNPC10C", 0 },
/* Standard 14400 bps Modem */
{ "PNPC10D", 0 },
/* Standard 28800 bps Modem */
{ "PNPC10E", 0 },
/* Standard Modem */
{ "PNPC10F", 0 },
/* Standard PCMCIA Card Modem */
{ "PNP2000", 0 },
/* Rockwell */
/* Modular Technology */
/* Rockwell 33.6 DPF Internal PnP */
/* Modular Technology 33.6 Internal PnP */
{ "ROK0030", 0 },
/* Kortex International */
/* KORTEX 14400 Externe PnP */
{ "ROK0100", 0 },
/* Rockwell 28.8 */
{ "ROK4120", 0 },
/* Viking Components, Inc */
/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
{ "ROK4920", 0 },
/* Rockwell */
/* British Telecom */
/* Modular Technology */
/* Rockwell 33.6 DPF External PnP */
/* BT Prologue 33.6 External PnP */
/* Modular Technology 33.6 External PnP */
{ "RSS00A0", 0 },
/* Viking 56K FAX INT */
{ "RSS0262", 0 },
/* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */
{ "RSS0250", 0 },
/* SupraExpress 28.8 Data/Fax PnP modem */
{ "SUP1310", 0 },
/* SupraExpress 336i PnP Voice Modem */
{ "SUP1381", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1421", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1590", 0 },
/* SupraExpress 336i Sp ASVD */
{ "SUP1620", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1760", 0 },
/* SupraExpress 56i Sp Intl */
{ "SUP2171", 0 },
/* Phoebe Micro */
/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
{ "TEX0011", 0 },
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
{ "UAC000F", 0 },
/* 3Com Corp. */
/* Gateway Telepath IIvi 33.6 */
{ "USR0000", 0 },
/* U.S. Robotics Sporster 33.6K Fax INT PnP */
{ "USR0002", 0 },
/* Sportster Vi 14.4 PnP FAX Voicemail */
{ "USR0004", 0 },
/* U.S. Robotics 33.6K Voice INT PnP */
{ "USR0006", 0 },
/* U.S. Robotics 33.6K Voice EXT PnP */
{ "USR0007", 0 },
/* U.S. Robotics Courier V.Everything INT PnP */
{ "USR0009", 0 },
/* U.S. Robotics 33.6K Voice INT PnP */
{ "USR2002", 0 },
/* U.S. Robotics 56K Voice INT PnP */
{ "USR2070", 0 },
/* U.S. Robotics 56K Voice EXT PnP */
{ "USR2080", 0 },
/* U.S. Robotics 56K FAX INT */
{ "USR3031", 0 },
/* U.S. Robotics 56K FAX INT */
{ "USR3050", 0 },
/* U.S. Robotics 56K Voice INT PnP */
{ "USR3070", 0 },
/* U.S. Robotics 56K Voice EXT PnP */
{ "USR3080", 0 },
/* U.S. Robotics 56K Voice INT PnP */
{ "USR3090", 0 },
/* U.S. Robotics 56K Message */
{ "USR9100", 0 },
/* U.S. Robotics 56K FAX EXT PnP*/
{ "USR9160", 0 },
/* U.S. Robotics 56K FAX INT PnP*/
{ "USR9170", 0 },
/* U.S. Robotics 56K Voice EXT PnP*/
{ "USR9180", 0 },
/* U.S. Robotics 56K Voice INT PnP*/
{ "USR9190", 0 },
/* Wacom tablets */
{ "WACFXXX", 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 },
/* Fujitsu Wacom Tablet PC device */
{ "FUJ02E5", 0 },
/* Fujitsu P-series tablet PC device */
{ "FUJ02E6", 0 },
/* Fujitsu Wacom 2FGT Tablet PC device */
{ "FUJ02E7", 0 },
/* Fujitsu Wacom 1FGT Tablet PC device */
{ "FUJ02E9", 0 },
/*
* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
* disguise)
*/
{ "LTS0001", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unknown PnP modems */
{ "PNPCXXX", UNKNOWN_DEV },
/* More unknown PnP modems */
{ "PNPDXXX", UNKNOWN_DEV },
{ "", 0 }
};
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
static char *modem_names[] __devinitdata = {
"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
"56K", "56k", "K56", "33.6", "28.8", "14.4",
"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
"33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
};
static int __devinit check_name(char *name)
{
char **tmp;
for (tmp = modem_names; *tmp; tmp++)
if (strstr(name, *tmp))
return 1;
return 0;
}
static int __devinit check_resources(struct pnp_dev *dev)
{
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
int i;
for (i = 0; i < ARRAY_SIZE(base); i++) {
if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
return 1;
}
return 0;
}
/*
* Given a complete unknown PnP device, try to use some heuristics to
* detect modems. Currently use such heuristic set:
* - dev->name or dev->bus->name must contain "modem" substring;
* - device must have only one IO region (8 byte long) with base address
* 0x2e8, 0x3e8, 0x2f8 or 0x3f8.
*
* Such detection looks very ugly, but can detect at least some of numerous
* PnP modems, alternatively we must hardcode all modems in pnp_devices[]
* table.
*/
static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
{
if (!(check_name(pnp_dev_name(dev)) ||
(dev->card && check_name(dev->card->name))))
return -ENODEV;
if (check_resources(dev))
return 0;
return -ENODEV;
}
static int __devinit
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct uart_port port;
int ret, line, flags = dev_id->driver_data;
if (flags & UNKNOWN_DEV) {
ret = serial_pnp_guess_board(dev, &flags);
if (ret < 0)
return ret;
}
memset(&port, 0, sizeof(struct uart_port));
if (pnp_irq_valid(dev, 0))
port.irq = pnp_irq(dev, 0);
if (pnp_port_valid(dev, 0)) {
port.iobase = pnp_port_start(dev, 0);
port.iotype = UPIO_PORT;
} else if (pnp_mem_valid(dev, 0)) {
port.mapbase = pnp_mem_start(dev, 0);
port.iotype = UPIO_MEM;
port.flags = UPF_IOREMAP;
} else
return -ENODEV;
#ifdef SERIAL_DEBUG_PNP
printk(KERN_DEBUG
"Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
port.iobase, port.mapbase, port.irq, port.iotype);
#endif
port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
port.flags |= UPF_SHARE_IRQ;
port.uartclk = 1843200;
port.dev = &dev->dev;
line = serial8250_register_port(&port);
if (line < 0)
return -ENODEV;
pnp_set_drvdata(dev, (void *)((long)line + 1));
return 0;
}
static void __devexit serial_pnp_remove(struct pnp_dev *dev)
{
long line = (long)pnp_get_drvdata(dev);
if (line)
serial8250_unregister_port(line - 1);
}
#ifdef CONFIG_PM
static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
{
long line = (long)pnp_get_drvdata(dev);
if (!line)
return -ENODEV;
serial8250_suspend_port(line - 1);
return 0;
}
static int serial_pnp_resume(struct pnp_dev *dev)
{
long line = (long)pnp_get_drvdata(dev);
if (!line)
return -ENODEV;
serial8250_resume_port(line - 1);
return 0;
}
#else
#define serial_pnp_suspend NULL
#define serial_pnp_resume NULL
#endif /* CONFIG_PM */
static struct pnp_driver serial_pnp_driver = {
.name = "serial",
.probe = serial_pnp_probe,
.remove = __devexit_p(serial_pnp_remove),
.suspend = serial_pnp_suspend,
.resume = serial_pnp_resume,
.id_table = pnp_dev_table,
};
static int __init serial8250_pnp_init(void)
{
return pnp_register_driver(&serial_pnp_driver);
}
static void __exit serial8250_pnp_exit(void)
{
pnp_unregister_driver(&serial_pnp_driver);
}
module_init(serial8250_pnp_init);
module_exit(serial8250_pnp_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
+280
View File
@@ -0,0 +1,280 @@
#
# The 8250/16550 serial drivers. You shouldn't be in this list unless
# you somehow have an implicit or explicit dependency on SERIAL_8250.
#
config SERIAL_8250
tristate "8250/16550 and compatible serial support"
select SERIAL_CORE
---help---
This selects whether you want to include the driver for the standard
serial ports. The standard answer is Y. People who might say N
here are those that are setting up dedicated Ethernet WWW/FTP
servers, or users that have one of the various bus mice instead of a
serial mouse and don't intend to use their machine's standard serial
port for anything. (Note that the Cyclades and Stallion multi
serial port drivers do not need this driver built in for them to
work.)
To compile this driver as a module, choose M here: the
module will be called 8250.
[WARNING: Do not compile this driver as a module if you are using
non-standard serial ports, since the configuration information will
be lost when the driver is unloaded. This limitation may be lifted
in the future.]
BTW1: If you have a mouseman serial mouse which is not recognized by
the X window system, try running gpm first.
BTW2: If you intend to use a software modem (also called Winmodem)
under Linux, forget it. These modems are crippled and require
proprietary drivers which are only available under Windows.
Most people will say Y or M here, so that they can use serial mice,
modems and similar devices connecting to the standard serial ports.
config SERIAL_8250_CONSOLE
bool "Console on 8250/16550 and compatible serial port"
depends on SERIAL_8250=y
select SERIAL_CORE_CONSOLE
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). This could be useful if some terminal or printer is connected
to that serial port.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttyS1". (Try "man bootparam" or see the documentation of
your boot loader (grub or lilo or loadlin) about how to pass options
to the kernel at boot time.)
If you don't have a VGA card installed and you say Y here, the
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
You can set that using a kernel command line option such as
"console=uart8250,io,0x3f8,9600n8"
"console=uart8250,mmio,0xff5e0000,115200n8".
and it will switch to normal serial console when the corresponding
port is ready.
"earlycon=uart8250,io,0x3f8,9600n8"
"earlycon=uart8250,mmio,0xff5e0000,115200n8".
it will not only setup early console.
If unsure, say N.
config FIX_EARLYCON_MEM
bool
depends on X86
default y
config SERIAL_8250_GSC
tristate
depends on SERIAL_8250 && GSC
default SERIAL_8250
config SERIAL_8250_PCI
tristate "8250/16550 PCI device support" if EXPERT
depends on SERIAL_8250 && PCI
default SERIAL_8250
help
This builds standard PCI serial support. You may be able to
disable this feature if you only need legacy serial support.
Saves about 9K.
config SERIAL_8250_PNP
tristate "8250/16550 PNP device support" if EXPERT
depends on SERIAL_8250 && PNP
default SERIAL_8250
help
This builds standard PNP serial support. You may be able to
disable this feature if you only need legacy serial support.
config SERIAL_8250_HP300
tristate
depends on SERIAL_8250 && HP300
default SERIAL_8250
config SERIAL_8250_CS
tristate "8250/16550 PCMCIA device support"
depends on PCMCIA && SERIAL_8250
---help---
Say Y here to enable support for 16-bit PCMCIA serial devices,
including serial port cards, modems, and the modem functions of
multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
credit-card size devices often used with laptops.)
To compile this driver as a module, choose M here: the
module will be called serial_cs.
If unsure, say N.
config SERIAL_8250_NR_UARTS
int "Maximum number of 8250/16550 serial ports"
depends on SERIAL_8250
default "4"
help
Set this to the number of serial ports you want the driver
to support. This includes any ports discovered via ACPI or
PCI enumeration and any ports that may be added at run-time
via hot-plug, or any ISA multi-port serial cards.
config SERIAL_8250_RUNTIME_UARTS
int "Number of 8250/16550 serial ports to register at runtime"
depends on SERIAL_8250
range 0 SERIAL_8250_NR_UARTS
default "4"
help
Set this to the maximum number of serial ports you want
the kernel to register at boot time. This can be overridden
with the module parameter "nr_uarts", or boot-time parameter
8250.nr_uarts
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250
help
If you wish to use any non-standard features of the standard "dumb"
driver, say Y here. This includes HUB6 support, shared serial
interrupts, special multiport support, support for more than the
four COM 1/2/3/4 boards, etc.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about serial driver options. If unsure, say N.
config SERIAL_8250_MANY_PORTS
bool "Support more than 4 legacy serial ports"
depends on SERIAL_8250_EXTENDED && !IA64
help
Say Y here if you have dumb serial boards other than the four
standard COM 1/2/3/4 ports. This may happen if you have an AST
FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
from <http://www.tldp.org/docs.html#howto>), or other custom
serial port hardware which acts similar to standard serial port
hardware. If you only use the standard COM 1/2/3/4 ports, you can
say N here to save some memory. You can also say Y if you have an
"intelligent" multiport card such as Cyclades, Digiboards, etc.
#
# Multi-port serial cards
#
config SERIAL_8250_FOURPORT
tristate "Support Fourport cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have an AST FourPort serial board.
To compile this driver as a module, choose M here: the module
will be called 8250_fourport.
config SERIAL_8250_ACCENT
tristate "Support Accent cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have an Accent Async serial board.
To compile this driver as a module, choose M here: the module
will be called 8250_accent.
config SERIAL_8250_BOCA
tristate "Support Boca cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have a Boca serial board. Please read the Boca
mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
To compile this driver as a module, choose M here: the module
will be called 8250_boca.
config SERIAL_8250_EXAR_ST16C554
tristate "Support Exar ST16C554/554D Quad UART"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
The Uplogix Envoy TU301 uses this Exar Quad UART. If you are
tinkering with your Envoy TU301, or have a machine with this UART,
say Y here.
To compile this driver as a module, choose M here: the module
will be called 8250_exar_st16c554.
config SERIAL_8250_HUB6
tristate "Support Hub6 cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have a HUB6 serial board.
To compile this driver as a module, choose M here: the module
will be called 8250_hub6.
#
# Misc. options/drivers.
#
config SERIAL_8250_SHARE_IRQ
bool "Support for sharing serial interrupts"
depends on SERIAL_8250_EXTENDED
help
Some serial boards have hardware support which allows multiple dumb
serial ports on the same board to share a single IRQ. To enable
support for this in the serial driver, say Y here.
config SERIAL_8250_DETECT_IRQ
bool "Autodetect IRQ on standard ports (unsafe)"
depends on SERIAL_8250_EXTENDED
help
Say Y here if you want the kernel to try to guess which IRQ
to use for your serial port.
This is considered unsafe; it is far better to configure the IRQ in
a boot script using the setserial command.
If unsure, say N.
config SERIAL_8250_RSA
bool "Support RSA serial ports"
depends on SERIAL_8250_EXTENDED
help
::: To be written :::
config SERIAL_8250_MCA
tristate "Support 8250-type ports on MCA buses"
depends on SERIAL_8250 != n && MCA
help
Say Y here if you have a MCA serial ports.
To compile this driver as a module, choose M here: the module
will be called 8250_mca.
config SERIAL_8250_ACORN
tristate "Acorn expansion card serial port support"
depends on ARCH_ACORN && SERIAL_8250
help
If you have an Atomwide Serial card or Serial Port card for an Acorn
system, say Y to this option. The driver can handle 1, 2, or 3 port
cards. If unsure, say N.
config SERIAL_8250_RM9K
bool "Support for MIPS RM9xxx integrated serial port"
depends on SERIAL_8250 != n && SERIAL_RM9000
select SERIAL_8250_SHARE_IRQ
help
Selecting this option will add support for the integrated serial
port hardware found on MIPS RM9122 and similar processors.
If unsure, say N.
config SERIAL_8250_FSL
bool
depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550
default PPC
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.
+20
View File
@@ -0,0 +1,20 @@
#
# Makefile for the 8250 serial device drivers.
#
obj-$(CONFIG_SERIAL_8250) += 8250.o
obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
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_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
+869
View File
@@ -0,0 +1,869 @@
/*======================================================================
A driver for PCMCIA serial devices
serial_cs.c 1.134 2002/05/04 05:48:53
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The initial developer of the original code is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds
are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
Alternatively, the contents of this file may be used under the
terms of the GNU General Public License version 2 (the "GPL"), in which
case the provisions of the GPL are applicable instead of the
above. If you wish to allow the use of your version of this file
only under the terms of the GPL and not to allow others to use
your version of this file under the MPL, indicate your decision
by deleting the provisions above and replace them with the notice
and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this
file under either the MPL or the GPL.
======================================================================*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <asm/io.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#include "8250.h"
/*====================================================================*/
/* Parameters that can be set with 'insmod' */
/* Enable the speaker? */
static int do_sound = 1;
/* Skip strict UART tests? */
static int buggy_uart;
module_param(do_sound, int, 0444);
module_param(buggy_uart, int, 0444);
/*====================================================================*/
/* Table of multi-port card ID's */
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 *);
};
struct serial_info {
struct pcmcia_device *p_dev;
int ndev;
int multi;
int slave;
int manfid;
int prodid;
int c950ctrl;
int line[4];
const struct serial_quirk *quirk;
};
struct serial_cfg_mem {
tuple_t tuple;
cisparse_t parse;
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.
*/
/* Generic Modem: MD55x (GPRS/EDGE) have
* Elan VPU16551 UART with 14.7456MHz oscillator
* manfid 0x015D, 0x4C45
*/
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)
{
u8 val;
int ret;
ret = pcmcia_read_config_byte(link, 0x800, &val);
if (ret)
goto failed;
ret = pcmcia_write_config_byte(link, 0x800, val | 1);
if (ret)
goto failed;
return 0;
failed:
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;
if (info->c950ctrl)
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->config_flags |= CONF_ENABLE_ESR;
}
static const struct serial_quirk quirks[] = {
{
.manfid = 0x0160,
.prodid = 0x0104,
.multi = -1,
.setup = quirk_setup_brainboxes_0104,
}, {
.manfid = 0x015D,
.prodid = 0x4C45,
.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_DUAL_RS232_G,
.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 serial_remove(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
int i;
dev_dbg(&link->dev, "serial_release\n");
/*
* Recheck to see if the device is still configured.
*/
for (i = 0; i < info->ndev; i++)
serial8250_unregister_port(info->line[i]);
if (!info->slave)
pcmcia_disable_device(link);
}
static int serial_suspend(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
int i;
for (i = 0; i < info->ndev; i++)
serial8250_suspend_port(info->line[i]);
return 0;
}
static int serial_resume(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
int i;
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;
}
static int serial_probe(struct pcmcia_device *link)
{
struct serial_info *info;
dev_dbg(&link->dev, "serial_attach()\n");
/* Create new serial device */
info = kzalloc(sizeof (*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->p_dev = link;
link->priv = info;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
if (do_sound)
link->config_flags |= CONF_ENABLE_SPKR;
return serial_config(link);
}
static void serial_detach(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
dev_dbg(&link->dev, "serial_detach\n");
/*
* Ensure that the ports have been released.
*/
serial_remove(link);
/* free bits */
kfree(info);
}
/*====================================================================*/
static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
unsigned int iobase, int irq)
{
struct uart_port port;
int line;
memset(&port, 0, sizeof (struct uart_port));
port.iobase = iobase;
port.irq = irq;
port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
port.uartclk = 1843200;
port.dev = &handle->dev;
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 "
"0x%04lx, irq %d failed\n", (u_long)iobase, irq);
return -EINVAL;
}
info->line[info->ndev] = line;
info->ndev++;
return 0;
}
/*====================================================================*/
static int pfc_config(struct pcmcia_device *p_dev)
{
unsigned int port = 0;
struct serial_info *info = p_dev->priv;
if ((p_dev->resource[1]->end != 0) &&
(resource_size(p_dev->resource[1]) == 8)) {
port = p_dev->resource[1]->start;
info->slave = 1;
} else if ((info->manfid == MANFID_OSITECH) &&
(resource_size(p_dev->resource[0]) == 0x40)) {
port = p_dev->resource[0]->start + 0x28;
info->slave = 1;
}
if (info->slave)
return setup_serial(p_dev, info, port, p_dev->irq);
dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
return -ENODEV;
}
static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
{
static const int size_table[2] = { 8, 16 };
int *try = priv_data;
if (p_dev->resource[0]->start == 0)
return -ENODEV;
if ((*try & 0x1) == 0)
p_dev->io_lines = 16;
if (p_dev->resource[0]->end != size_table[(*try >> 1)])
return -ENODEV;
p_dev->resource[0]->end = 8;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return pcmcia_request_io(p_dev);
}
static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
void *priv_data)
{
static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j;
if (p_dev->io_lines > 3)
return -ENODEV;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = 8;
for (j = 0; j < 5; j++) {
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
}
static int simple_config(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
int i = -ENODEV, try;
/* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */
link->config_flags |= CONF_AUTO_SET_VPP;
for (try = 0; try < 4; try++)
if (!pcmcia_loop_config(link, simple_config_check, &try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
goto found_port;
dev_warn(&link->dev, "no usable port range found, giving up\n");
return -1;
found_port:
if (info->multi && (info->manfid == MANFID_3COM))
link->config_index &= ~(0x08);
/*
* Apply any configuration quirks.
*/
if (info->quirk && info->quirk->config)
info->quirk->config(link);
i = pcmcia_enable_device(link);
if (i != 0)
return -1;
return setup_serial(link, info, link->resource[0]->start, link->irq);
}
static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
{
int *multi = priv_data;
if (p_dev->resource[1]->end)
return -EINVAL;
/* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */
if (p_dev->resource[0]->end <= 8)
return -EINVAL;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = *multi * 8;
if (pcmcia_request_io(p_dev))
return -ENODEV;
return 0;
}
static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
void *priv_data)
{
int *base2 = priv_data;
if (!p_dev->resource[0]->end || !p_dev->resource[1]->end ||
p_dev->resource[0]->start + 8 != p_dev->resource[1]->start)
return -ENODEV;
p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
if (pcmcia_request_io(p_dev))
return -ENODEV;
*base2 = p_dev->resource[0]->start + 8;
return 0;
}
static int multi_config(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
int i, base2 = 0;
/* First, look for a generic full-sized window */
if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
base2 = link->resource[0]->start + 8;
else {
/* If that didn't work, look for two windows */
info->multi = 2;
if (pcmcia_loop_config(link, multi_config_check_notpicky,
&base2)) {
dev_warn(&link->dev, "no usable port range "
"found, giving up\n");
return -ENODEV;
}
}
if (!link->irq)
dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
/*
* Apply any configuration quirks.
*/
if (info->quirk && info->quirk->config)
info->quirk->config(link);
i = pcmcia_enable_device(link);
if (i != 0)
return -ENODEV;
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
* 8 registers are for the UART, the others are extra registers.
* Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
*/
if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
info->prodid == PRODID_POSSIO_GCC)) {
int err;
if (link->config_index == 1 ||
link->config_index == 3) {
err = setup_serial(link, info, base2,
link->irq);
base2 = link->resource[0]->start;
} else {
err = setup_serial(link, info, link->resource[0]->start,
link->irq);
}
info->c950ctrl = base2;
/*
* 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);
return 0;
}
setup_serial(link, info, link->resource[0]->start, link->irq);
for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i),
link->irq);
return 0;
}
static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data)
{
struct serial_info *info = p_dev->priv;
if (!p_dev->resource[0]->end)
return -EINVAL;
if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
info->multi = p_dev->resource[0]->end >> 3;
if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
&& (p_dev->resource[1]->end == 8))
info->multi = 2;
return 0; /* break */
}
static int serial_config(struct pcmcia_device * link)
{
struct serial_info *info = link->priv;
int i;
dev_dbg(&link->dev, "serial_config\n");
/* Is this a compliant multifunction card? */
info->multi = (link->socket->functions > 1);
/* Is this a multiport card? */
info->manfid = link->manf_id;
info->prodid = link->card_id;
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;
}
/* Another check for dual-serial cards: look for either serial or
multifunction cards that ask for appropriate IO port ranges */
if ((info->multi == 0) &&
(link->has_func_id) &&
(link->socket->pcmcia_pfc == 0) &&
((link->func_id == CISTPL_FUNCID_MULTI) ||
(link->func_id == CISTPL_FUNCID_SERIAL)))
pcmcia_loop_config(link, serial_check_for_multi, info);
/*
* Apply any multi-port quirk.
*/
if (info->quirk && info->quirk->multi != -1)
info->multi = info->quirk->multi;
dev_info(&link->dev,
"trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
link->manf_id, link->card_id,
link->socket->pcmcia_pfc, info->multi, info->quirk);
if (link->socket->pcmcia_pfc)
i = pfc_config(link);
else if (info->multi > 1)
i = multi_config(link);
else
i = simple_config(link);
if (i || info->ndev == 0)
goto 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;
return 0;
failed:
dev_warn(&link->dev, "failed to initialize\n");
serial_remove(link);
return -ENODEV;
}
static const struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05),
PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */
PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */
PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */
PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */
PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */
PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */
PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */
PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b),
PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447),
PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41),
PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38),
PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676),
PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767),
PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
/* too generic */
/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
PCMCIA_DEVICE_FUNC_ID(2),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, serial_ids);
MODULE_FIRMWARE("cis/PCMLM28.cis");
MODULE_FIRMWARE("cis/DP83903.cis");
MODULE_FIRMWARE("cis/3CCFEM556.cis");
MODULE_FIRMWARE("cis/3CXEM556.cis");
MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
MODULE_FIRMWARE("cis/SW_555_SER.cis");
MODULE_FIRMWARE("cis/MT5634ZLX.cis");
MODULE_FIRMWARE("cis/COMpad2.cis");
MODULE_FIRMWARE("cis/COMpad4.cis");
MODULE_FIRMWARE("cis/RS-COM-2P.cis");
static struct pcmcia_driver serial_cs_driver = {
.owner = THIS_MODULE,
.name = "serial_cs",
.probe = serial_probe,
.remove = serial_detach,
.id_table = serial_ids,
.suspend = serial_suspend,
.resume = serial_resume,
};
static int __init init_serial_cs(void)
{
return pcmcia_register_driver(&serial_cs_driver);
}
static void __exit exit_serial_cs(void)
{
pcmcia_unregister_driver(&serial_cs_driver);
}
module_init(init_serial_cs);
module_exit(exit_serial_cs);
MODULE_LICENSE("GPL");