aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2009-01-02 08:49:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:43 -0500
commit7d6a07d123b62bf4fa71867420c23da3ca36c995 (patch)
treeccb554b8bf86b9cf1b4f6bcd88745e0c5cb1793e
parentb430428a188e8a434325e251d0704af4b88b4711 (diff)
8250: Serial driver changes to support future Cavium OCTEON serial patches.
In order to use Cavium OCTEON specific serial i/o drivers, we first patch the 8250 driver to use replaceable I/O functions. Compatible I/O functions are added for existing iotypeS. An added benefit of this change is that it makes it easy to factor some of the existing special cases out to board/SOC specific support code. The alternative is to load up 8250.c with a bunch of OCTEON specific iotype code and bug work-arounds. Signed-off-by: David Daney <ddaney@caviumnetworks.com> Signed-off-by: Tomaso Paoletti <tpaoletti@caviumnetworks.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/serial/8250.c194
-rw-r--r--include/linux/serial_8250.h2
-rw-r--r--include/linux/serial_core.h2
3 files changed, 140 insertions, 58 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 8e28750a4058..849af9d21feb 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -303,16 +303,16 @@ static const u8 au_io_out_map[] = {
303}; 303};
304 304
305/* sane hardware needs no mapping */ 305/* sane hardware needs no mapping */
306static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) 306static inline int map_8250_in_reg(struct uart_port *p, int offset)
307{ 307{
308 if (up->port.iotype != UPIO_AU) 308 if (p->iotype != UPIO_AU)
309 return offset; 309 return offset;
310 return au_io_in_map[offset]; 310 return au_io_in_map[offset];
311} 311}
312 312
313static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) 313static inline int map_8250_out_reg(struct uart_port *p, int offset)
314{ 314{
315 if (up->port.iotype != UPIO_AU) 315 if (p->iotype != UPIO_AU)
316 return offset; 316 return offset;
317 return au_io_out_map[offset]; 317 return au_io_out_map[offset];
318} 318}
@@ -341,16 +341,16 @@ static const u8
341 [UART_SCR] = 0x2c 341 [UART_SCR] = 0x2c
342 }; 342 };
343 343
344static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) 344static inline int map_8250_in_reg(struct uart_port *p, int offset)
345{ 345{
346 if (up->port.iotype != UPIO_RM9000) 346 if (p->iotype != UPIO_RM9000)
347 return offset; 347 return offset;
348 return regmap_in[offset]; 348 return regmap_in[offset];
349} 349}
350 350
351static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) 351static inline int map_8250_out_reg(struct uart_port *p, int offset)
352{ 352{
353 if (up->port.iotype != UPIO_RM9000) 353 if (p->iotype != UPIO_RM9000)
354 return offset; 354 return offset;
355 return regmap_out[offset]; 355 return regmap_out[offset];
356} 356}
@@ -363,108 +363,170 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
363 363
364#endif 364#endif
365 365
366static unsigned int serial_in(struct uart_8250_port *up, int offset) 366static unsigned int hub6_serial_in(struct uart_port *p, int offset)
367{ 367{
368 unsigned int tmp; 368 offset = map_8250_in_reg(p, offset) << p->regshift;
369 offset = map_8250_in_reg(up, offset) << up->port.regshift; 369 outb(p->hub6 - 1 + offset, p->iobase);
370 return inb(p->iobase + 1);
371}
370 372
371 switch (up->port.iotype) { 373static void hub6_serial_out(struct uart_port *p, int offset, int value)
372 case UPIO_HUB6: 374{
373 outb(up->port.hub6 - 1 + offset, up->port.iobase); 375 offset = map_8250_out_reg(p, offset) << p->regshift;
374 return inb(up->port.iobase + 1); 376 outb(p->hub6 - 1 + offset, p->iobase);
377 outb(value, p->iobase + 1);
378}
375 379
376 case UPIO_MEM: 380static unsigned int mem_serial_in(struct uart_port *p, int offset)
377 case UPIO_DWAPB: 381{
378 return readb(up->port.membase + offset); 382 offset = map_8250_in_reg(p, offset) << p->regshift;
383 return readb(p->membase + offset);
384}
379 385
380 case UPIO_RM9000: 386static void mem_serial_out(struct uart_port *p, int offset, int value)
381 case UPIO_MEM32: 387{
382 return readl(up->port.membase + offset); 388 offset = map_8250_out_reg(p, offset) << p->regshift;
389 writeb(value, p->membase + offset);
390}
391
392static void mem32_serial_out(struct uart_port *p, int offset, int value)
393{
394 offset = map_8250_out_reg(p, offset) << p->regshift;
395 writel(value, p->membase + offset);
396}
397
398static unsigned int mem32_serial_in(struct uart_port *p, int offset)
399{
400 offset = map_8250_in_reg(p, offset) << p->regshift;
401 return readl(p->membase + offset);
402}
383 403
384#ifdef CONFIG_SERIAL_8250_AU1X00 404#ifdef CONFIG_SERIAL_8250_AU1X00
385 case UPIO_AU: 405static unsigned int au_serial_in(struct uart_port *p, int offset)
386 return __raw_readl(up->port.membase + offset); 406{
407 offset = map_8250_in_reg(p, offset) << p->regshift;
408 return __raw_readl(p->membase + offset);
409}
410
411static void au_serial_out(struct uart_port *p, int offset, int value)
412{
413 offset = map_8250_out_reg(p, offset) << p->regshift;
414 __raw_writel(value, p->membase + offset);
415}
387#endif 416#endif
388 417
389 case UPIO_TSI: 418static unsigned int tsi_serial_in(struct uart_port *p, int offset)
390 if (offset == UART_IIR) { 419{
391 tmp = readl(up->port.membase + (UART_IIR & ~3)); 420 unsigned int tmp;
392 return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ 421 offset = map_8250_in_reg(p, offset) << p->regshift;
393 } else 422 if (offset == UART_IIR) {
394 return readb(up->port.membase + offset); 423 tmp = readl(p->membase + (UART_IIR & ~3));
424 return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
425 } else
426 return readb(p->membase + offset);
427}
395 428
396 default: 429static void tsi_serial_out(struct uart_port *p, int offset, int value)
397 return inb(up->port.iobase + offset); 430{
398 } 431 offset = map_8250_out_reg(p, offset) << p->regshift;
432 if (!((offset == UART_IER) && (value & UART_IER_UUE)))
433 writeb(value, p->membase + offset);
399} 434}
400 435
401static void 436static void dwapb_serial_out(struct uart_port *p, int offset, int value)
402serial_out(struct uart_8250_port *up, int offset, int value)
403{ 437{
404 /* Save the offset before it's remapped */
405 int save_offset = offset; 438 int save_offset = offset;
406 offset = map_8250_out_reg(up, offset) << up->port.regshift; 439 offset = map_8250_out_reg(p, offset) << p->regshift;
440 /* Save the LCR value so it can be re-written when a
441 * Busy Detect interrupt occurs. */
442 if (save_offset == UART_LCR) {
443 struct uart_8250_port *up = (struct uart_8250_port *)p;
444 up->lcr = value;
445 }
446 writeb(value, p->membase + offset);
447 /* Read the IER to ensure any interrupt is cleared before
448 * returning from ISR. */
449 if (save_offset == UART_TX || save_offset == UART_IER)
450 value = p->serial_in(p, UART_IER);
451}
407 452
408 switch (up->port.iotype) { 453static unsigned int io_serial_in(struct uart_port *p, int offset)
454{
455 offset = map_8250_in_reg(p, offset) << p->regshift;
456 return inb(p->iobase + offset);
457}
458
459static void io_serial_out(struct uart_port *p, int offset, int value)
460{
461 offset = map_8250_out_reg(p, offset) << p->regshift;
462 outb(value, p->iobase + offset);
463}
464
465static void set_io_from_upio(struct uart_port *p)
466{
467 switch (p->iotype) {
409 case UPIO_HUB6: 468 case UPIO_HUB6:
410 outb(up->port.hub6 - 1 + offset, up->port.iobase); 469 p->serial_in = hub6_serial_in;
411 outb(value, up->port.iobase + 1); 470 p->serial_out = hub6_serial_out;
412 break; 471 break;
413 472
414 case UPIO_MEM: 473 case UPIO_MEM:
415 writeb(value, up->port.membase + offset); 474 p->serial_in = mem_serial_in;
475 p->serial_out = mem_serial_out;
416 break; 476 break;
417 477
418 case UPIO_RM9000: 478 case UPIO_RM9000:
419 case UPIO_MEM32: 479 case UPIO_MEM32:
420 writel(value, up->port.membase + offset); 480 p->serial_in = mem32_serial_in;
481 p->serial_out = mem32_serial_out;
421 break; 482 break;
422 483
423#ifdef CONFIG_SERIAL_8250_AU1X00 484#ifdef CONFIG_SERIAL_8250_AU1X00
424 case UPIO_AU: 485 case UPIO_AU:
425 __raw_writel(value, up->port.membase + offset); 486 p->serial_in = au_serial_in;
487 p->serial_out = au_serial_out;
426 break; 488 break;
427#endif 489#endif
428 case UPIO_TSI: 490 case UPIO_TSI:
429 if (!((offset == UART_IER) && (value & UART_IER_UUE))) 491 p->serial_in = tsi_serial_in;
430 writeb(value, up->port.membase + offset); 492 p->serial_out = tsi_serial_out;
431 break; 493 break;
432 494
433 case UPIO_DWAPB: 495 case UPIO_DWAPB:
434 /* Save the LCR value so it can be re-written when a 496 p->serial_in = mem_serial_in;
435 * Busy Detect interrupt occurs. */ 497 p->serial_out = dwapb_serial_out;
436 if (save_offset == UART_LCR)
437 up->lcr = value;
438 writeb(value, up->port.membase + offset);
439 /* Read the IER to ensure any interrupt is cleared before
440 * returning from ISR. */
441 if (save_offset == UART_TX || save_offset == UART_IER)
442 value = serial_in(up, UART_IER);
443 break; 498 break;
444 499
445 default: 500 default:
446 outb(value, up->port.iobase + offset); 501 p->serial_in = io_serial_in;
502 p->serial_out = io_serial_out;
503 break;
447 } 504 }
448} 505}
449 506
450static void 507static void
451serial_out_sync(struct uart_8250_port *up, int offset, int value) 508serial_out_sync(struct uart_8250_port *up, int offset, int value)
452{ 509{
453 switch (up->port.iotype) { 510 struct uart_port *p = &up->port;
511 switch (p->iotype) {
454 case UPIO_MEM: 512 case UPIO_MEM:
455 case UPIO_MEM32: 513 case UPIO_MEM32:
456#ifdef CONFIG_SERIAL_8250_AU1X00 514#ifdef CONFIG_SERIAL_8250_AU1X00
457 case UPIO_AU: 515 case UPIO_AU:
458#endif 516#endif
459 case UPIO_DWAPB: 517 case UPIO_DWAPB:
460 serial_out(up, offset, value); 518 p->serial_out(p, offset, value);
461 serial_in(up, UART_LCR); /* safe, no side-effects */ 519 p->serial_in(p, UART_LCR); /* safe, no side-effects */
462 break; 520 break;
463 default: 521 default:
464 serial_out(up, offset, value); 522 p->serial_out(p, offset, value);
465 } 523 }
466} 524}
467 525
526#define serial_in(up, offset) \
527 (up->port.serial_in(&(up)->port, (offset)))
528#define serial_out(up, offset, value) \
529 (up->port.serial_out(&(up)->port, (offset), (value)))
468/* 530/*
469 * We used to support using pause I/O for certain machines. We 531 * We used to support using pause I/O for certain machines. We
470 * haven't supported this for a while, but just in case it's badly 532 * haven't supported this for a while, but just in case it's badly
@@ -2576,6 +2638,7 @@ static void __init serial8250_isa_init_ports(void)
2576 up->port.membase = old_serial_port[i].iomem_base; 2638 up->port.membase = old_serial_port[i].iomem_base;
2577 up->port.iotype = old_serial_port[i].io_type; 2639 up->port.iotype = old_serial_port[i].io_type;
2578 up->port.regshift = old_serial_port[i].iomem_reg_shift; 2640 up->port.regshift = old_serial_port[i].iomem_reg_shift;
2641 set_io_from_upio(&up->port);
2579 if (share_irqs) 2642 if (share_irqs)
2580 up->port.flags |= UPF_SHARE_IRQ; 2643 up->port.flags |= UPF_SHARE_IRQ;
2581 } 2644 }
@@ -2769,6 +2832,13 @@ int __init early_serial_setup(struct uart_port *port)
2769 p->flags = port->flags; 2832 p->flags = port->flags;
2770 p->mapbase = port->mapbase; 2833 p->mapbase = port->mapbase;
2771 p->private_data = port->private_data; 2834 p->private_data = port->private_data;
2835
2836 set_io_from_upio(p);
2837 if (port->serial_in)
2838 p->serial_in = port->serial_in;
2839 if (port->serial_out)
2840 p->serial_out = port->serial_out;
2841
2772 return 0; 2842 return 0;
2773} 2843}
2774 2844
@@ -2833,6 +2903,8 @@ static int __devinit serial8250_probe(struct platform_device *dev)
2833 port.mapbase = p->mapbase; 2903 port.mapbase = p->mapbase;
2834 port.hub6 = p->hub6; 2904 port.hub6 = p->hub6;
2835 port.private_data = p->private_data; 2905 port.private_data = p->private_data;
2906 port.serial_in = p->serial_in;
2907 port.serial_out = p->serial_out;
2836 port.dev = &dev->dev; 2908 port.dev = &dev->dev;
2837 if (share_irqs) 2909 if (share_irqs)
2838 port.flags |= UPF_SHARE_IRQ; 2910 port.flags |= UPF_SHARE_IRQ;
@@ -2986,6 +3058,12 @@ int serial8250_register_port(struct uart_port *port)
2986 uart->port.private_data = port->private_data; 3058 uart->port.private_data = port->private_data;
2987 if (port->dev) 3059 if (port->dev)
2988 uart->port.dev = port->dev; 3060 uart->port.dev = port->dev;
3061 set_io_from_upio(&uart->port);
3062 /* Possibly override default I/O functions. */
3063 if (port->serial_in)
3064 uart->port.serial_in = port->serial_in;
3065 if (port->serial_out)
3066 uart->port.serial_out = port->serial_out;
2989 3067
2990 ret = uart_add_one_port(&serial8250_reg, &uart->port); 3068 ret = uart_add_one_port(&serial8250_reg, &uart->port);
2991 if (ret == 0) 3069 if (ret == 0)
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 3d37c94abbc8..77d83d929f2c 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -28,6 +28,8 @@ struct plat_serial8250_port {
28 unsigned char iotype; /* UPIO_* */ 28 unsigned char iotype; /* UPIO_* */
29 unsigned char hub6; 29 unsigned char hub6;
30 upf_t flags; /* UPF_* flags */ 30 upf_t flags; /* UPF_* flags */
31 unsigned int (*serial_in)(struct uart_port *, int);
32 void (*serial_out)(struct uart_port *, int, int);
31}; 33};
32 34
33/* 35/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 2395969faa04..60061f44f3d8 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -248,6 +248,8 @@ struct uart_port {
248 spinlock_t lock; /* port lock */ 248 spinlock_t lock; /* port lock */
249 unsigned long iobase; /* in/out[bwl] */ 249 unsigned long iobase; /* in/out[bwl] */
250 unsigned char __iomem *membase; /* read/write[bwl] */ 250 unsigned char __iomem *membase; /* read/write[bwl] */
251 unsigned int (*serial_in)(struct uart_port *, int);
252 void (*serial_out)(struct uart_port *, int, int);
251 unsigned int irq; /* irq number */ 253 unsigned int irq; /* irq number */
252 unsigned int uartclk; /* base uart clock */ 254 unsigned int uartclk; /* base uart clock */
253 unsigned int fifosize; /* tx fifo size */ 255 unsigned int fifosize; /* tx fifo size */