xref: /openbmc/linux/drivers/tty/serial/sunhv.c (revision 82003e04)
1 /* sunhv.c: Serial driver for SUN4V hypervisor console.
2  *
3  * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/errno.h>
8 #include <linux/tty.h>
9 #include <linux/tty_flip.h>
10 #include <linux/major.h>
11 #include <linux/circ_buf.h>
12 #include <linux/serial.h>
13 #include <linux/sysrq.h>
14 #include <linux/console.h>
15 #include <linux/spinlock.h>
16 #include <linux/slab.h>
17 #include <linux/delay.h>
18 #include <linux/init.h>
19 #include <linux/of_device.h>
20 
21 #include <asm/hypervisor.h>
22 #include <asm/spitfire.h>
23 #include <asm/prom.h>
24 #include <asm/irq.h>
25 #include <asm/setup.h>
26 
27 #if defined(CONFIG_MAGIC_SYSRQ)
28 #define SUPPORT_SYSRQ
29 #endif
30 
31 #include <linux/serial_core.h>
32 #include <linux/sunserialcore.h>
33 
34 #define CON_BREAK	((long)-1)
35 #define CON_HUP		((long)-2)
36 
37 #define IGNORE_BREAK	0x1
38 #define IGNORE_ALL	0x2
39 
40 static char *con_write_page;
41 static char *con_read_page;
42 
43 static int hung_up = 0;
44 
45 static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit)
46 {
47 	while (!uart_circ_empty(xmit)) {
48 		long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
49 
50 		if (status != HV_EOK)
51 			break;
52 
53 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
54 		port->icount.tx++;
55 	}
56 }
57 
58 static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit)
59 {
60 	while (!uart_circ_empty(xmit)) {
61 		unsigned long ra = __pa(xmit->buf + xmit->tail);
62 		unsigned long len, status, sent;
63 
64 		len = CIRC_CNT_TO_END(xmit->head, xmit->tail,
65 				      UART_XMIT_SIZE);
66 		status = sun4v_con_write(ra, len, &sent);
67 		if (status != HV_EOK)
68 			break;
69 		xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1);
70 		port->icount.tx += sent;
71 	}
72 }
73 
74 static int receive_chars_getchar(struct uart_port *port)
75 {
76 	int saw_console_brk = 0;
77 	int limit = 10000;
78 
79 	while (limit-- > 0) {
80 		long status;
81 		long c = sun4v_con_getchar(&status);
82 
83 		if (status == HV_EWOULDBLOCK)
84 			break;
85 
86 		if (c == CON_BREAK) {
87 			if (uart_handle_break(port))
88 				continue;
89 			saw_console_brk = 1;
90 			c = 0;
91 		}
92 
93 		if (c == CON_HUP) {
94 			hung_up = 1;
95 			uart_handle_dcd_change(port, 0);
96 		} else if (hung_up) {
97 			hung_up = 0;
98 			uart_handle_dcd_change(port, 1);
99 		}
100 
101 		if (port->state == NULL) {
102 			uart_handle_sysrq_char(port, c);
103 			continue;
104 		}
105 
106 		port->icount.rx++;
107 
108 		if (uart_handle_sysrq_char(port, c))
109 			continue;
110 
111 		tty_insert_flip_char(&port->state->port, c, TTY_NORMAL);
112 	}
113 
114 	return saw_console_brk;
115 }
116 
117 static int receive_chars_read(struct uart_port *port)
118 {
119 	int saw_console_brk = 0;
120 	int limit = 10000;
121 
122 	while (limit-- > 0) {
123 		unsigned long ra = __pa(con_read_page);
124 		unsigned long bytes_read, i;
125 		long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read);
126 
127 		if (stat != HV_EOK) {
128 			bytes_read = 0;
129 
130 			if (stat == CON_BREAK) {
131 				if (uart_handle_break(port))
132 					continue;
133 				saw_console_brk = 1;
134 				*con_read_page = 0;
135 				bytes_read = 1;
136 			} else if (stat == CON_HUP) {
137 				hung_up = 1;
138 				uart_handle_dcd_change(port, 0);
139 				continue;
140 			} else {
141 				/* HV_EWOULDBLOCK, etc.  */
142 				break;
143 			}
144 		}
145 
146 		if (hung_up) {
147 			hung_up = 0;
148 			uart_handle_dcd_change(port, 1);
149 		}
150 
151 		if (port->sysrq != 0 &&  *con_read_page) {
152 			for (i = 0; i < bytes_read; i++)
153 				uart_handle_sysrq_char(port, con_read_page[i]);
154 		}
155 
156 		if (port->state == NULL)
157 			continue;
158 
159 		port->icount.rx += bytes_read;
160 
161 		tty_insert_flip_string(&port->state->port, con_read_page,
162 				bytes_read);
163 	}
164 
165 	return saw_console_brk;
166 }
167 
168 struct sunhv_ops {
169 	void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit);
170 	int (*receive_chars)(struct uart_port *port);
171 };
172 
173 static const struct sunhv_ops bychar_ops = {
174 	.transmit_chars = transmit_chars_putchar,
175 	.receive_chars = receive_chars_getchar,
176 };
177 
178 static const struct sunhv_ops bywrite_ops = {
179 	.transmit_chars = transmit_chars_write,
180 	.receive_chars = receive_chars_read,
181 };
182 
183 static const struct sunhv_ops *sunhv_ops = &bychar_ops;
184 
185 static struct tty_port *receive_chars(struct uart_port *port)
186 {
187 	struct tty_port *tport = NULL;
188 
189 	if (port->state != NULL)		/* Unopened serial console */
190 		tport = &port->state->port;
191 
192 	if (sunhv_ops->receive_chars(port))
193 		sun_do_break();
194 
195 	return tport;
196 }
197 
198 static void transmit_chars(struct uart_port *port)
199 {
200 	struct circ_buf *xmit;
201 
202 	if (!port->state)
203 		return;
204 
205 	xmit = &port->state->xmit;
206 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
207 		return;
208 
209 	sunhv_ops->transmit_chars(port, xmit);
210 
211 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
212 		uart_write_wakeup(port);
213 }
214 
215 static irqreturn_t sunhv_interrupt(int irq, void *dev_id)
216 {
217 	struct uart_port *port = dev_id;
218 	struct tty_port *tport;
219 	unsigned long flags;
220 
221 	spin_lock_irqsave(&port->lock, flags);
222 	tport = receive_chars(port);
223 	transmit_chars(port);
224 	spin_unlock_irqrestore(&port->lock, flags);
225 
226 	if (tport)
227 		tty_flip_buffer_push(tport);
228 
229 	return IRQ_HANDLED;
230 }
231 
232 /* port->lock is not held.  */
233 static unsigned int sunhv_tx_empty(struct uart_port *port)
234 {
235 	/* Transmitter is always empty for us.  If the circ buffer
236 	 * is non-empty or there is an x_char pending, our caller
237 	 * will do the right thing and ignore what we return here.
238 	 */
239 	return TIOCSER_TEMT;
240 }
241 
242 /* port->lock held by caller.  */
243 static void sunhv_set_mctrl(struct uart_port *port, unsigned int mctrl)
244 {
245 	return;
246 }
247 
248 /* port->lock is held by caller and interrupts are disabled.  */
249 static unsigned int sunhv_get_mctrl(struct uart_port *port)
250 {
251 	return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS;
252 }
253 
254 /* port->lock held by caller.  */
255 static void sunhv_stop_tx(struct uart_port *port)
256 {
257 	return;
258 }
259 
260 /* port->lock held by caller.  */
261 static void sunhv_start_tx(struct uart_port *port)
262 {
263 	transmit_chars(port);
264 }
265 
266 /* port->lock is not held.  */
267 static void sunhv_send_xchar(struct uart_port *port, char ch)
268 {
269 	unsigned long flags;
270 	int limit = 10000;
271 
272 	if (ch == __DISABLED_CHAR)
273 		return;
274 
275 	spin_lock_irqsave(&port->lock, flags);
276 
277 	while (limit-- > 0) {
278 		long status = sun4v_con_putchar(ch);
279 		if (status == HV_EOK)
280 			break;
281 		udelay(1);
282 	}
283 
284 	spin_unlock_irqrestore(&port->lock, flags);
285 }
286 
287 /* port->lock held by caller.  */
288 static void sunhv_stop_rx(struct uart_port *port)
289 {
290 }
291 
292 /* port->lock is not held.  */
293 static void sunhv_break_ctl(struct uart_port *port, int break_state)
294 {
295 	if (break_state) {
296 		unsigned long flags;
297 		int limit = 10000;
298 
299 		spin_lock_irqsave(&port->lock, flags);
300 
301 		while (limit-- > 0) {
302 			long status = sun4v_con_putchar(CON_BREAK);
303 			if (status == HV_EOK)
304 				break;
305 			udelay(1);
306 		}
307 
308 		spin_unlock_irqrestore(&port->lock, flags);
309 	}
310 }
311 
312 /* port->lock is not held.  */
313 static int sunhv_startup(struct uart_port *port)
314 {
315 	return 0;
316 }
317 
318 /* port->lock is not held.  */
319 static void sunhv_shutdown(struct uart_port *port)
320 {
321 }
322 
323 /* port->lock is not held.  */
324 static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios,
325 			      struct ktermios *old)
326 {
327 	unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
328 	unsigned int quot = uart_get_divisor(port, baud);
329 	unsigned int iflag, cflag;
330 	unsigned long flags;
331 
332 	spin_lock_irqsave(&port->lock, flags);
333 
334 	iflag = termios->c_iflag;
335 	cflag = termios->c_cflag;
336 
337 	port->ignore_status_mask = 0;
338 	if (iflag & IGNBRK)
339 		port->ignore_status_mask |= IGNORE_BREAK;
340 	if ((cflag & CREAD) == 0)
341 		port->ignore_status_mask |= IGNORE_ALL;
342 
343 	/* XXX */
344 	uart_update_timeout(port, cflag,
345 			    (port->uartclk / (16 * quot)));
346 
347 	spin_unlock_irqrestore(&port->lock, flags);
348 }
349 
350 static const char *sunhv_type(struct uart_port *port)
351 {
352 	return "SUN4V HCONS";
353 }
354 
355 static void sunhv_release_port(struct uart_port *port)
356 {
357 }
358 
359 static int sunhv_request_port(struct uart_port *port)
360 {
361 	return 0;
362 }
363 
364 static void sunhv_config_port(struct uart_port *port, int flags)
365 {
366 }
367 
368 static int sunhv_verify_port(struct uart_port *port, struct serial_struct *ser)
369 {
370 	return -EINVAL;
371 }
372 
373 static struct uart_ops sunhv_pops = {
374 	.tx_empty	= sunhv_tx_empty,
375 	.set_mctrl	= sunhv_set_mctrl,
376 	.get_mctrl	= sunhv_get_mctrl,
377 	.stop_tx	= sunhv_stop_tx,
378 	.start_tx	= sunhv_start_tx,
379 	.send_xchar	= sunhv_send_xchar,
380 	.stop_rx	= sunhv_stop_rx,
381 	.break_ctl	= sunhv_break_ctl,
382 	.startup	= sunhv_startup,
383 	.shutdown	= sunhv_shutdown,
384 	.set_termios	= sunhv_set_termios,
385 	.type		= sunhv_type,
386 	.release_port	= sunhv_release_port,
387 	.request_port	= sunhv_request_port,
388 	.config_port	= sunhv_config_port,
389 	.verify_port	= sunhv_verify_port,
390 };
391 
392 static struct uart_driver sunhv_reg = {
393 	.owner			= THIS_MODULE,
394 	.driver_name		= "sunhv",
395 	.dev_name		= "ttyS",
396 	.major			= TTY_MAJOR,
397 };
398 
399 static struct uart_port *sunhv_port;
400 
401 /* Copy 's' into the con_write_page, decoding "\n" into
402  * "\r\n" along the way.  We have to return two lengths
403  * because the caller needs to know how much to advance
404  * 's' and also how many bytes to output via con_write_page.
405  */
406 static int fill_con_write_page(const char *s, unsigned int n,
407 			       unsigned long *page_bytes)
408 {
409 	const char *orig_s = s;
410 	char *p = con_write_page;
411 	int left = PAGE_SIZE;
412 
413 	while (n--) {
414 		if (*s == '\n') {
415 			if (left < 2)
416 				break;
417 			*p++ = '\r';
418 			left--;
419 		} else if (left < 1)
420 			break;
421 		*p++ = *s++;
422 		left--;
423 	}
424 	*page_bytes = p - con_write_page;
425 	return s - orig_s;
426 }
427 
428 static void sunhv_console_write_paged(struct console *con, const char *s, unsigned n)
429 {
430 	struct uart_port *port = sunhv_port;
431 	unsigned long flags;
432 	int locked = 1;
433 
434 	if (port->sysrq || oops_in_progress)
435 		locked = spin_trylock_irqsave(&port->lock, flags);
436 	else
437 		spin_lock_irqsave(&port->lock, flags);
438 
439 	while (n > 0) {
440 		unsigned long ra = __pa(con_write_page);
441 		unsigned long page_bytes;
442 		unsigned int cpy = fill_con_write_page(s, n,
443 						       &page_bytes);
444 
445 		n -= cpy;
446 		s += cpy;
447 		while (page_bytes > 0) {
448 			unsigned long written;
449 			int limit = 1000000;
450 
451 			while (limit--) {
452 				unsigned long stat;
453 
454 				stat = sun4v_con_write(ra, page_bytes,
455 						       &written);
456 				if (stat == HV_EOK)
457 					break;
458 				udelay(1);
459 			}
460 			if (limit < 0)
461 				break;
462 			page_bytes -= written;
463 			ra += written;
464 		}
465 	}
466 
467 	if (locked)
468 		spin_unlock_irqrestore(&port->lock, flags);
469 }
470 
471 static inline void sunhv_console_putchar(struct uart_port *port, char c)
472 {
473 	int limit = 1000000;
474 
475 	while (limit-- > 0) {
476 		long status = sun4v_con_putchar(c);
477 		if (status == HV_EOK)
478 			break;
479 		udelay(1);
480 	}
481 }
482 
483 static void sunhv_console_write_bychar(struct console *con, const char *s, unsigned n)
484 {
485 	struct uart_port *port = sunhv_port;
486 	unsigned long flags;
487 	int i, locked = 1;
488 
489 	if (port->sysrq || oops_in_progress)
490 		locked = spin_trylock_irqsave(&port->lock, flags);
491 	else
492 		spin_lock_irqsave(&port->lock, flags);
493 
494 	for (i = 0; i < n; i++) {
495 		if (*s == '\n')
496 			sunhv_console_putchar(port, '\r');
497 		sunhv_console_putchar(port, *s++);
498 	}
499 
500 	if (locked)
501 		spin_unlock_irqrestore(&port->lock, flags);
502 }
503 
504 static struct console sunhv_console = {
505 	.name	=	"ttyHV",
506 	.write	=	sunhv_console_write_bychar,
507 	.device	=	uart_console_device,
508 	.flags	=	CON_PRINTBUFFER,
509 	.index	=	-1,
510 	.data	=	&sunhv_reg,
511 };
512 
513 static int hv_probe(struct platform_device *op)
514 {
515 	struct uart_port *port;
516 	unsigned long minor;
517 	int err;
518 
519 	if (op->archdata.irqs[0] == 0xffffffff)
520 		return -ENODEV;
521 
522 	port = kzalloc(sizeof(struct uart_port), GFP_KERNEL);
523 	if (unlikely(!port))
524 		return -ENOMEM;
525 
526 	minor = 1;
527 	if (sun4v_hvapi_register(HV_GRP_CORE, 1, &minor) == 0 &&
528 	    minor >= 1) {
529 		err = -ENOMEM;
530 		con_write_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
531 		if (!con_write_page)
532 			goto out_free_port;
533 
534 		con_read_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
535 		if (!con_read_page)
536 			goto out_free_con_write_page;
537 
538 		sunhv_console.write = sunhv_console_write_paged;
539 		sunhv_ops = &bywrite_ops;
540 	}
541 
542 	sunhv_port = port;
543 
544 	port->line = 0;
545 	port->ops = &sunhv_pops;
546 	port->type = PORT_SUNHV;
547 	port->uartclk = ( 29491200 / 16 ); /* arbitrary */
548 
549 	port->membase = (unsigned char __iomem *) __pa(port);
550 
551 	port->irq = op->archdata.irqs[0];
552 
553 	port->dev = &op->dev;
554 
555 	err = sunserial_register_minors(&sunhv_reg, 1);
556 	if (err)
557 		goto out_free_con_read_page;
558 
559 	sunserial_console_match(&sunhv_console, op->dev.of_node,
560 				&sunhv_reg, port->line, false);
561 
562 	err = uart_add_one_port(&sunhv_reg, port);
563 	if (err)
564 		goto out_unregister_driver;
565 
566 	err = request_irq(port->irq, sunhv_interrupt, 0, "hvcons", port);
567 	if (err)
568 		goto out_remove_port;
569 
570 	platform_set_drvdata(op, port);
571 
572 	return 0;
573 
574 out_remove_port:
575 	uart_remove_one_port(&sunhv_reg, port);
576 
577 out_unregister_driver:
578 	sunserial_unregister_minors(&sunhv_reg, 1);
579 
580 out_free_con_read_page:
581 	kfree(con_read_page);
582 
583 out_free_con_write_page:
584 	kfree(con_write_page);
585 
586 out_free_port:
587 	kfree(port);
588 	sunhv_port = NULL;
589 	return err;
590 }
591 
592 static int hv_remove(struct platform_device *dev)
593 {
594 	struct uart_port *port = platform_get_drvdata(dev);
595 
596 	free_irq(port->irq, port);
597 
598 	uart_remove_one_port(&sunhv_reg, port);
599 
600 	sunserial_unregister_minors(&sunhv_reg, 1);
601 
602 	kfree(port);
603 	sunhv_port = NULL;
604 
605 	return 0;
606 }
607 
608 static const struct of_device_id hv_match[] = {
609 	{
610 		.name = "console",
611 		.compatible = "qcn",
612 	},
613 	{
614 		.name = "console",
615 		.compatible = "SUNW,sun4v-console",
616 	},
617 	{},
618 };
619 
620 static struct platform_driver hv_driver = {
621 	.driver = {
622 		.name = "hv",
623 		.of_match_table = hv_match,
624 	},
625 	.probe		= hv_probe,
626 	.remove		= hv_remove,
627 };
628 
629 static int __init sunhv_init(void)
630 {
631 	if (tlb_type != hypervisor)
632 		return -ENODEV;
633 
634 	return platform_driver_register(&hv_driver);
635 }
636 device_initcall(sunhv_init);
637 
638 #if 0 /* ...def MODULE ; never supported as such */
639 MODULE_AUTHOR("David S. Miller");
640 MODULE_DESCRIPTION("SUN4V Hypervisor console driver");
641 MODULE_VERSION("2.0");
642 MODULE_LICENSE("GPL");
643 #endif
644