Merge branch 'merge'

This commit is contained in:
Paul Mackerras 2006-08-01 10:37:25 +10:00
commit 57cad8084e
1510 changed files with 22919 additions and 13479 deletions

View file

@ -299,6 +299,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
static unsigned int serial_in(struct uart_8250_port *up, int offset)
{
unsigned int tmp;
offset = map_8250_in_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
@ -317,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
return __raw_readl(up->port.membase + offset);
#endif
case UPIO_TSI:
if (offset == UART_IIR) {
tmp = readl((u32 *)(up->port.membase + UART_RX));
return (cpu_to_le32(tmp) >> 8) & 0xff;
} else
return readb(up->port.membase + offset);
default:
return inb(up->port.iobase + offset);
}
@ -346,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value)
__raw_writel(value, up->port.membase + offset);
break;
#endif
case UPIO_TSI:
if (!((offset == UART_IER) && (value & UART_IER_UUE)))
writeb(value, up->port.membase + offset);
break;
default:
outb(value, up->port.iobase + offset);
@ -2240,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
touch_nmi_watchdog();
if (oops_in_progress) {
locked = spin_trylock_irqsave(&up->port.lock, flags);
local_irq_save(flags);
if (up->port.sysrq) {
/* serial8250_handle_port() already took the lock */
locked = 0;
} else if (oops_in_progress) {
locked = spin_trylock(&up->port.lock);
} else
spin_lock_irqsave(&up->port.lock, flags);
spin_lock(&up->port.lock);
/*
* First save the IER then disable the interrupts
@ -2265,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
serial_out(up, UART_IER, ier);
if (locked)
spin_unlock_irqrestore(&up->port.lock, flags);
spin_unlock(&up->port.lock);
local_irq_restore(flags);
}
static int serial8250_console_setup(struct console *co, char *options)

View file

@ -673,7 +673,7 @@ static void dz_reset(struct dz_port *dport)
}
#ifdef CONFIG_SERIAL_DZ_CONSOLE
static void dz_console_putchar(struct uart_port *port, int ch)
static void dz_console_putchar(struct uart_port *uport, int ch)
{
struct dz_port *dport = (struct dz_port *)uport;
unsigned long flags;

View file

@ -1143,9 +1143,8 @@ static void __init ip22zilog_prepare(void)
up[(chip * 2) + 1].port.fifosize = 1;
up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
up[(chip * 2) + 1].port.flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
up[(chip * 2) + 1].port.line = (chip * 2) + 1;
up[(chip * 2) + 1].flags = 0;
up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
}
}

View file

@ -2036,6 +2036,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
case UPIO_MEM:
case UPIO_MEM32:
case UPIO_AU:
case UPIO_TSI:
snprintf(address, sizeof(address),
"MMIO 0x%lx", port->mapbase);
break;

View file

@ -1047,12 +1047,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
up = &sunsab_ports[inst * 2];
err = sunsab_init_one(&up[0], op,
sizeof(union sab82532_async_regs),
0,
(inst * 2) + 0);
if (err)
return err;
err = sunsab_init_one(&up[0], op, 0,
err = sunsab_init_one(&up[1], op,
sizeof(union sab82532_async_regs),
(inst * 2) + 1);
if (err) {
of_iounmap(up[0].port.membase,
@ -1117,7 +1118,7 @@ static int __init sunsab_init(void)
int err;
num_channels = 0;
for_each_node_by_name(dp, "su")
for_each_node_by_name(dp, "se")
num_channels += 2;
for_each_node_by_name(dp, "serial") {
if (of_device_is_compatible(dp, "sab82532"))

View file

@ -1200,6 +1200,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
if (up->port.type == PORT_UNKNOWN)
return -ENODEV;
printk("%s: %s port at %lx, irq %u\n",
to_of_device(up->port.dev)->node->full_name,
(up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
up->port.mapbase, up->port.irq);
#ifdef CONFIG_SERIO
serio = &up->serio;
serio->port_data = up;
@ -1406,25 +1411,35 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
struct device_node *dp = op->node;
struct uart_sunsu_port *up;
struct resource *rp;
enum su_type type;
int err;
if (inst >= UART_NR)
return -EINVAL;
type = su_get_type(dp);
if (type == SU_PORT_PORT) {
if (inst >= UART_NR)
return -EINVAL;
up = &sunsu_ports[inst];
} else {
up = kzalloc(sizeof(*up), GFP_KERNEL);
if (!up)
return -ENOMEM;
}
up = &sunsu_ports[inst];
up->port.line = inst;
spin_lock_init(&up->port.lock);
up->su_type = su_get_type(dp);
up->su_type = type;
rp = &op->resource[0];
up->port.mapbase = op->resource[0].start;
up->port.mapbase = rp->start;
up->reg_size = (rp->end - rp->start) + 1;
up->port.membase = of_ioremap(rp, 0, up->reg_size, "su");
if (!up->port.membase)
if (!up->port.membase) {
if (type != SU_PORT_PORT)
kfree(up);
return -ENOMEM;
}
up->port.irq = op->irqs[0];
@ -1436,8 +1451,11 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
err = 0;
if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
err = sunsu_kbd_ms_init(up);
if (err)
if (err) {
kfree(up);
goto out_unmap;
}
dev_set_drvdata(&op->dev, up);
return 0;
}
@ -1476,8 +1494,12 @@ static int __devexit su_remove(struct of_device *dev)
#ifdef CONFIG_SERIO
serio_unregister_port(&up->serio);
#endif
} else if (up->port.type != PORT_UNKNOWN)
kfree(up);
} else if (up->port.type != PORT_UNKNOWN) {
uart_remove_one_port(&sunsu_reg, &up->port);
}
dev_set_drvdata(&dev->dev, NULL);
return 0;
}

View file

@ -68,9 +68,6 @@ static int num_sunzilog;
#define NUM_SUNZILOG num_sunzilog
#define NUM_CHANNELS (NUM_SUNZILOG * 2)
#define KEYBOARD_LINE 0x2
#define MOUSE_LINE 0x3
#define ZS_CLOCK 4915200 /* Zilog input clock rate. */
#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */
@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
{
int baud, brg;
if (channel == KEYBOARD_LINE) {
up->flags |= SUNZILOG_FLAG_CONS_KEYB;
if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
up->cflag = B1200 | CS8 | CLOCAL | CREAD;
baud = 1200;
} else {
up->flags |= SUNZILOG_FLAG_CONS_MOUSE;
up->cflag = B4800 | CS8 | CLOCAL | CREAD;
baud = 4800;
}
@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
}
#ifdef CONFIG_SERIO
static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
{
struct serio *serio = &up->serio;
serio->port_data = up;
serio->id.type = SERIO_RS232;
if (channel == KEYBOARD_LINE) {
if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
serio->id.proto = SERIO_SUNKBD;
strlcpy(serio->name, "zskbd", sizeof(serio->name));
} else {
@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch
strlcpy(serio->name, "zsms", sizeof(serio->name));
}
strlcpy(serio->phys,
(channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
((up->flags & SUNZILOG_FLAG_CONS_KEYB) ?
"zs/serio0" : "zs/serio1"),
sizeof(serio->phys));
serio->write = sunzilog_serio_write;
@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
(void) read_zsreg(channel, R0);
}
if (up->port.line == KEYBOARD_LINE ||
up->port.line == MOUSE_LINE) {
if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
SUNZILOG_FLAG_CONS_MOUSE)) {
sunzilog_init_kbdms(up, up->port.line);
up->curregs[R9] |= (NV | MIE);
write_zsreg(channel, R9, up->curregs[R9]);
@ -1313,37 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
spin_unlock_irqrestore(&up->port.lock, flags);
#ifdef CONFIG_SERIO
if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE)
sunzilog_register_serio(up, up->port.line);
if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
SUNZILOG_FLAG_CONS_MOUSE))
sunzilog_register_serio(up);
#endif
}
static int __devinit zs_get_instance(struct device_node *dp)
{
int ret;
ret = of_getintprop_default(dp, "slave", -1);
if (ret != -1)
return ret;
if (of_find_property(dp, "keyboard", NULL))
ret = 1;
else
ret = 0;
return ret;
}
static int zilog_irq = -1;
static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
{
struct of_device *op = to_of_device(&dev->dev);
static int inst;
struct uart_sunzilog_port *up;
struct zilog_layout __iomem *rp;
int inst = zs_get_instance(dev->node);
int keyboard_mouse;
int err;
keyboard_mouse = 0;
if (of_find_property(op->node, "keyboard", NULL))
keyboard_mouse = 1;
sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
sizeof(struct zilog_layout),
"zs");
@ -1352,16 +1337,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
rp = sunzilog_chip_regs[inst];
if (zilog_irq == -1) {
if (zilog_irq == -1)
zilog_irq = op->irqs[0];
err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
"zs", sunzilog_irq_chain);
if (err) {
of_iounmap(rp, sizeof(struct zilog_layout));
return err;
}
}
up = &sunzilog_port_table[inst * 2];
@ -1378,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
up[0].port.line = (inst * 2) + 0;
up[0].port.dev = &op->dev;
up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
if (inst == 1)
if (keyboard_mouse)
up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
sunzilog_init_hw(&up[0]);
@ -1395,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
up[1].port.line = (inst * 2) + 1;
up[1].port.dev = &op->dev;
up[1].flags |= 0;
if (inst == 1)
if (keyboard_mouse)
up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
sunzilog_init_hw(&up[1]);
if (inst != 1) {
if (!keyboard_mouse) {
err = uart_add_one_port(&sunzilog_reg, &up[0].port);
if (err) {
of_iounmap(rp, sizeof(struct zilog_layout));
@ -1411,9 +1388,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
of_iounmap(rp, sizeof(struct zilog_layout));
return err;
}
} else {
printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
"is a zs\n",
op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
"is a zs\n",
op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
}
dev_set_drvdata(&dev->dev, &up[0]);
dev_set_drvdata(&op->dev, &up[0]);
inst++;
return 0;
}
@ -1462,36 +1448,65 @@ static struct of_platform_driver zs_driver = {
static int __init sunzilog_init(void)
{
struct device_node *dp;
int err;
int err, uart_count;
int num_keybms;
NUM_SUNZILOG = 0;
for_each_node_by_name(dp, "zs")
num_keybms = 0;
for_each_node_by_name(dp, "zs") {
NUM_SUNZILOG++;
if (of_find_property(dp, "keyboard", NULL))
num_keybms++;
}
uart_count = 0;
if (NUM_SUNZILOG) {
int uart_count;
err = sunzilog_alloc_tables();
if (err)
return err;
goto out;
/* Subtract 1 for keyboard, 1 for mouse. */
uart_count = (NUM_SUNZILOG * 2) - 2;
uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms);
sunzilog_reg.nr = uart_count;
sunzilog_reg.minor = sunserial_current_minor;
err = uart_register_driver(&sunzilog_reg);
if (err) {
sunzilog_free_tables();
return err;
}
if (err)
goto out_free_tables;
sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
sunzilog_reg.cons = SUNZILOG_CONSOLE();
sunserial_current_minor += uart_count;
}
return of_register_driver(&zs_driver, &of_bus_type);
err = of_register_driver(&zs_driver, &of_bus_type);
if (err)
goto out_unregister_uart;
if (zilog_irq != -1) {
err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
"zs", sunzilog_irq_chain);
if (err)
goto out_unregister_driver;
}
out:
return err;
out_unregister_driver:
of_unregister_driver(&zs_driver);
out_unregister_uart:
if (NUM_SUNZILOG) {
uart_unregister_driver(&sunzilog_reg);
sunzilog_reg.cons = NULL;
}
out_free_tables:
sunzilog_free_tables();
goto out;
}
static void __exit sunzilog_exit(void)

View file

@ -38,6 +38,7 @@
#include <linux/tty_flip.h>
#include <asm/io.h>
#include <asm/vr41xx/irq.h>
#include <asm/vr41xx/siu.h>
#include <asm/vr41xx/vr41xx.h>