Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+37 -18
+33 -12
drivers/serial/sh-sci.c
··· 3 3 * 4 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 7 * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). 8 8 * 9 9 * based off of the old drivers/char/sh-sci.c by: ··· 46 46 #include <linux/cpufreq.h> 47 47 #include <linux/clk.h> 48 48 #include <linux/ctype.h> 49 + #include <linux/err.h> 49 50 50 51 #ifdef CONFIG_SUPERH 51 52 #include <asm/clock.h> ··· 1146 1145 break; 1147 1146 } 1148 1147 1149 - #if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) 1150 - if (port->mapbase == 0) 1148 + if (port->flags & UPF_IOREMAP && !port->membase) { 1149 + #if defined(CONFIG_SUPERH64) 1151 1150 port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); 1152 - 1153 - port->membase = (void __iomem *)port->mapbase; 1151 + port->membase = (void __iomem *)port->mapbase; 1152 + #else 1153 + port->membase = ioremap_nocache(port->mapbase, 0x40); 1154 1154 #endif 1155 + 1156 + printk(KERN_ERR "sci: can't remap port#%d\n", port->line); 1157 + } 1155 1158 } 1156 1159 1157 1160 static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) ··· 1441 1436 static int __devinit sci_probe(struct platform_device *dev) 1442 1437 { 1443 1438 struct plat_sci_port *p = dev->dev.platform_data; 1444 - int i; 1439 + int i, ret = -EINVAL; 1445 1440 1446 1441 for (i = 0; p && p->flags != 0; p++, i++) { 1447 1442 struct sci_port *sciport = &sci_ports[i]; ··· 1458 1453 1459 1454 sciport->port.mapbase = p->mapbase; 1460 1455 1461 - /* 1462 - * For the simple (and majority of) cases where we don't need 1463 - * to do any remapping, just cast the cookie directly. 1464 - */ 1465 - if (p->mapbase && !p->membase && !(p->flags & UPF_IOREMAP)) 1466 - p->membase = (void __iomem *)p->mapbase; 1456 + if (p->mapbase && !p->membase) { 1457 + if (p->flags & UPF_IOREMAP) { 1458 + p->membase = ioremap_nocache(p->mapbase, 0x40); 1459 + if (IS_ERR(p->membase)) { 1460 + ret = PTR_ERR(p->membase); 1461 + goto err_unreg; 1462 + } 1463 + } else { 1464 + /* 1465 + * For the simple (and majority of) cases 1466 + * where we don't need to do any remapping, 1467 + * just cast the cookie directly. 1468 + */ 1469 + p->membase = (void __iomem *)p->mapbase; 1470 + } 1471 + } 1467 1472 1468 1473 sciport->port.membase = p->membase; 1469 1474 ··· 1504 1489 #endif 1505 1490 1506 1491 return 0; 1492 + 1493 + err_unreg: 1494 + for (i = i - 1; i >= 0; i--) 1495 + uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); 1496 + 1497 + return ret; 1507 1498 } 1508 1499 1509 1500 static int __devexit sci_remove(struct platform_device *dev)
+4 -6
drivers/serial/sh-sci.h
··· 320 320 #define SCI_EVENT_WRITE_WAKEUP 0 321 321 322 322 #define SCI_IN(size, offset) \ 323 - unsigned int addr = port->mapbase + (offset); \ 324 323 if ((size) == 8) { \ 325 - return ctrl_inb(addr); \ 324 + return ioread8(port->membase + (offset)); \ 326 325 } else { \ 327 - return ctrl_inw(addr); \ 326 + return ioread16(port->membase + (offset)); \ 328 327 } 329 328 #define SCI_OUT(size, offset, value) \ 330 - unsigned int addr = port->mapbase + (offset); \ 331 329 if ((size) == 8) { \ 332 - ctrl_outb(value, addr); \ 330 + iowrite8(value, port->membase + (offset)); \ 333 331 } else if ((size) == 16) { \ 334 - ctrl_outw(value, addr); \ 332 + iowrite16(value, port->membase + (offset)); \ 335 333 } 336 334 337 335 #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\