diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-10-01 02:46:58 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-10-01 02:46:58 -0400 |
commit | 7ff731aeba1cdac473c818a9884eb94ddad18e7f (patch) | |
tree | ac415594035811fde75bd2963d861a03d0efcb6b /drivers/serial | |
parent | 62429e03644833693e6f94afe537f252e2d3b475 (diff) |
serial: sh-sci: Handle the general UPF_IOREMAP case.
Presently we don't do much with UPF_IOREMAP other than special case it
for SH-5's onchip_remap() on the early console. Tie this in generically
for platforms that need the remap.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/sh-sci.c | 45 | ||||
-rw-r--r-- | drivers/serial/sh-sci.h | 10 |
2 files changed, 37 insertions, 18 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f5aebc9f27e7..ac658a7a27be 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | 4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) |
5 | * | 5 | * |
6 | * Copyright (C) 2002 - 2006 Paul Mundt | 6 | * Copyright (C) 2002 - 2008 Paul Mundt |
7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). | 7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). |
8 | * | 8 | * |
9 | * based off of the old drivers/char/sh-sci.c by: | 9 | * based off of the old drivers/char/sh-sci.c by: |
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/cpufreq.h> | 46 | #include <linux/cpufreq.h> |
47 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/err.h> | ||
49 | 50 | ||
50 | #ifdef CONFIG_SUPERH | 51 | #ifdef CONFIG_SUPERH |
51 | #include <asm/clock.h> | 52 | #include <asm/clock.h> |
@@ -1145,12 +1146,16 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
1145 | break; | 1146 | break; |
1146 | } | 1147 | } |
1147 | 1148 | ||
1148 | #if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 1149 | if (port->flags & UPF_IOREMAP && !port->membase) { |
1149 | if (port->mapbase == 0) | 1150 | #if defined(CONFIG_SUPERH64) |
1150 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); | 1151 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); |
1151 | 1152 | port->membase = (void __iomem *)port->mapbase; | |
1152 | port->membase = (void __iomem *)port->mapbase; | 1153 | #else |
1154 | port->membase = ioremap_nocache(port->mapbase, 0x40); | ||
1153 | #endif | 1155 | #endif |
1156 | |||
1157 | printk(KERN_ERR "sci: can't remap port#%d\n", port->line); | ||
1158 | } | ||
1154 | } | 1159 | } |
1155 | 1160 | ||
1156 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 1161 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
@@ -1436,7 +1441,7 @@ static struct uart_driver sci_uart_driver = { | |||
1436 | static int __devinit sci_probe(struct platform_device *dev) | 1441 | static int __devinit sci_probe(struct platform_device *dev) |
1437 | { | 1442 | { |
1438 | struct plat_sci_port *p = dev->dev.platform_data; | 1443 | struct plat_sci_port *p = dev->dev.platform_data; |
1439 | int i; | 1444 | int i, ret = -EINVAL; |
1440 | 1445 | ||
1441 | for (i = 0; p && p->flags != 0; p++, i++) { | 1446 | for (i = 0; p && p->flags != 0; p++, i++) { |
1442 | struct sci_port *sciport = &sci_ports[i]; | 1447 | struct sci_port *sciport = &sci_ports[i]; |
@@ -1453,12 +1458,22 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1453 | 1458 | ||
1454 | sciport->port.mapbase = p->mapbase; | 1459 | sciport->port.mapbase = p->mapbase; |
1455 | 1460 | ||
1456 | /* | 1461 | if (p->mapbase && !p->membase) { |
1457 | * For the simple (and majority of) cases where we don't need | 1462 | if (p->flags & UPF_IOREMAP) { |
1458 | * to do any remapping, just cast the cookie directly. | 1463 | p->membase = ioremap_nocache(p->mapbase, 0x40); |
1459 | */ | 1464 | if (IS_ERR(p->membase)) { |
1460 | if (p->mapbase && !p->membase && !(p->flags & UPF_IOREMAP)) | 1465 | ret = PTR_ERR(p->membase); |
1461 | p->membase = (void __iomem *)p->mapbase; | 1466 | goto err_unreg; |
1467 | } | ||
1468 | } else { | ||
1469 | /* | ||
1470 | * For the simple (and majority of) cases | ||
1471 | * where we don't need to do any remapping, | ||
1472 | * just cast the cookie directly. | ||
1473 | */ | ||
1474 | p->membase = (void __iomem *)p->mapbase; | ||
1475 | } | ||
1476 | } | ||
1462 | 1477 | ||
1463 | sciport->port.membase = p->membase; | 1478 | sciport->port.membase = p->membase; |
1464 | 1479 | ||
@@ -1489,6 +1504,12 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1489 | #endif | 1504 | #endif |
1490 | 1505 | ||
1491 | return 0; | 1506 | return 0; |
1507 | |||
1508 | err_unreg: | ||
1509 | for (i = i - 1; i >= 0; i--) | ||
1510 | uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); | ||
1511 | |||
1512 | return ret; | ||
1492 | } | 1513 | } |
1493 | 1514 | ||
1494 | static int __devexit sci_remove(struct platform_device *dev) | 1515 | static int __devexit sci_remove(struct platform_device *dev) |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 8a0749e34ca3..2b4c1dff1e85 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -320,18 +320,16 @@ | |||
320 | #define SCI_EVENT_WRITE_WAKEUP 0 | 320 | #define SCI_EVENT_WRITE_WAKEUP 0 |
321 | 321 | ||
322 | #define SCI_IN(size, offset) \ | 322 | #define SCI_IN(size, offset) \ |
323 | unsigned int addr = port->mapbase + (offset); \ | ||
324 | if ((size) == 8) { \ | 323 | if ((size) == 8) { \ |
325 | return ctrl_inb(addr); \ | 324 | return ioread8(port->membase + (offset)); \ |
326 | } else { \ | 325 | } else { \ |
327 | return ctrl_inw(addr); \ | 326 | return ioread16(port->membase + (offset)); \ |
328 | } | 327 | } |
329 | #define SCI_OUT(size, offset, value) \ | 328 | #define SCI_OUT(size, offset, value) \ |
330 | unsigned int addr = port->mapbase + (offset); \ | ||
331 | if ((size) == 8) { \ | 329 | if ((size) == 8) { \ |
332 | ctrl_outb(value, addr); \ | 330 | iowrite8(value, port->membase + (offset)); \ |
333 | } else if ((size) == 16) { \ | 331 | } else if ((size) == 16) { \ |
334 | ctrl_outw(value, addr); \ | 332 | iowrite16(value, port->membase + (offset)); \ |
335 | } | 333 | } |
336 | 334 | ||
337 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 335 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |