Commit 85b34e48 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-serial

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 0f31b37c 2a2b8976
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/8250.h> #include <linux/serial_8250.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -901,7 +901,7 @@ static int __init set_preferred_console(void) ...@@ -901,7 +901,7 @@ static int __init set_preferred_console(void)
DBG("Found serial console at ttyS%d\n", offset); DBG("Found serial console at ttyS%d\n", offset);
if (spd) { if (spd) {
char opt[16]; static char __initdata opt[16];
sprintf(opt, "%d", *spd); sprintf(opt, "%d", *spd);
return add_preferred_console("ttyS", offset, opt); return add_preferred_console("ttyS", offset, opt);
} else } else
...@@ -1123,8 +1123,8 @@ __setup("decr_overclock=", set_decr_overclock ); ...@@ -1123,8 +1123,8 @@ __setup("decr_overclock=", set_decr_overclock );
*/ */
#define MAX_LEGACY_SERIAL_PORTS 8 #define MAX_LEGACY_SERIAL_PORTS 8
static struct old_serial_port old_serial_ports[MAX_LEGACY_SERIAL_PORTS]; static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
static unsigned int old_serial_count; static unsigned int old_serial_count;
void __init generic_find_legacy_serial_ports(unsigned int *default_speed) void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
{ {
...@@ -1202,13 +1202,13 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed) ...@@ -1202,13 +1202,13 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
if (index >= old_serial_count) if (index >= old_serial_count)
old_serial_count = index + 1; old_serial_count = index + 1;
/* Check if there is a port who already claimed our slot */ /* Check if there is a port who already claimed our slot */
if (old_serial_ports[index].port != 0) { if (serial_ports[index].iobase != 0) {
/* if we still have some room, move it, else override */ /* if we still have some room, move it, else override */
if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) { if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
DBG("Moved legacy port %d -> %d\n", index, DBG("Moved legacy port %d -> %d\n", index,
old_serial_count); old_serial_count);
old_serial_ports[old_serial_count++] = serial_ports[old_serial_count++] =
old_serial_ports[index]; serial_ports[index];
} else { } else {
DBG("Replacing legacy port %d\n", index); DBG("Replacing legacy port %d\n", index);
} }
...@@ -1220,18 +1220,17 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed) ...@@ -1220,18 +1220,17 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
old_serial_count = index + 1; old_serial_count = index + 1;
/* Now fill the entry */ /* Now fill the entry */
memset(&old_serial_ports[index], 0, sizeof(struct old_serial_port)); memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
old_serial_ports[index].uart = 0; serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
old_serial_ports[index].baud_base = clk ? (*clk / 16) : BASE_BAUD; serial_ports[index].iobase = reg->address;
old_serial_ports[index].port = reg->address; serial_ports[index].irq = interrupts ? interrupts[0] : 0;
old_serial_ports[index].irq = interrupts ? interrupts[0] : 0; serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
old_serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
index, index,
old_serial_ports[index].port, serial_ports[index].iobase,
old_serial_ports[index].irq, serial_ports[index].irq,
old_serial_ports[index].baud_base * 16); serial_ports[index].uartclk);
/* Get phys address of IO reg for port 1 */ /* Get phys address of IO reg for port 1 */
if (index != 0) if (index != 0)
...@@ -1279,19 +1278,21 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed) ...@@ -1279,19 +1278,21 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
DBG(" <- generic_find_legacy_serial_port()\n"); DBG(" <- generic_find_legacy_serial_port()\n");
} }
struct old_serial_port *get_legacy_serial_ports(unsigned int *count) static struct platform_device serial_device = {
{ .name = "serial8250",
*count = old_serial_count; .id = 0,
return old_serial_ports; .dev = {
} .platform_data = serial_ports,
#else },
struct old_serial_port *get_legacy_serial_ports(unsigned int *count) };
static int __init serial_dev_init(void)
{ {
*count = 0; return platform_device_register(&serial_device);
return 0;
} }
arch_initcall(serial_dev_init);
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
EXPORT_SYMBOL(get_legacy_serial_ports);
int check_legacy_ioport(unsigned long base_port) int check_legacy_ioport(unsigned long base_port)
{ {
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -997,7 +998,7 @@ static void send_break( struct m68k_serial * info, int duration) ...@@ -997,7 +998,7 @@ static void send_break( struct m68k_serial * info, int duration)
unsigned long flags; unsigned long flags;
if (!info->port) if (!info->port)
return; return;
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
save_flags(flags); save_flags(flags);
cli(); cli();
#ifdef USE_INTS #ifdef USE_INTS
...@@ -1189,8 +1190,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -1189,8 +1190,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
#endif #endif
if (info->blocked_open) { if (info->blocked_open) {
if (info->close_delay) { if (info->close_delay) {
current->state = TASK_INTERRUPTIBLE; msleep_interruptible(jiffies_to_msecs(info->close_delay));
schedule_timeout(info->close_delay);
} }
wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait);
} }
......
...@@ -1396,7 +1396,7 @@ static void end_break(ser_info_t *info) ...@@ -1396,7 +1396,7 @@ static void end_break(ser_info_t *info)
*/ */
static void send_break(ser_info_t *info, int duration) static void send_break(ser_info_t *info, int duration)
{ {
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
#ifdef SERIAL_DEBUG_SEND_BREAK #ifdef SERIAL_DEBUG_SEND_BREAK
printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
#endif #endif
...@@ -1707,8 +1707,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp) ...@@ -1707,8 +1707,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
info->tty = 0; info->tty = 0;
if (info->blocked_open) { if (info->blocked_open) {
if (info->close_delay) { if (info->close_delay) {
current->state = TASK_INTERRUPTIBLE; msleep_interruptible(jiffies_to_msecs(info->close_delay));
schedule_timeout(info->close_delay);
} }
wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait);
} }
...@@ -1761,9 +1760,8 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) ...@@ -1761,9 +1760,8 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies); printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
#endif #endif
current->state = TASK_INTERRUPTIBLE;
/* current->counter = 0; make us low-priority */ /* current->counter = 0; make us low-priority */
schedule_timeout(char_time); msleep_interruptible(jiffies_to_msecs(char_time));
if (signal_pending(current)) if (signal_pending(current))
break; break;
if (timeout && ((orig_jiffies + timeout) < jiffies)) if (timeout && ((orig_jiffies + timeout) < jiffies))
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
#include <linux/sysrq.h> #include <linux/sysrq.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serialP.h> #include <linux/serial_8250.h>
#include <linux/circ_buf.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/8250.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#endif #endif
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include "8250.h"
/* /*
* Configuration: * Configuration:
...@@ -112,17 +113,11 @@ unsigned int share_irqs = SERIAL8250_SHARE_IRQS; ...@@ -112,17 +113,11 @@ unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
#define SERIAL_PORT_DFNS #define SERIAL_PORT_DFNS
#endif #endif
#ifndef ARCH_HAS_GET_LEGACY_SERIAL_PORTS
static struct old_serial_port old_serial_port[] = { static struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */ SERIAL_PORT_DFNS /* defined in asm/serial.h */
}; };
static inline struct old_serial_port *get_legacy_serial_ports(unsigned int *count)
{
*count = ARRAY_SIZE(old_serial_port);
return old_serial_port;
}
#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) #define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
#endif /* ARCH_HAS_DYNAMIC_LEGACY_SERIAL_PORTS */
#ifdef CONFIG_SERIAL_8250_RSA #ifdef CONFIG_SERIAL_8250_RSA
...@@ -1158,7 +1153,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r ...@@ -1158,7 +1153,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r
{ {
struct irq_info *i = dev_id; struct irq_info *i = dev_id;
struct list_head *l, *end = NULL; struct list_head *l, *end = NULL;
int pass_counter = 0; int pass_counter = 0, handled = 0;
DEBUG_INTR("serial8250_interrupt(%d)...", irq); DEBUG_INTR("serial8250_interrupt(%d)...", irq);
...@@ -1177,6 +1172,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r ...@@ -1177,6 +1172,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r
serial8250_handle_port(up, regs); serial8250_handle_port(up, regs);
spin_unlock(&up->port.lock); spin_unlock(&up->port.lock);
handled = 1;
end = NULL; end = NULL;
} else if (end == NULL) } else if (end == NULL)
end = l; end = l;
...@@ -1194,8 +1191,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r ...@@ -1194,8 +1191,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r
spin_unlock(&i->lock); spin_unlock(&i->lock);
DEBUG_INTR("end.\n"); DEBUG_INTR("end.\n");
/* FIXME! Was it really ours? */
return IRQ_HANDLED; return IRQ_RETVAL(handled);
} }
/* /*
...@@ -1738,147 +1735,130 @@ serial8250_pm(struct uart_port *port, unsigned int state, ...@@ -1738,147 +1735,130 @@ serial8250_pm(struct uart_port *port, unsigned int state,
} }
/* /*
* Resource handling. This is complicated by the fact that resources * Resource handling.
* depend on the port type. Maybe we should be claiming the standard
* 8250 ports, and then trying to get other resources as necessary?
*/ */
static int static int serial8250_request_std_resource(struct uart_8250_port *up)
serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res)
{ {
unsigned int size = 8 << up->port.regshift; unsigned int size = 8 << up->port.regshift;
int ret = 0; int ret = 0;
switch (up->port.iotype) { switch (up->port.iotype) {
case UPIO_MEM: case UPIO_MEM:
if (up->port.mapbase) { if (!up->port.mapbase)
*res = request_mem_region(up->port.mapbase, size, "serial"); break;
if (!*res)
ret = -EBUSY; if (!request_mem_region(up->port.mapbase, size, "serial")) {
ret = -EBUSY;
break;
}
if (up->port.flags & UPF_IOREMAP) {
up->port.membase = ioremap(up->port.mapbase, size);
if (!up->port.membase) {
release_mem_region(up->port.mapbase, size);
ret = -ENOMEM;
}
} }
break; break;
case UPIO_HUB6: case UPIO_HUB6:
case UPIO_PORT: case UPIO_PORT:
*res = request_region(up->port.iobase, size, "serial"); if (!request_region(up->port.iobase, size, "serial"))
if (!*res)
ret = -EBUSY; ret = -EBUSY;
break; break;
} }
return ret; return ret;
} }
static int static void serial8250_release_std_resource(struct uart_8250_port *up)
serial8250_request_rsa_resource(struct uart_8250_port *up, struct resource **res)
{ {
unsigned int size = 8 << up->port.regshift; unsigned int size = 8 << up->port.regshift;
unsigned long start;
int ret = 0;
switch (up->port.iotype) { switch (up->port.iotype) {
case UPIO_MEM: case UPIO_MEM:
if (up->port.mapbase) { if (!up->port.mapbase)
start = up->port.mapbase; break;
start += UART_RSA_BASE << up->port.regshift;
*res = request_mem_region(start, size, "serial-rsa"); if (up->port.flags & UPF_IOREMAP) {
if (!*res) iounmap(up->port.membase);
ret = -EBUSY; up->port.membase = NULL;
} }
release_mem_region(up->port.mapbase, size);
break; break;
case UPIO_HUB6: case UPIO_HUB6:
case UPIO_PORT: case UPIO_PORT:
start = up->port.iobase; release_region(up->port.iobase, size);
start += UART_RSA_BASE << up->port.regshift;
*res = request_region(start, size, "serial-rsa");
if (!*res)
ret = -EBUSY;
break; break;
} }
return ret;
} }
static void serial8250_release_port(struct uart_port *port) static int serial8250_request_rsa_resource(struct uart_8250_port *up)
{ {
struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned long start = UART_RSA_BASE << up->port.regshift;
unsigned long start, offset = 0, size = 0; unsigned int size = 8 << up->port.regshift;
int ret = 0;
if (up->port.type == PORT_RSA) {
offset = UART_RSA_BASE << up->port.regshift;
size = 8;
}
size <<= up->port.regshift;
switch (up->port.iotype) { switch (up->port.iotype) {
case UPIO_MEM: case UPIO_MEM:
if (up->port.mapbase) { ret = -EINVAL;
/*
* Unmap the area.
*/
iounmap(up->port.membase);
up->port.membase = NULL;
start = up->port.mapbase;
if (size)
release_mem_region(start + offset, size);
release_mem_region(start, 8 << up->port.regshift);
}
break; break;
case UPIO_HUB6: case UPIO_HUB6:
case UPIO_PORT: case UPIO_PORT:
start = up->port.iobase; start += up->port.iobase;
if (!request_region(start, size, "serial-rsa"))
ret = -EBUSY;
break;
}
if (size) return ret;
release_region(start + offset, size); }
release_region(start + offset, 8 << up->port.regshift);
static void serial8250_release_rsa_resource(struct uart_8250_port *up)
{
unsigned long offset = UART_RSA_BASE << up->port.regshift;
unsigned int size = 8 << up->port.regshift;
switch (up->port.iotype) {
case UPIO_MEM:
break; break;
default: case UPIO_HUB6:
case UPIO_PORT:
release_region(up->port.iobase + offset, size);
break; break;
} }
} }
static void serial8250_release_port(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
serial8250_release_std_resource(up);
if (up->port.type == PORT_RSA)
serial8250_release_rsa_resource(up);
}
static int serial8250_request_port(struct uart_port *port) static int serial8250_request_port(struct uart_port *port)
{ {
struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_8250_port *up = (struct uart_8250_port *)port;
struct resource *res = NULL, *res_rsa = NULL;
int ret = 0; int ret = 0;
if (up->port.type == PORT_RSA) { ret = serial8250_request_std_resource(up);
ret = serial8250_request_rsa_resource(up, &res_rsa); if (ret == 0 && up->port.type == PORT_RSA) {
ret = serial8250_request_rsa_resource(up);
if (ret < 0) if (ret < 0)
return ret; serial8250_release_std_resource(up);
} }
ret = serial8250_request_std_resource(up, &res);
/*
* If we have a mapbase, then request that as well.
*/
if (ret == 0 && up->port.flags & UPF_IOREMAP) {
int size = res->end - res->start + 1;
up->port.membase = ioremap(up->port.mapbase, size);
if (!up->port.membase)
ret = -ENOMEM;
}
if (ret < 0) {
if (res_rsa)
release_resource(res_rsa);
if (res)
release_resource(res);
}
return ret; return ret;
} }
static void serial8250_config_port(struct uart_port *port, int flags) static void serial8250_config_port(struct uart_port *port, int flags)
{ {
struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_8250_port *up = (struct uart_8250_port *)port;
struct resource *res_std = NULL, *res_rsa = NULL;
int probeflags = PROBE_ANY; int probeflags = PROBE_ANY;
int ret; int ret;
...@@ -1894,11 +1874,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) ...@@ -1894,11 +1874,11 @@ static void serial8250_config_port(struct uart_port *port, int flags)
* Find the region that we can probe for. This in turn * Find the region that we can probe for. This in turn
* tells us whether we can probe for the type of port. * tells us whether we can probe for the type of port.
*/ */
ret = serial8250_request_std_resource(up, &res_std); ret = serial8250_request_std_resource(up);
if (ret < 0) if (ret < 0)
return; return;
ret = serial8250_request_rsa_resource(up, &res_rsa); ret = serial8250_request_rsa_resource(up);
if (ret < 0) if (ret < 0)
probeflags &= ~PROBE_RSA; probeflags &= ~PROBE_RSA;
...@@ -1907,14 +1887,10 @@ static void serial8250_config_port(struct uart_port *port, int flags) ...@@ -1907,14 +1887,10 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
autoconfig_irq(up); autoconfig_irq(up);
/* if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
* If the port wasn't an RSA port, release the resource. serial8250_release_rsa_resource(up);
*/ if (up->port.type == PORT_UNKNOWN)
if (up->port.type != PORT_RSA && res_rsa) serial8250_release_std_resource(up);
release_resource(res_rsa);
if (up->port.type == PORT_UNKNOWN && res_std)
release_resource(res_std);
} }
static int static int
...@@ -1964,28 +1940,40 @@ static void __init serial8250_isa_init_ports(void) ...@@ -1964,28 +1940,40 @@ static void __init serial8250_isa_init_ports(void)
{ {
struct uart_8250_port *up; struct uart_8250_port *up;
static int first = 1; static int first = 1;
struct old_serial_port *old_ports;
int count;
int i; int i;
if (!first) if (!first)
return; return;
first = 0; first = 0;
old_ports = get_legacy_serial_ports(&count); for (i = 0; i < UART_NR; i++) {
if (old_ports == NULL) struct uart_8250_port *up = &serial8250_ports[i];
return;
up->port.line = i;
spin_lock_init(&up->port.lock);
init_timer(&up->timer);
up->timer.function = serial8250_timeout;
/*
* ALPHA_KLUDGE_MCR needs to be killed.
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
up->mcr_force = ALPHA_KLUDGE_MCR;
up->port.ops = &serial8250_pops;
}
for (i = 0, up = serial8250_ports; i < count; i++, up++) { for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
up->port.iobase = old_ports[i].port; i++, up++) {
up->port.irq = irq_canonicalize(old_ports[i].irq); up->port.iobase = old_serial_port[i].port;
up->port.uartclk = old_ports[i].baud_base * 16; up->port.irq = irq_canonicalize(old_serial_port[i].irq);
up->port.flags = old_ports[i].flags; up->port.uartclk = old_serial_port[i].baud_base * 16;
up->port.hub6 = old_ports[i].hub6; up->port.flags = old_serial_port[i].flags;
up->port.membase = old_ports[i].iomem_base; up->port.hub6 = old_serial_port[i].hub6;
up->port.iotype = old_ports[i].io_type; up->port.membase = old_serial_port[i].iomem_base;
up->port.regshift = old_ports[i].iomem_reg_shift; up->port.iotype = old_serial_port[i].io_type;
up->port.ops = &serial8250_pops; up->port.regshift = old_serial_port[i].iomem_reg_shift;
if (share_irqs) if (share_irqs)
up->port.flags |= UPF_SHARE_IRQ; up->port.flags |= UPF_SHARE_IRQ;
} }
...@@ -2001,18 +1989,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) ...@@ -2001,18 +1989,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
for (i = 0; i < UART_NR; i++) { for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i]; struct uart_8250_port *up = &serial8250_ports[i];
up->port.line = i;
up->port.ops = &serial8250_pops;
up->port.dev = dev; up->port.dev = dev;
init_timer(&up->timer);
up->timer.function = serial8250_timeout;
/*
* ALPHA_KLUDGE_MCR needs to be killed.
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
up->mcr_force = ALPHA_KLUDGE_MCR;
uart_add_one_port(drv, &up->port); uart_add_one_port(drv, &up->port);
} }
} }
...@@ -2113,14 +2090,9 @@ static int __init serial8250_console_setup(struct console *co, char *options) ...@@ -2113,14 +2090,9 @@ static int __init serial8250_console_setup(struct console *co, char *options)
if (co->index >= UART_NR) if (co->index >= UART_NR)
co->index = 0; co->index = 0;
port = &serial8250_ports[co->index].port; port = &serial8250_ports[co->index].port;
if (!port->ops) if (!port->iobase && !port->membase)
return -ENODEV; return -ENODEV;
/*
* Temporary fix.
*/
spin_lock_init(&port->lock);
if (options) if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow); uart_parse_options(options, &baud, &parity, &bits, &flow);
...@@ -2181,20 +2153,6 @@ int __init early_serial_setup(struct uart_port *port) ...@@ -2181,20 +2153,6 @@ int __init early_serial_setup(struct uart_port *port)
return 0; return 0;
} }
/*
* This is for ISAPNP only.
*/
void serial8250_get_irq_map(unsigned int *map)
{
int i;
for (i = 0; i < UART_NR; i++) {
if (serial8250_ports[i].port.type != PORT_UNKNOWN &&
serial8250_ports[i].port.irq < 16)
*map |= 1 << serial8250_ports[i].port.irq;
}
}
/** /**
* serial8250_suspend_port - suspend one serial port * serial8250_suspend_port - suspend one serial port
* @line: serial line number * @line: serial line number
...@@ -2219,6 +2177,51 @@ void serial8250_resume_port(int line) ...@@ -2219,6 +2177,51 @@ void serial8250_resume_port(int line)
uart_resume_port(&serial8250_reg, &serial8250_ports[line].port); uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
} }
/*
* Register a set of serial devices attached to a platform device. The
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
static int __devinit serial8250_probe(struct device *dev)
{
struct plat_serial8250_port *p = dev->platform_data;
struct uart_port port;
memset(&port, 0, sizeof(struct uart_port));
for (; p && p->flags != 0; p++) {
port.iobase = p->iobase;
port.membase = p->membase;
port.irq = p->irq;
port.uartclk = p->uartclk;
port.regshift = p->regshift;
port.iotype = p->iotype;
port.flags = p->flags;
port.mapbase = p->mapbase;
port.dev = dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
serial8250_register_port(&port);
}
return 0;
}
/*
* Remove serial ports registered against a platform device.
*/
static int __devexit serial8250_remove(struct device *dev)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.dev == dev)
serial8250_unregister_port(i);
}
return 0;
}
static int serial8250_suspend(struct device *dev, u32 state, u32 level) static int serial8250_suspend(struct device *dev, u32 state, u32 level)
{ {
int i; int i;
...@@ -2256,11 +2259,18 @@ static int serial8250_resume(struct device *dev, u32 level) ...@@ -2256,11 +2259,18 @@ static int serial8250_resume(struct device *dev, u32 level)
static struct device_driver serial8250_isa_driver = { static struct device_driver serial8250_isa_driver = {
.name = "serial8250", .name = "serial8250",
.bus = &platform_bus_type, .bus = &platform_bus_type,
.probe = serial8250_probe,
.remove = __devexit_p(serial8250_remove),
.suspend = serial8250_suspend, .suspend = serial8250_suspend,
.resume = serial8250_resume, .resume = serial8250_resume,
}; };
/*
* This "device" covers _all_ ISA 8250-compatible serial devices listed
* in the table in include/asm/serial.h
*/
static struct platform_device *serial8250_isa_devs;
/* /*
* serial8250_register_port and serial8250_unregister_port allows for * serial8250_register_port and serial8250_unregister_port allows for
* 16x50 serial ports to be configured at run-time, to support PCMCIA * 16x50 serial ports to be configured at run-time, to support PCMCIA
...@@ -2338,6 +2348,9 @@ int serial8250_register_port(struct uart_port *port) ...@@ -2338,6 +2348,9 @@ int serial8250_register_port(struct uart_port *port)
struct uart_8250_port *uart; struct uart_8250_port *uart;
int ret = -ENOSPC; int ret = -ENOSPC;
if (port->uartclk == 0)
return -EINVAL;
down(&serial_sem); down(&serial_sem);
uart = serial8250_find_match_or_unused(port); uart = serial8250_find_match_or_unused(port);
...@@ -2379,10 +2392,14 @@ void serial8250_unregister_port(int line) ...@@ -2379,10 +2392,14 @@ void serial8250_unregister_port(int line)
down(&serial_sem); down(&serial_sem);
uart_remove_one_port(&serial8250_reg, &uart->port); uart_remove_one_port(&serial8250_reg, &uart->port);
uart->port.flags &= ~UPF_BOOT_AUTOCONF; if (serial8250_isa_devs) {
uart->port.type = PORT_UNKNOWN; uart->port.flags &= ~UPF_BOOT_AUTOCONF;
uart->port.dev = NULL; uart->port.type = PORT_UNKNOWN;
uart_add_one_port(&serial8250_reg, &uart->port); uart->port.dev = &serial8250_isa_devs->dev;
uart_add_one_port(&serial8250_reg, &uart->port);
} else {
uart->port.dev = NULL;
}
up(&serial_sem); up(&serial_sem);
} }
EXPORT_SYMBOL(serial8250_unregister_port); EXPORT_SYMBOL(serial8250_unregister_port);
...@@ -2395,41 +2412,53 @@ static int __init serial8250_init(void) ...@@ -2395,41 +2412,53 @@ static int __init serial8250_init(void)
"%d ports, IRQ sharing %sabled\n", (int) UART_NR, "%d ports, IRQ sharing %sabled\n", (int) UART_NR,
share_irqs ? "en" : "dis"); share_irqs ? "en" : "dis");
ret = driver_register(&serial8250_isa_driver);
if (ret)
goto out;
for (i = 0; i < NR_IRQS; i++) for (i = 0; i < NR_IRQS; i++)
spin_lock_init(&irq_lists[i].lock); spin_lock_init(&irq_lists[i].lock);
ret = uart_register_driver(&serial8250_reg); ret = uart_register_driver(&serial8250_reg);
if (ret) if (ret)
goto out;
serial8250_isa_devs = platform_device_register_simple("serial8250",
-1, NULL, 0);
if (IS_ERR(serial8250_isa_devs)) {
ret = PTR_ERR(serial8250_isa_devs);
goto unreg; goto unreg;
}
serial8250_register_ports(&serial8250_reg, NULL); serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
goto out;
ret = driver_register(&serial8250_isa_driver);
if (ret == 0)
goto out;
platform_device_unregister(serial8250_isa_devs);
unreg: unreg:
driver_unregister(&serial8250_isa_driver); uart_unregister_driver(&serial8250_reg);
out: out:
return ret; return ret;
} }
static void __exit serial8250_exit(void) static void __exit serial8250_exit(void)
{ {
int i; struct platform_device *isa_dev = serial8250_isa_devs;
for (i = 0; i < UART_NR; i++) /*
uart_remove_one_port(&serial8250_reg, &serial8250_ports[i].port); * This tells serial8250_unregister_port() not to re-register
* the ports (thereby making serial8250_isa_driver permanently
* in use.)
*/
serial8250_isa_devs = NULL;
uart_unregister_driver(&serial8250_reg);
driver_unregister(&serial8250_isa_driver); driver_unregister(&serial8250_isa_driver);
platform_device_unregister(isa_dev);
uart_unregister_driver(&serial8250_reg);
} }
module_init(serial8250_init); module_init(serial8250_init);
module_exit(serial8250_exit); module_exit(serial8250_exit);
EXPORT_SYMBOL(serial8250_get_irq_map);
EXPORT_SYMBOL(serial8250_suspend_port); EXPORT_SYMBOL(serial8250_suspend_port);
EXPORT_SYMBOL(serial8250_resume_port); EXPORT_SYMBOL(serial8250_resume_port);
...@@ -2481,11 +2510,26 @@ int register_serial(struct serial_struct *req) ...@@ -2481,11 +2510,26 @@ int register_serial(struct serial_struct *req)
port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET; port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
/* /*
* If a clock rate wasn't specified by the low level * If a clock rate wasn't specified by the low level driver, then
* driver, then default to the standard clock rate. * default to the standard clock rate. This should be 115200 (*16)
* and should not depend on the architecture's BASE_BAUD definition.
* However, since this API will be deprecated, it's probably a
* better idea to convert the drivers to use the new API
* (serial8250_register_port and serial8250_unregister_port).
*/ */
if (port.uartclk == 0) if (port.uartclk == 0) {
printk(KERN_WARNING
"Serial: registering port at [%08x,%08lx,%p] irq %d with zero baud_base\n",
port.iobase, port.mapbase, port.membase, port.irq);
printk(KERN_WARNING "Serial: see %s:%d for more information\n",
__FILE__, __LINE__);
dump_stack();
/*
* Fix it up for now, but this is only a temporary measure.
*/
port.uartclk = BASE_BAUD * 16; port.uartclk = BASE_BAUD * 16;
}
return serial8250_register_port(&port); return serial8250_register_port(&port);
} }
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
int serial8250_register_port(struct uart_port *); int serial8250_register_port(struct uart_port *);
void serial8250_unregister_port(int line); void serial8250_unregister_port(int line);
void serial8250_get_irq_map(unsigned int *map);
void serial8250_suspend_port(int line); void serial8250_suspend_port(int line);
void serial8250_resume_port(int line); void serial8250_resume_port(int line);
...@@ -73,3 +72,14 @@ struct serial8250_config { ...@@ -73,3 +72,14 @@ struct serial8250_config {
#else #else
#define SERIAL8250_SHARE_IRQS 0 #define SERIAL8250_SHARE_IRQS 0
#endif #endif
#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)
#else
#define ALPHA_KLUDGE_MCR 0
#endif
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -22,11 +21,13 @@ ...@@ -22,11 +21,13 @@
#include <asm/ecard.h> #include <asm/ecard.h>
#include <asm/string.h> #include <asm/string.h>
#include "8250.h"
#define MAX_PORTS 3 #define MAX_PORTS 3
struct serial_card_type { struct serial_card_type {
unsigned int num_ports; unsigned int num_ports;
unsigned int baud_base; unsigned int uartclk;
unsigned int type; unsigned int type;
unsigned int offset[MAX_PORTS]; unsigned int offset[MAX_PORTS];
}; };
...@@ -36,31 +37,15 @@ struct serial_card_info { ...@@ -36,31 +37,15 @@ struct serial_card_info {
int ports[MAX_PORTS]; int ports[MAX_PORTS];
}; };
static inline int
serial_register_onedev(unsigned long baddr, void *vaddr, int irq, unsigned int baud_base)
{
struct serial_struct req;
memset(&req, 0, sizeof(req));
req.irq = irq;
req.flags = UPF_AUTOPROBE | UPF_SHARE_IRQ;
req.baud_base = baud_base;
req.io_type = UPIO_MEM;
req.iomem_base = vaddr;
req.iomem_reg_shift = 2;
req.iomap_base = baddr;
return register_serial(&req);
}
static int __devinit static int __devinit
serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{ {
struct serial_card_info *info; struct serial_card_info *info;
struct serial_card_type *type = id->data; struct serial_card_type *type = id->data;
struct uart_port port;
unsigned long bus_addr; unsigned long bus_addr;
unsigned char *virt_addr; unsigned char __iomem *virt_addr;
unsigned int port; unsigned int i;
info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL); info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL);
if (!info) if (!info)
...@@ -69,21 +54,28 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -69,21 +54,28 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
memset(info, 0, sizeof(struct serial_card_info)); memset(info, 0, sizeof(struct serial_card_info));
info->num_ports = type->num_ports; info->num_ports = type->num_ports;
ecard_set_drvdata(ec, info); bus_addr = ecard_resource_start(ec, type->type);
virt_addr = ioremap(bus_addr, ecard_resource_len(ec, type->type));
bus_addr = ec->resource[type->type].start;
virt_addr = ioremap(bus_addr, ec->resource[type->type].end - bus_addr + 1);
if (!virt_addr) { if (!virt_addr) {
kfree(info); kfree(info);
return -ENOMEM; return -ENOMEM;
} }
for (port = 0; port < info->num_ports; port ++) { ecard_set_drvdata(ec, info);
unsigned long baddr = bus_addr + type->offset[port];
unsigned char *vaddr = virt_addr + type->offset[port]; 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 = virt_addr + type->offset[i];
port.mapbase = bus_addr + type->offset[i];
info->ports[port] = serial_register_onedev(baddr, vaddr, info->ports[i] = serial8250_register_port(&port);
ec->irq, type->baud_base);
} }
return 0; return 0;
...@@ -98,21 +90,21 @@ static void __devexit serial_card_remove(struct expansion_card *ec) ...@@ -98,21 +90,21 @@ static void __devexit serial_card_remove(struct expansion_card *ec)
for (i = 0; i < info->num_ports; i++) for (i = 0; i < info->num_ports; i++)
if (info->ports[i] > 0) if (info->ports[i] > 0)
unregister_serial(info->ports[i]); serial8250_unregister_port(info->ports[i]);
kfree(info); kfree(info);
} }
static struct serial_card_type atomwide_type = { static struct serial_card_type atomwide_type = {
.num_ports = 3, .num_ports = 3,
.baud_base = 7372800 / 16, .uartclk = 7372800,
.type = ECARD_RES_IOCSLOW, .type = ECARD_RES_IOCSLOW,
.offset = { 0x2800, 0x2400, 0x2000 }, .offset = { 0x2800, 0x2400, 0x2000 },
}; };
static struct serial_card_type serport_type = { static struct serial_card_type serport_type = {
.num_ports = 2, .num_ports = 2,
.baud_base = 3686400 / 16, .uartclk = 3686400,
.type = ECARD_RES_IOCSLOW, .type = ECARD_RES_IOCSLOW,
.offset = { 0x2000, 0x2020 }, .offset = { 0x2000, 0x2020 },
}; };
...@@ -128,7 +120,7 @@ static struct ecard_driver serial_card_driver = { ...@@ -128,7 +120,7 @@ static struct ecard_driver serial_card_driver = {
.remove = __devexit_p(serial_card_remove), .remove = __devexit_p(serial_card_remove),
.id_table = serial_cids, .id_table = serial_cids,
.drv = { .drv = {
.name = "8250_acorn", .name = "8250_acorn",
}, },
}; };
......
...@@ -12,81 +12,71 @@ ...@@ -12,81 +12,71 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/serial.h>
#include "8250.h"
struct serial_private { struct serial_private {
int line; int line;
void *iomem_base;
}; };
static acpi_status acpi_serial_mmio(struct serial_struct *req, static acpi_status acpi_serial_mmio(struct uart_port *port,
struct acpi_resource_address64 *addr) struct acpi_resource_address64 *addr)
{ {
unsigned long size; port->mapbase = addr->min_address_range;
port->iotype = UPIO_MEM;
size = addr->max_address_range - addr->min_address_range + 1; port->flags |= UPF_IOREMAP;
req->iomap_base = addr->min_address_range;
req->iomem_base = ioremap(req->iomap_base, size);
if (!req->iomem_base) {
printk(KERN_ERR "%s: couldn't ioremap 0x%lx-0x%lx\n",
__FUNCTION__, req->iomap_base, req->iomap_base + size);
return AE_ERROR;
}
req->io_type = SERIAL_IO_MEM;
return AE_OK; return AE_OK;
} }
static acpi_status acpi_serial_port(struct serial_struct *req, static acpi_status acpi_serial_port(struct uart_port *port,
struct acpi_resource_io *io) struct acpi_resource_io *io)
{ {
if (io->range_length) { if (io->range_length) {
req->port = io->min_base_address; port->iobase = io->min_base_address;
req->io_type = SERIAL_IO_PORT; port->iotype = UPIO_PORT;
} else } else
printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__); printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__);
return AE_OK; return AE_OK;
} }
static acpi_status acpi_serial_ext_irq(struct serial_struct *req, static acpi_status acpi_serial_ext_irq(struct uart_port *port,
struct acpi_resource_ext_irq *ext_irq) struct acpi_resource_ext_irq *ext_irq)
{ {
if (ext_irq->number_of_interrupts > 0) if (ext_irq->number_of_interrupts > 0)
req->irq = acpi_register_gsi(ext_irq->interrupts[0], port->irq = acpi_register_gsi(ext_irq->interrupts[0],
ext_irq->edge_level, ext_irq->active_high_low); ext_irq->edge_level, ext_irq->active_high_low);
return AE_OK; return AE_OK;
} }
static acpi_status acpi_serial_irq(struct serial_struct *req, static acpi_status acpi_serial_irq(struct uart_port *port,
struct acpi_resource_irq *irq) struct acpi_resource_irq *irq)
{ {
if (irq->number_of_interrupts > 0) if (irq->number_of_interrupts > 0)
req->irq = acpi_register_gsi(irq->interrupts[0], port->irq = acpi_register_gsi(irq->interrupts[0],
irq->edge_level, irq->active_high_low); irq->edge_level, irq->active_high_low);
return AE_OK; return AE_OK;
} }
static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
{ {
struct serial_struct *serial_req = (struct serial_struct *) data; struct uart_port *port = (struct uart_port *) data;
struct acpi_resource_address64 addr; struct acpi_resource_address64 addr;
acpi_status status; acpi_status status;
status = acpi_resource_to_address64(res, &addr); status = acpi_resource_to_address64(res, &addr);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
return acpi_serial_mmio(serial_req, &addr); return acpi_serial_mmio(port, &addr);
else if (res->id == ACPI_RSTYPE_IO) else if (res->id == ACPI_RSTYPE_IO)
return acpi_serial_port(serial_req, &res->data.io); return acpi_serial_port(port, &res->data.io);
else if (res->id == ACPI_RSTYPE_EXT_IRQ) else if (res->id == ACPI_RSTYPE_EXT_IRQ)
return acpi_serial_ext_irq(serial_req, &res->data.extended_irq); return acpi_serial_ext_irq(port, &res->data.extended_irq);
else if (res->id == ACPI_RSTYPE_IRQ) else if (res->id == ACPI_RSTYPE_IRQ)
return acpi_serial_irq(serial_req, &res->data.irq); return acpi_serial_irq(port, &res->data.irq);
return AE_OK; return AE_OK;
} }
...@@ -94,10 +84,13 @@ static int acpi_serial_add(struct acpi_device *device) ...@@ -94,10 +84,13 @@ static int acpi_serial_add(struct acpi_device *device)
{ {
struct serial_private *priv; struct serial_private *priv;
acpi_status status; acpi_status status;
struct serial_struct serial_req; struct uart_port port;
int result; int result;
memset(&serial_req, 0, sizeof(serial_req)); memset(&port, 0, sizeof(struct uart_port));
port.uartclk = 1843200;
port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
priv = kmalloc(sizeof(struct serial_private), GFP_KERNEL); priv = kmalloc(sizeof(struct serial_private), GFP_KERNEL);
if (!priv) { if (!priv) {
...@@ -107,25 +100,20 @@ static int acpi_serial_add(struct acpi_device *device) ...@@ -107,25 +100,20 @@ static int acpi_serial_add(struct acpi_device *device)
memset(priv, 0, sizeof(*priv)); memset(priv, 0, sizeof(*priv));
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
acpi_serial_resource, &serial_req); acpi_serial_resource, &port);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
result = -ENODEV; result = -ENODEV;
goto fail; goto fail;
} }
if (serial_req.iomem_base) if (!port.mapbase && !port.iobase) {
priv->iomem_base = serial_req.iomem_base;
else if (!serial_req.port) {
printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n", printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n",
__FUNCTION__, device->pnp.bus_id); __FUNCTION__, device->pnp.bus_id);
result = -ENODEV; result = -ENODEV;
goto fail; goto fail;
} }
serial_req.baud_base = BASE_BAUD; priv->line = serial8250_register_port(&port);
serial_req.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
priv->line = register_serial(&serial_req);
if (priv->line < 0) { if (priv->line < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", printk(KERN_WARNING "Couldn't register serial port %s: %d\n",
device->pnp.bus_id, priv->line); device->pnp.bus_id, priv->line);
...@@ -137,8 +125,6 @@ static int acpi_serial_add(struct acpi_device *device) ...@@ -137,8 +125,6 @@ static int acpi_serial_add(struct acpi_device *device)
return 0; return 0;
fail: fail:
if (serial_req.iomem_base)
iounmap(serial_req.iomem_base);
kfree(priv); kfree(priv);
return result; return result;
...@@ -152,9 +138,7 @@ static int acpi_serial_remove(struct acpi_device *device, int type) ...@@ -152,9 +138,7 @@ static int acpi_serial_remove(struct acpi_device *device, int type)
return -EINVAL; return -EINVAL;
priv = acpi_driver_data(device); priv = acpi_driver_data(device);
unregister_serial(priv->line); serial8250_unregister_port(priv->line);
if (priv->iomem_base)
iounmap(priv->iomem_base);
kfree(priv); kfree(priv);
return 0; return 0;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/serial.h> #include <linux/serial_core.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -22,37 +22,18 @@ ...@@ -22,37 +22,18 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/parisc-device.h> #include <asm/parisc-device.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/serial.h> #include <asm/serial.h> /* for LASI_BASE_BAUD */
static void setup_parisc_serial(struct serial_struct *serial, #include "8250.h"
unsigned long address, int irq, int line)
{
memset(serial, 0, sizeof(struct serial_struct));
/* autoconfig() sets state->type. This sets info->type */
serial->type = PORT_16550A;
serial->line = line;
serial->iomap_base = address;
serial->iomem_base = ioremap(address, 0x8);
serial->irq = irq;
serial->io_type = SERIAL_IO_MEM; /* define access method */
serial->flags = 0;
serial->xmit_fifo_size = 16;
serial->custom_divisor = 0;
serial->baud_base = LASI_BASE_BAUD;
}
static int __init static int __init
serial_init_chip(struct parisc_device *dev) serial_init_chip(struct parisc_device *dev)
{ {
static int serial_line_nr; static int serial_line_nr;
struct uart_port port;
unsigned long address; unsigned long address;
int err; int err;
struct serial_struct *serial;
if (!dev->irq) { if (!dev->irq) {
/* We find some unattached serial ports by walking native /* We find some unattached serial ports by walking native
* busses. These should be silently ignored. Otherwise, * busses. These should be silently ignored. Otherwise,
...@@ -66,21 +47,23 @@ serial_init_chip(struct parisc_device *dev) ...@@ -66,21 +47,23 @@ serial_init_chip(struct parisc_device *dev)
return -ENODEV; return -ENODEV;
} }
serial = kmalloc(sizeof(*serial), GFP_KERNEL);
if (!serial)
return -ENOMEM;
address = dev->hpa; address = dev->hpa;
if (dev->id.sversion != 0x8d) { if (dev->id.sversion != 0x8d) {
address += 0x800; address += 0x800;
} }
setup_parisc_serial(serial, address, dev->irq, serial_line_nr++); memset(&port, 0, sizeof(struct uart_port));
err = register_serial(serial); port.mapbase = address;
port.irq = dev->irq;
port.iotype = UPIO_MEM;
port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
port.uartclk = LASI_BASE_BAUD * 16;
port.dev = &dev->dev;
err = serial8250_register_port(&port);
if (err < 0) { if (err < 0) {
printk(KERN_WARNING "register_serial returned error %d\n", err); printk(KERN_WARNING "serial8250_register_port returned error %d\n", err);
kfree(serial); return err;
return -ENODEV;
} }
return 0; return 0;
......
...@@ -23,13 +23,13 @@ ...@@ -23,13 +23,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/bitops.h>
#include <linux/8250.h>
#include <linux/8250_pci.h> #include <linux/8250_pci.h>
#include <linux/bitops.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/io.h> #include <asm/io.h>
#include "8250.h"
/* /*
* Definitions for PCI support. * Definitions for PCI support.
...@@ -1026,6 +1026,7 @@ enum pci_board_num_t { ...@@ -1026,6 +1026,7 @@ enum pci_board_num_t {
pbn_b1_bt_2_921600, pbn_b1_bt_2_921600,
pbn_b1_1_1382400,
pbn_b1_2_1382400, pbn_b1_2_1382400,
pbn_b1_4_1382400, pbn_b1_4_1382400,
pbn_b1_8_1382400, pbn_b1_8_1382400,
...@@ -1253,6 +1254,12 @@ static struct pci_board pci_boards[] __devinitdata = { ...@@ -1253,6 +1254,12 @@ static struct pci_board pci_boards[] __devinitdata = {
.uart_offset = 8, .uart_offset = 8,
}, },
[pbn_b1_1_1382400] = {
.flags = FL_BASE1,
.num_ports = 1,
.base_baud = 1382400,
.uart_offset = 8,
},
[pbn_b1_2_1382400] = { [pbn_b1_2_1382400] = {
.flags = FL_BASE1, .flags = FL_BASE1,
.num_ports = 2, .num_ports = 2,
...@@ -1689,7 +1696,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) ...@@ -1689,7 +1696,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
struct uart_port serial_port; struct uart_port serial_port;
memset(&serial_port, 0, sizeof(struct uart_port)); memset(&serial_port, 0, sizeof(struct uart_port));
serial_port.flags = UPF_SKIP_TEST | UPF_AUTOPROBE | serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF |
UPF_SHARE_IRQ; UPF_SHARE_IRQ;
serial_port.uartclk = board->base_baud * 16; serial_port.uartclk = board->base_baud * 16;
serial_port.irq = get_pci_irq(dev, board, i); serial_port.irq = get_pci_irq(dev, board, i);
...@@ -2108,6 +2115,13 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -2108,6 +2115,13 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_bt_1_460800 }, pbn_b0_bt_1_460800 },
/*
* Dell Remote Access Card III - Tim_T_Murphy@Dell.com
*/
{ PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b1_1_1382400 },
/* /*
* RAStel 2 port modem, gerg@moreton.com.au * RAStel 2 port modem, gerg@moreton.com.au
*/ */
......
...@@ -21,15 +21,12 @@ ...@@ -21,15 +21,12 @@
#include <linux/pnp.h> #include <linux/pnp.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/8250.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/serial.h>
#include "8250.h"
#define UNKNOWN_DEV 0x3000 #define UNKNOWN_DEV 0x3000
...@@ -48,7 +45,7 @@ static const struct pnp_device_id pnp_dev_table[] = { ...@@ -48,7 +45,7 @@ static const struct pnp_device_id pnp_dev_table[] = {
/* Actiontec ISA PNP 56K X2 Fax Modem */ /* Actiontec ISA PNP 56K X2 Fax Modem */
{ "AEI1240", 0 }, { "AEI1240", 0 },
/* Rockwell 56K ACF II Fax+Data+Voice Modem */ /* Rockwell 56K ACF II Fax+Data+Voice Modem */
{ "AKY1021", SPCI_FL_NO_SHIRQ }, { "AKY1021", 0 /*SPCI_FL_NO_SHIRQ*/ },
/* AZT3005 PnP SOUND DEVICE */ /* AZT3005 PnP SOUND DEVICE */
{ "AZT4001", 0 }, { "AZT4001", 0 },
/* Best Data Products Inc. Smart One 336F PnP Modem */ /* Best Data Products Inc. Smart One 336F PnP Modem */
...@@ -397,26 +394,29 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) ...@@ -397,26 +394,29 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
static int __devinit static int __devinit
serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
{ {
struct serial_struct serial_req; struct uart_port port;
int ret, line, flags = dev_id->driver_data; int ret, line, flags = dev_id->driver_data;
if (flags & UNKNOWN_DEV) { if (flags & UNKNOWN_DEV) {
ret = serial_pnp_guess_board(dev, &flags); ret = serial_pnp_guess_board(dev, &flags);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
memset(&serial_req, 0, sizeof(serial_req));
serial_req.irq = pnp_irq(dev,0); memset(&port, 0, sizeof(struct uart_port));
serial_req.port = pnp_port_start(dev, 0); port.irq = pnp_irq(dev,0);
if (HIGH_BITS_OFFSET) port.iobase = pnp_port_start(dev, 0);
serial_req.port = pnp_port_start(dev, 0) >> HIGH_BITS_OFFSET;
#ifdef SERIAL_DEBUG_PNP #ifdef SERIAL_DEBUG_PNP
printk("Setup PNP port: port %x, irq %d, type %d\n", printk("Setup PNP port: port %x, irq %d, type %d\n",
serial_req.port, serial_req.irq, serial_req.io_type); port.iobase, port.irq, port.iotype);
#endif #endif
serial_req.flags = UPF_SKIP_TEST | UPF_AUTOPROBE; port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
serial_req.baud_base = 115200; port.uartclk = 1843200;
line = register_serial(&serial_req); port.dev = &dev->dev;
line = serial8250_register_port(&port);
if (line >= 0) if (line >= 0)
pnp_set_drvdata(dev, (void *)(line + 1)); pnp_set_drvdata(dev, (void *)(line + 1));
...@@ -428,7 +428,7 @@ static void __devexit serial_pnp_remove(struct pnp_dev * dev) ...@@ -428,7 +428,7 @@ static void __devexit serial_pnp_remove(struct pnp_dev * dev)
{ {
int line = (int)pnp_get_drvdata(dev); int line = (int)pnp_get_drvdata(dev);
if (line) if (line)
unregister_serial(line - 1); serial8250_unregister_port(line - 1);
} }
static struct pnp_driver serial_pnp_driver = { static struct pnp_driver serial_pnp_driver = {
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serialP.h> #include <linux/serialP.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/8250.h>
#include <asm/serial.h> #include <asm/serial.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -41,6 +40,7 @@ ...@@ -41,6 +40,7 @@
#endif #endif
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include "8250.h"
/* /*
* Debugging. * Debugging.
...@@ -1313,20 +1313,6 @@ void unregister_serial(int line) ...@@ -1313,20 +1313,6 @@ void unregister_serial(int line)
uart_unregister_port(&serial8250_reg, line); uart_unregister_port(&serial8250_reg, line);
} }
/*
* This is for ISAPNP only.
*/
void serial8250_get_irq_map(unsigned int *map)
{
int i;
for (i = 0; i < UART_NR; i++) {
if (serial8250_ports[i].port.type != PORT_UNKNOWN &&
serial8250_ports[i].port.irq < 16)
*map |= 1 << serial8250_ports[i].port.irq;
}
}
/** /**
* serial8250_suspend_port - suspend one serial port * serial8250_suspend_port - suspend one serial port
* @line: serial line number * @line: serial line number
...@@ -1382,7 +1368,6 @@ module_exit(serial8250_exit); ...@@ -1382,7 +1368,6 @@ module_exit(serial8250_exit);
EXPORT_SYMBOL(register_serial); EXPORT_SYMBOL(register_serial);
EXPORT_SYMBOL(unregister_serial); EXPORT_SYMBOL(unregister_serial);
EXPORT_SYMBOL(serial8250_get_irq_map);
EXPORT_SYMBOL(serial8250_suspend_port); EXPORT_SYMBOL(serial8250_suspend_port);
EXPORT_SYMBOL(serial8250_resume_port); EXPORT_SYMBOL(serial8250_resume_port);
......
...@@ -140,12 +140,6 @@ static inline void trace(struct icom_port *, char *, unsigned long) {}; ...@@ -140,12 +140,6 @@ static inline void trace(struct icom_port *, char *, unsigned long) {};
static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {}; static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
#endif #endif
static void msleep(unsigned long msecs)
{
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(MSECS_TO_JIFFIES(msecs));
}
static void free_port_memory(struct icom_port *icom_port) static void free_port_memory(struct icom_port *icom_port)
{ {
struct pci_dev *dev = icom_port->adapter->pci_dev; struct pci_dev *dev = icom_port->adapter->pci_dev;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -978,7 +979,7 @@ static void send_break( struct mcf_serial * info, int duration) ...@@ -978,7 +979,7 @@ static void send_break( struct mcf_serial * info, int duration)
if (!info->addr) if (!info->addr)
return; return;
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
uartp = info->addr; uartp = info->addr;
local_irq_save(flags); local_irq_save(flags);
...@@ -1230,8 +1231,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp) ...@@ -1230,8 +1231,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
#endif #endif
if (info->blocked_open) { if (info->blocked_open) {
if (info->close_delay) { if (info->close_delay) {
current->state = TASK_INTERRUPTIBLE; msleep_interruptible(jiffies_to_msecs(info->close_delay));
schedule_timeout(info->close_delay);
} }
wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait);
} }
...@@ -1296,8 +1296,7 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout) ...@@ -1296,8 +1296,7 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
fifo_cnt++; fifo_cnt++;
if (fifo_cnt == 0) if (fifo_cnt == 0)
break; break;
set_current_state(TASK_INTERRUPTIBLE); msleep_interruptible(jiffies_to_msecs(char_time));
schedule_timeout(char_time);
if (signal_pending(current)) if (signal_pending(current))
break; break;
if (timeout && time_after(jiffies, orig_jiffies + timeout)) if (timeout && time_after(jiffies, orig_jiffies + timeout))
......
...@@ -949,8 +949,7 @@ static int pmz_startup(struct uart_port *port) ...@@ -949,8 +949,7 @@ static int pmz_startup(struct uart_port *port)
*/ */
if (pwr_delay != 0) { if (pwr_delay != 0) {
pmz_debug("pmz: delaying %d ms\n", pwr_delay); pmz_debug("pmz: delaying %d ms\n", pwr_delay);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(pwr_delay);
schedule_timeout((pwr_delay * HZ)/1000);
} }
/* IrDA reset is done now */ /* IrDA reset is done now */
...@@ -1684,8 +1683,7 @@ static int pmz_resume(struct macio_dev *mdev) ...@@ -1684,8 +1683,7 @@ static int pmz_resume(struct macio_dev *mdev)
*/ */
if (pwr_delay != 0) { if (pwr_delay != 0) {
pmz_debug("pmz: delaying %d ms\n", pwr_delay); pmz_debug("pmz: delaying %d ms\n", pwr_delay);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(pwr_delay);
schedule_timeout((pwr_delay * HZ)/1000);
} }
pmz_debug("resume, switching complete\n"); pmz_debug("resume, switching complete\n");
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/serial.h> /* for serial_state and serial_icounter_struct */ #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
#include <linux/delay.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -162,8 +163,6 @@ static int uart_startup(struct uart_state *state, int init_hw) ...@@ -162,8 +163,6 @@ static int uart_startup(struct uart_state *state, int init_hw)
return -ENOMEM; return -ENOMEM;
info->xmit.buf = (unsigned char *) page; info->xmit.buf = (unsigned char *) page;
info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
init_MUTEX(&info->tmpbuf_sem);
uart_circ_clear(&info->xmit); uart_circ_clear(&info->xmit);
} }
...@@ -238,7 +237,6 @@ static void uart_shutdown(struct uart_state *state) ...@@ -238,7 +237,6 @@ static void uart_shutdown(struct uart_state *state)
if (info->xmit.buf) { if (info->xmit.buf) {
free_page((unsigned long)info->xmit.buf); free_page((unsigned long)info->xmit.buf);
info->xmit.buf = NULL; info->xmit.buf = NULL;
info->tmpbuf = NULL;
} }
/* /*
...@@ -450,53 +448,30 @@ __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c) ...@@ -450,53 +448,30 @@ __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
} }
static inline int static void uart_put_char(struct tty_struct *tty, unsigned char ch)
__uart_user_write(struct uart_port *port, struct circ_buf *circ,
const unsigned char __user *buf, int count)
{ {
unsigned long flags; struct uart_state *state = tty->driver_data;
int c, ret = 0;
if (down_interruptible(&port->info->tmpbuf_sem))
return -EINTR;
while (1) {
int c1;
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (count < c)
c = count;
if (c <= 0)
break;
c -= copy_from_user(port->info->tmpbuf, buf, c); __uart_put_char(state->port, &state->info->xmit, ch);
if (!c) { }
if (!ret)
ret = -EFAULT;
break;
}
spin_lock_irqsave(&port->lock, flags);
c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (c1 < c)
c = c1;
memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
spin_unlock_irqrestore(&port->lock, flags);
buf += c;
count -= c;
ret += c;
}
up(&port->info->tmpbuf_sem);
return ret; static void uart_flush_chars(struct tty_struct *tty)
{
uart_start(tty);
} }
static inline int static int
__uart_kern_write(struct uart_port *port, struct circ_buf *circ, uart_write(struct tty_struct *tty, const unsigned char * buf, int count)
const unsigned char *buf, int count)
{ {
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
struct circ_buf *circ = &state->info->xmit;
unsigned long flags; unsigned long flags;
int c, ret = 0; int c, ret = 0;
if (!circ->buf)
return 0;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
while (1) { while (1) {
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
...@@ -512,33 +487,6 @@ __uart_kern_write(struct uart_port *port, struct circ_buf *circ, ...@@ -512,33 +487,6 @@ __uart_kern_write(struct uart_port *port, struct circ_buf *circ,
} }
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
return ret;
}
static void uart_put_char(struct tty_struct *tty, unsigned char ch)
{
struct uart_state *state = tty->driver_data;
__uart_put_char(state->port, &state->info->xmit, ch);
}
static void uart_flush_chars(struct tty_struct *tty)
{
uart_start(tty);
}
static int
uart_write(struct tty_struct *tty, const unsigned char * buf, int count)
{
struct uart_state *state = tty->driver_data;
int ret;
if (!state->info->xmit.buf)
return 0;
ret = __uart_kern_write(state->port, &state->info->xmit,
buf, count);
uart_start(tty); uart_start(tty);
return ret; return ret;
} }
...@@ -1272,8 +1220,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1272,8 +1220,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
if (state->info->blocked_open) { if (state->info->blocked_open) {
if (state->close_delay) { if (state->close_delay) {
set_current_state(TASK_INTERRUPTIBLE); msleep_interruptible(jiffies_to_msecs(state->close_delay));
schedule_timeout(state->close_delay);
} }
} else if (!uart_console(port)) { } else if (!uart_console(port)) {
uart_change_pm(state, 3); uart_change_pm(state, 3);
...@@ -1338,8 +1285,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) ...@@ -1338,8 +1285,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
* we wait. * we wait.
*/ */
while (!port->ops->tx_empty(port)) { while (!port->ops->tx_empty(port)) {
set_current_state(TASK_INTERRUPTIBLE); msleep_interruptible(jiffies_to_msecs(char_time));
schedule_timeout(char_time);
if (signal_pending(current)) if (signal_pending(current))
break; break;
if (time_after(jiffies, expire)) if (time_after(jiffies, expire))
...@@ -1896,10 +1842,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) ...@@ -1896,10 +1842,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
* Wait for the transmitter to empty. * Wait for the transmitter to empty.
*/ */
while (!ops->tx_empty(port)) { while (!ops->tx_empty(port)) {
set_current_state(TASK_UNINTERRUPTIBLE); msleep(10);
schedule_timeout(10*HZ/1000);
} }
set_current_state(TASK_RUNNING);
ops->shutdown(port); ops->shutdown(port);
} }
......
...@@ -40,11 +40,8 @@ ...@@ -40,11 +40,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/8250.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -56,6 +53,8 @@ ...@@ -56,6 +53,8 @@
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include "8250.h"
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG; static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i"); MODULE_PARM(pc_debug, "i");
...@@ -147,7 +146,7 @@ static void serial_remove(dev_link_t *link) ...@@ -147,7 +146,7 @@ static void serial_remove(dev_link_t *link)
*/ */
if (info->link.state & DEV_CONFIG) { if (info->link.state & DEV_CONFIG) {
for (i = 0; i < info->ndev; i++) for (i = 0; i < info->ndev; i++)
unregister_serial(info->line[i]); serial8250_unregister_port(info->line[i]);
info->link.dev = NULL; info->link.dev = NULL;
...@@ -303,21 +302,22 @@ static void serial_detach(dev_link_t * link) ...@@ -303,21 +302,22 @@ static void serial_detach(dev_link_t * link)
/*====================================================================*/ /*====================================================================*/
static int setup_serial(struct serial_info * info, ioaddr_t port, int irq) static int setup_serial(struct serial_info * info, ioaddr_t iobase, int irq)
{ {
struct serial_struct serial; struct uart_port port;
int line; int line;
memset(&serial, 0, sizeof (serial)); memset(&port, 0, sizeof (struct uart_port));
serial.port = port; port.iobase = iobase;
serial.irq = irq; port.irq = irq;
serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ; port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
port.uartclk = 1843200;
if (buggy_uart) if (buggy_uart)
serial.flags |= UPF_BUGGY_UART; port.flags |= UPF_BUGGY_UART;
line = register_serial(&serial); line = serial8250_register_port(&port);
if (line < 0) { if (line < 0) {
printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx," printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
" irq %d failed\n", (u_long) serial.port, serial.irq); "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
return -EINVAL; return -EINVAL;
} }
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#ifndef _PPC64_SERIAL_H #ifndef _PPC64_SERIAL_H
#define _PPC64_SERIAL_H #define _PPC64_SERIAL_H
#include <linux/config.h>
/* /*
* This assumes you have a 1.8432 MHz clock for your UART. * This assumes you have a 1.8432 MHz clock for your UART.
* *
...@@ -22,9 +20,4 @@ ...@@ -22,9 +20,4 @@
/* Default baud base if not found in device-tree */ /* Default baud base if not found in device-tree */
#define BASE_BAUD ( 1843200 / 16 ) #define BASE_BAUD ( 1843200 / 16 )
#define ARCH_HAS_GET_LEGACY_SERIAL_PORTS
struct old_serial_port;
extern struct old_serial_port *get_legacy_serial_ports(unsigned int *count);
#define UART_NR (8 + CONFIG_SERIAL_8250_NR_UARTS)
#endif /* _PPC64_SERIAL_H */ #endif /* _PPC64_SERIAL_H */
...@@ -521,7 +521,8 @@ ...@@ -521,7 +521,8 @@
#define PCI_VENDOR_ID_AI 0x1025 #define PCI_VENDOR_ID_AI 0x1025
#define PCI_DEVICE_ID_AI_M1435 0x1435 #define PCI_DEVICE_ID_AI_M1435 0x1435
#define PCI_VENDOR_ID_DELL 0x1028 #define PCI_VENDOR_ID_DELL 0x1028
#define PCI_DEVICE_ID_DELL_RACIII 0x0008
#define PCI_VENDOR_ID_MATROX 0x102B #define PCI_VENDOR_ID_MATROX 0x102B
#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 #define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
......
/*
* linux/include/linux/serial_8250.h
*
* Copyright (C) 2004 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.
*/
#ifndef _LINUX_SERIAL_8250_H
#define _LINUX_SERIAL_8250_H
#include <linux/serial_core.h>
#include <linux/device.h>
struct plat_serial8250_port {
unsigned long iobase; /* io base address */
void __iomem *membase; /* ioremap cookie or NULL */
unsigned long mapbase; /* resource base */
unsigned int irq; /* interrupt number */
unsigned int uartclk; /* UART clock rate */
unsigned char regshift; /* register shift */
unsigned char iotype; /* UPIO_* */
unsigned int flags; /* UPF_* flags */
};
#endif
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef LINUX_SERIAL_CORE_H
#define LINUX_SERIAL_CORE_H
/* /*
* The type definitions. These are from Ted Ts'o's serial.h * The type definitions. These are from Ted Ts'o's serial.h
...@@ -96,6 +98,7 @@ ...@@ -96,6 +98,7 @@
#include <linux/circ_buf.h> #include <linux/circ_buf.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/tty.h>
struct uart_port; struct uart_port;
struct uart_info; struct uart_info;
...@@ -246,7 +249,7 @@ struct uart_state { ...@@ -246,7 +249,7 @@ struct uart_state {
struct semaphore sem; struct semaphore sem;
}; };
#define UART_XMIT_SIZE 1024 #define UART_XMIT_SIZE PAGE_SIZE
/* /*
* This is the state information which is only valid when the port * This is the state information which is only valid when the port
* is open; it may be freed by the core driver once the device has * is open; it may be freed by the core driver once the device has
...@@ -268,9 +271,6 @@ struct uart_info { ...@@ -268,9 +271,6 @@ struct uart_info {
#define UIF_NORMAL_ACTIVE (1 << 29) #define UIF_NORMAL_ACTIVE (1 << 29)
#define UIF_INITIALIZED (1 << 31) #define UIF_INITIALIZED (1 << 31)
unsigned char *tmpbuf;
struct semaphore tmpbuf_sem;
int blocked_open; int blocked_open;
struct tasklet_struct tlet; struct tasklet_struct tlet;
...@@ -458,3 +458,5 @@ uart_handle_cts_change(struct uart_port *port, unsigned int status) ...@@ -458,3 +458,5 @@ uart_handle_cts_change(struct uart_port *port, unsigned int status)
!((cflag) & CLOCAL)) !((cflag) & CLOCAL))
#endif #endif
#endif /* LINUX_SERIAL_CORE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment