0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/errno.h>
0009 #include <linux/tty.h>
0010 #include <linux/tty_flip.h>
0011 #include <linux/major.h>
0012 #include <linux/circ_buf.h>
0013 #include <linux/serial.h>
0014 #include <linux/sysrq.h>
0015 #include <linux/console.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/slab.h>
0018 #include <linux/delay.h>
0019 #include <linux/init.h>
0020 #include <linux/of_device.h>
0021
0022 #include <asm/hypervisor.h>
0023 #include <asm/spitfire.h>
0024 #include <asm/prom.h>
0025 #include <asm/irq.h>
0026 #include <asm/setup.h>
0027
0028 #include <linux/serial_core.h>
0029 #include <linux/sunserialcore.h>
0030
0031 #define CON_BREAK ((long)-1)
0032 #define CON_HUP ((long)-2)
0033
0034 #define IGNORE_BREAK 0x1
0035 #define IGNORE_ALL 0x2
0036
0037 static char *con_write_page;
0038 static char *con_read_page;
0039
0040 static int hung_up = 0;
0041
0042 static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit)
0043 {
0044 while (!uart_circ_empty(xmit)) {
0045 long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
0046
0047 if (status != HV_EOK)
0048 break;
0049
0050 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0051 port->icount.tx++;
0052 }
0053 }
0054
0055 static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit)
0056 {
0057 while (!uart_circ_empty(xmit)) {
0058 unsigned long ra = __pa(xmit->buf + xmit->tail);
0059 unsigned long len, status, sent;
0060
0061 len = CIRC_CNT_TO_END(xmit->head, xmit->tail,
0062 UART_XMIT_SIZE);
0063 status = sun4v_con_write(ra, len, &sent);
0064 if (status != HV_EOK)
0065 break;
0066 xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1);
0067 port->icount.tx += sent;
0068 }
0069 }
0070
0071 static int receive_chars_getchar(struct uart_port *port)
0072 {
0073 int saw_console_brk = 0;
0074 int limit = 10000;
0075
0076 while (limit-- > 0) {
0077 long status;
0078 long c = sun4v_con_getchar(&status);
0079
0080 if (status == HV_EWOULDBLOCK)
0081 break;
0082
0083 if (c == CON_BREAK) {
0084 if (uart_handle_break(port))
0085 continue;
0086 saw_console_brk = 1;
0087 c = 0;
0088 }
0089
0090 if (c == CON_HUP) {
0091 hung_up = 1;
0092 uart_handle_dcd_change(port, 0);
0093 } else if (hung_up) {
0094 hung_up = 0;
0095 uart_handle_dcd_change(port, 1);
0096 }
0097
0098 if (port->state == NULL) {
0099 uart_handle_sysrq_char(port, c);
0100 continue;
0101 }
0102
0103 port->icount.rx++;
0104
0105 if (uart_handle_sysrq_char(port, c))
0106 continue;
0107
0108 tty_insert_flip_char(&port->state->port, c, TTY_NORMAL);
0109 }
0110
0111 return saw_console_brk;
0112 }
0113
0114 static int receive_chars_read(struct uart_port *port)
0115 {
0116 static int saw_console_brk;
0117 int limit = 10000;
0118
0119 while (limit-- > 0) {
0120 unsigned long ra = __pa(con_read_page);
0121 unsigned long bytes_read, i;
0122 long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read);
0123
0124 if (stat != HV_EOK) {
0125 bytes_read = 0;
0126
0127 if (stat == CON_BREAK) {
0128 if (saw_console_brk)
0129 sun_do_break();
0130
0131 if (uart_handle_break(port))
0132 continue;
0133 saw_console_brk = 1;
0134 *con_read_page = 0;
0135 bytes_read = 1;
0136 } else if (stat == CON_HUP) {
0137 hung_up = 1;
0138 uart_handle_dcd_change(port, 0);
0139 continue;
0140 } else {
0141
0142 break;
0143 }
0144 }
0145
0146 if (hung_up) {
0147 hung_up = 0;
0148 uart_handle_dcd_change(port, 1);
0149 }
0150
0151 if (port->sysrq != 0 && *con_read_page) {
0152 for (i = 0; i < bytes_read; i++)
0153 uart_handle_sysrq_char(port, con_read_page[i]);
0154 saw_console_brk = 0;
0155 }
0156
0157 if (port->state == NULL)
0158 continue;
0159
0160 port->icount.rx += bytes_read;
0161
0162 tty_insert_flip_string(&port->state->port, con_read_page,
0163 bytes_read);
0164 }
0165
0166 return saw_console_brk;
0167 }
0168
0169 struct sunhv_ops {
0170 void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit);
0171 int (*receive_chars)(struct uart_port *port);
0172 };
0173
0174 static const struct sunhv_ops bychar_ops = {
0175 .transmit_chars = transmit_chars_putchar,
0176 .receive_chars = receive_chars_getchar,
0177 };
0178
0179 static const struct sunhv_ops bywrite_ops = {
0180 .transmit_chars = transmit_chars_write,
0181 .receive_chars = receive_chars_read,
0182 };
0183
0184 static const struct sunhv_ops *sunhv_ops = &bychar_ops;
0185
0186 static struct tty_port *receive_chars(struct uart_port *port)
0187 {
0188 struct tty_port *tport = NULL;
0189
0190 if (port->state != NULL)
0191 tport = &port->state->port;
0192
0193 if (sunhv_ops->receive_chars(port))
0194 sun_do_break();
0195
0196 return tport;
0197 }
0198
0199 static void transmit_chars(struct uart_port *port)
0200 {
0201 struct circ_buf *xmit;
0202
0203 if (!port->state)
0204 return;
0205
0206 xmit = &port->state->xmit;
0207 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
0208 return;
0209
0210 sunhv_ops->transmit_chars(port, xmit);
0211
0212 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0213 uart_write_wakeup(port);
0214 }
0215
0216 static irqreturn_t sunhv_interrupt(int irq, void *dev_id)
0217 {
0218 struct uart_port *port = dev_id;
0219 struct tty_port *tport;
0220 unsigned long flags;
0221
0222 spin_lock_irqsave(&port->lock, flags);
0223 tport = receive_chars(port);
0224 transmit_chars(port);
0225 spin_unlock_irqrestore(&port->lock, flags);
0226
0227 if (tport)
0228 tty_flip_buffer_push(tport);
0229
0230 return IRQ_HANDLED;
0231 }
0232
0233
0234 static unsigned int sunhv_tx_empty(struct uart_port *port)
0235 {
0236
0237
0238
0239
0240 return TIOCSER_TEMT;
0241 }
0242
0243
0244 static void sunhv_set_mctrl(struct uart_port *port, unsigned int mctrl)
0245 {
0246 return;
0247 }
0248
0249
0250 static unsigned int sunhv_get_mctrl(struct uart_port *port)
0251 {
0252 return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS;
0253 }
0254
0255
0256 static void sunhv_stop_tx(struct uart_port *port)
0257 {
0258 return;
0259 }
0260
0261
0262 static void sunhv_start_tx(struct uart_port *port)
0263 {
0264 transmit_chars(port);
0265 }
0266
0267
0268 static void sunhv_send_xchar(struct uart_port *port, char ch)
0269 {
0270 unsigned long flags;
0271 int limit = 10000;
0272
0273 if (ch == __DISABLED_CHAR)
0274 return;
0275
0276 spin_lock_irqsave(&port->lock, flags);
0277
0278 while (limit-- > 0) {
0279 long status = sun4v_con_putchar(ch);
0280 if (status == HV_EOK)
0281 break;
0282 udelay(1);
0283 }
0284
0285 spin_unlock_irqrestore(&port->lock, flags);
0286 }
0287
0288
0289 static void sunhv_stop_rx(struct uart_port *port)
0290 {
0291 }
0292
0293
0294 static void sunhv_break_ctl(struct uart_port *port, int break_state)
0295 {
0296 if (break_state) {
0297 unsigned long flags;
0298 int limit = 10000;
0299
0300 spin_lock_irqsave(&port->lock, flags);
0301
0302 while (limit-- > 0) {
0303 long status = sun4v_con_putchar(CON_BREAK);
0304 if (status == HV_EOK)
0305 break;
0306 udelay(1);
0307 }
0308
0309 spin_unlock_irqrestore(&port->lock, flags);
0310 }
0311 }
0312
0313
0314 static int sunhv_startup(struct uart_port *port)
0315 {
0316 return 0;
0317 }
0318
0319
0320 static void sunhv_shutdown(struct uart_port *port)
0321 {
0322 }
0323
0324
0325 static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios,
0326 struct ktermios *old)
0327 {
0328 unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
0329 unsigned int quot = uart_get_divisor(port, baud);
0330 unsigned int iflag, cflag;
0331 unsigned long flags;
0332
0333 spin_lock_irqsave(&port->lock, flags);
0334
0335 iflag = termios->c_iflag;
0336 cflag = termios->c_cflag;
0337
0338 port->ignore_status_mask = 0;
0339 if (iflag & IGNBRK)
0340 port->ignore_status_mask |= IGNORE_BREAK;
0341 if ((cflag & CREAD) == 0)
0342 port->ignore_status_mask |= IGNORE_ALL;
0343
0344
0345 uart_update_timeout(port, cflag,
0346 (port->uartclk / (16 * quot)));
0347
0348 spin_unlock_irqrestore(&port->lock, flags);
0349 }
0350
0351 static const char *sunhv_type(struct uart_port *port)
0352 {
0353 return "SUN4V HCONS";
0354 }
0355
0356 static void sunhv_release_port(struct uart_port *port)
0357 {
0358 }
0359
0360 static int sunhv_request_port(struct uart_port *port)
0361 {
0362 return 0;
0363 }
0364
0365 static void sunhv_config_port(struct uart_port *port, int flags)
0366 {
0367 }
0368
0369 static int sunhv_verify_port(struct uart_port *port, struct serial_struct *ser)
0370 {
0371 return -EINVAL;
0372 }
0373
0374 static const struct uart_ops sunhv_pops = {
0375 .tx_empty = sunhv_tx_empty,
0376 .set_mctrl = sunhv_set_mctrl,
0377 .get_mctrl = sunhv_get_mctrl,
0378 .stop_tx = sunhv_stop_tx,
0379 .start_tx = sunhv_start_tx,
0380 .send_xchar = sunhv_send_xchar,
0381 .stop_rx = sunhv_stop_rx,
0382 .break_ctl = sunhv_break_ctl,
0383 .startup = sunhv_startup,
0384 .shutdown = sunhv_shutdown,
0385 .set_termios = sunhv_set_termios,
0386 .type = sunhv_type,
0387 .release_port = sunhv_release_port,
0388 .request_port = sunhv_request_port,
0389 .config_port = sunhv_config_port,
0390 .verify_port = sunhv_verify_port,
0391 };
0392
0393 static struct uart_driver sunhv_reg = {
0394 .owner = THIS_MODULE,
0395 .driver_name = "sunhv",
0396 .dev_name = "ttyHV",
0397 .major = TTY_MAJOR,
0398 };
0399
0400 static struct uart_port *sunhv_port;
0401
0402 void sunhv_migrate_hvcons_irq(int cpu)
0403 {
0404
0405 irq_force_affinity(sunhv_port->irq, cpumask_of(cpu));
0406 }
0407
0408
0409
0410
0411
0412
0413 static int fill_con_write_page(const char *s, unsigned int n,
0414 unsigned long *page_bytes)
0415 {
0416 const char *orig_s = s;
0417 char *p = con_write_page;
0418 int left = PAGE_SIZE;
0419
0420 while (n--) {
0421 if (*s == '\n') {
0422 if (left < 2)
0423 break;
0424 *p++ = '\r';
0425 left--;
0426 } else if (left < 1)
0427 break;
0428 *p++ = *s++;
0429 left--;
0430 }
0431 *page_bytes = p - con_write_page;
0432 return s - orig_s;
0433 }
0434
0435 static void sunhv_console_write_paged(struct console *con, const char *s, unsigned n)
0436 {
0437 struct uart_port *port = sunhv_port;
0438 unsigned long flags;
0439 int locked = 1;
0440
0441 if (port->sysrq || oops_in_progress)
0442 locked = spin_trylock_irqsave(&port->lock, flags);
0443 else
0444 spin_lock_irqsave(&port->lock, flags);
0445
0446 while (n > 0) {
0447 unsigned long ra = __pa(con_write_page);
0448 unsigned long page_bytes;
0449 unsigned int cpy = fill_con_write_page(s, n,
0450 &page_bytes);
0451
0452 n -= cpy;
0453 s += cpy;
0454 while (page_bytes > 0) {
0455 unsigned long written;
0456 int limit = 1000000;
0457
0458 while (limit--) {
0459 unsigned long stat;
0460
0461 stat = sun4v_con_write(ra, page_bytes,
0462 &written);
0463 if (stat == HV_EOK)
0464 break;
0465 udelay(1);
0466 }
0467 if (limit < 0)
0468 break;
0469 page_bytes -= written;
0470 ra += written;
0471 }
0472 }
0473
0474 if (locked)
0475 spin_unlock_irqrestore(&port->lock, flags);
0476 }
0477
0478 static inline void sunhv_console_putchar(struct uart_port *port, char c)
0479 {
0480 int limit = 1000000;
0481
0482 while (limit-- > 0) {
0483 long status = sun4v_con_putchar(c);
0484 if (status == HV_EOK)
0485 break;
0486 udelay(1);
0487 }
0488 }
0489
0490 static void sunhv_console_write_bychar(struct console *con, const char *s, unsigned n)
0491 {
0492 struct uart_port *port = sunhv_port;
0493 unsigned long flags;
0494 int i, locked = 1;
0495
0496 if (port->sysrq || oops_in_progress)
0497 locked = spin_trylock_irqsave(&port->lock, flags);
0498 else
0499 spin_lock_irqsave(&port->lock, flags);
0500
0501 for (i = 0; i < n; i++) {
0502 if (*s == '\n')
0503 sunhv_console_putchar(port, '\r');
0504 sunhv_console_putchar(port, *s++);
0505 }
0506
0507 if (locked)
0508 spin_unlock_irqrestore(&port->lock, flags);
0509 }
0510
0511 static struct console sunhv_console = {
0512 .name = "ttyHV",
0513 .write = sunhv_console_write_bychar,
0514 .device = uart_console_device,
0515 .flags = CON_PRINTBUFFER,
0516 .index = -1,
0517 .data = &sunhv_reg,
0518 };
0519
0520 static int hv_probe(struct platform_device *op)
0521 {
0522 struct uart_port *port;
0523 unsigned long minor;
0524 int err;
0525
0526 if (op->archdata.irqs[0] == 0xffffffff)
0527 return -ENODEV;
0528
0529 port = kzalloc(sizeof(struct uart_port), GFP_KERNEL);
0530 if (unlikely(!port))
0531 return -ENOMEM;
0532
0533 minor = 1;
0534 if (sun4v_hvapi_register(HV_GRP_CORE, 1, &minor) == 0 &&
0535 minor >= 1) {
0536 err = -ENOMEM;
0537 con_write_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
0538 if (!con_write_page)
0539 goto out_free_port;
0540
0541 con_read_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
0542 if (!con_read_page)
0543 goto out_free_con_write_page;
0544
0545 sunhv_console.write = sunhv_console_write_paged;
0546 sunhv_ops = &bywrite_ops;
0547 }
0548
0549 sunhv_port = port;
0550
0551 port->has_sysrq = 1;
0552 port->line = 0;
0553 port->ops = &sunhv_pops;
0554 port->type = PORT_SUNHV;
0555 port->uartclk = ( 29491200 / 16 );
0556
0557 port->membase = (unsigned char __iomem *) __pa(port);
0558
0559 port->irq = op->archdata.irqs[0];
0560
0561 port->dev = &op->dev;
0562
0563 err = sunserial_register_minors(&sunhv_reg, 1);
0564 if (err)
0565 goto out_free_con_read_page;
0566
0567 sunserial_console_match(&sunhv_console, op->dev.of_node,
0568 &sunhv_reg, port->line, false);
0569
0570 err = uart_add_one_port(&sunhv_reg, port);
0571 if (err)
0572 goto out_unregister_driver;
0573
0574 err = request_irq(port->irq, sunhv_interrupt, 0, "hvcons", port);
0575 if (err)
0576 goto out_remove_port;
0577
0578 platform_set_drvdata(op, port);
0579
0580 return 0;
0581
0582 out_remove_port:
0583 uart_remove_one_port(&sunhv_reg, port);
0584
0585 out_unregister_driver:
0586 sunserial_unregister_minors(&sunhv_reg, 1);
0587
0588 out_free_con_read_page:
0589 kfree(con_read_page);
0590
0591 out_free_con_write_page:
0592 kfree(con_write_page);
0593
0594 out_free_port:
0595 kfree(port);
0596 sunhv_port = NULL;
0597 return err;
0598 }
0599
0600 static int hv_remove(struct platform_device *dev)
0601 {
0602 struct uart_port *port = platform_get_drvdata(dev);
0603
0604 free_irq(port->irq, port);
0605
0606 uart_remove_one_port(&sunhv_reg, port);
0607
0608 sunserial_unregister_minors(&sunhv_reg, 1);
0609 kfree(con_read_page);
0610 kfree(con_write_page);
0611 kfree(port);
0612 sunhv_port = NULL;
0613
0614 return 0;
0615 }
0616
0617 static const struct of_device_id hv_match[] = {
0618 {
0619 .name = "console",
0620 .compatible = "qcn",
0621 },
0622 {
0623 .name = "console",
0624 .compatible = "SUNW,sun4v-console",
0625 },
0626 {},
0627 };
0628
0629 static struct platform_driver hv_driver = {
0630 .driver = {
0631 .name = "hv",
0632 .of_match_table = hv_match,
0633 },
0634 .probe = hv_probe,
0635 .remove = hv_remove,
0636 };
0637
0638 static int __init sunhv_init(void)
0639 {
0640 if (tlb_type != hypervisor)
0641 return -ENODEV;
0642
0643 return platform_driver_register(&hv_driver);
0644 }
0645 device_initcall(sunhv_init);
0646
0647 #if 0
0648 MODULE_AUTHOR("David S. Miller");
0649 MODULE_DESCRIPTION("SUN4V Hypervisor console driver");
0650 MODULE_VERSION("2.0");
0651 MODULE_LICENSE("GPL");
0652 #endif