1 /* sunhv.c: Serial driver for SUN4V hypervisor console.
3 * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/errno.h>
10 #include <linux/tty_flip.h>
11 #include <linux/major.h>
12 #include <linux/circ_buf.h>
13 #include <linux/serial.h>
14 #include <linux/sysrq.h>
15 #include <linux/console.h>
16 #include <linux/spinlock.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/init.h>
20 #include <linux/of_device.h>
22 #include <asm/hypervisor.h>
23 #include <asm/spitfire.h>
26 #include <asm/setup.h>
28 #if defined(CONFIG_MAGIC_SYSRQ)
32 #include <linux/serial_core.h>
33 #include <linux/sunserialcore.h>
35 #define CON_BREAK ((long)-1)
36 #define CON_HUP ((long)-2)
38 #define IGNORE_BREAK 0x1
39 #define IGNORE_ALL 0x2
41 static char *con_write_page
;
42 static char *con_read_page
;
44 static int hung_up
= 0;
46 static void transmit_chars_putchar(struct uart_port
*port
, struct circ_buf
*xmit
)
48 while (!uart_circ_empty(xmit
)) {
49 long status
= sun4v_con_putchar(xmit
->buf
[xmit
->tail
]);
54 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
- 1);
59 static void transmit_chars_write(struct uart_port
*port
, struct circ_buf
*xmit
)
61 while (!uart_circ_empty(xmit
)) {
62 unsigned long ra
= __pa(xmit
->buf
+ xmit
->tail
);
63 unsigned long len
, status
, sent
;
65 len
= CIRC_CNT_TO_END(xmit
->head
, xmit
->tail
,
67 status
= sun4v_con_write(ra
, len
, &sent
);
70 xmit
->tail
= (xmit
->tail
+ sent
) & (UART_XMIT_SIZE
- 1);
71 port
->icount
.tx
+= sent
;
75 static int receive_chars_getchar(struct uart_port
*port
, struct tty_struct
*tty
)
77 int saw_console_brk
= 0;
82 long c
= sun4v_con_getchar(&status
);
84 if (status
== HV_EWOULDBLOCK
)
88 if (uart_handle_break(port
))
96 uart_handle_dcd_change(port
, 0);
99 uart_handle_dcd_change(port
, 1);
103 uart_handle_sysrq_char(port
, c
);
109 if (uart_handle_sysrq_char(port
, c
))
112 tty_insert_flip_char(tty
, c
, TTY_NORMAL
);
115 return saw_console_brk
;
118 static int receive_chars_read(struct uart_port
*port
, struct tty_struct
*tty
)
120 int saw_console_brk
= 0;
123 while (limit
-- > 0) {
124 unsigned long ra
= __pa(con_read_page
);
125 unsigned long bytes_read
, i
;
126 long stat
= sun4v_con_read(ra
, PAGE_SIZE
, &bytes_read
);
128 if (stat
!= HV_EOK
) {
131 if (stat
== CON_BREAK
) {
132 if (uart_handle_break(port
))
137 } else if (stat
== CON_HUP
) {
139 uart_handle_dcd_change(port
, 0);
142 /* HV_EWOULDBLOCK, etc. */
149 uart_handle_dcd_change(port
, 1);
152 for (i
= 0; i
< bytes_read
; i
++)
153 uart_handle_sysrq_char(port
, con_read_page
[i
]);
158 port
->icount
.rx
+= bytes_read
;
160 tty_insert_flip_string(tty
, con_read_page
, bytes_read
);
163 return saw_console_brk
;
167 void (*transmit_chars
)(struct uart_port
*port
, struct circ_buf
*xmit
);
168 int (*receive_chars
)(struct uart_port
*port
, struct tty_struct
*tty
);
171 static struct sunhv_ops bychar_ops
= {
172 .transmit_chars
= transmit_chars_putchar
,
173 .receive_chars
= receive_chars_getchar
,
176 static struct sunhv_ops bywrite_ops
= {
177 .transmit_chars
= transmit_chars_write
,
178 .receive_chars
= receive_chars_read
,
181 static struct sunhv_ops
*sunhv_ops
= &bychar_ops
;
183 static struct tty_struct
*receive_chars(struct uart_port
*port
)
185 struct tty_struct
*tty
= NULL
;
187 if (port
->state
!= NULL
) /* Unopened serial console */
188 tty
= port
->state
->port
.tty
;
190 if (sunhv_ops
->receive_chars(port
, tty
))
196 static void transmit_chars(struct uart_port
*port
)
198 struct circ_buf
*xmit
;
203 xmit
= &port
->state
->xmit
;
204 if (uart_circ_empty(xmit
) || uart_tx_stopped(port
))
207 sunhv_ops
->transmit_chars(port
, xmit
);
209 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
210 uart_write_wakeup(port
);
213 static irqreturn_t
sunhv_interrupt(int irq
, void *dev_id
)
215 struct uart_port
*port
= dev_id
;
216 struct tty_struct
*tty
;
219 spin_lock_irqsave(&port
->lock
, flags
);
220 tty
= receive_chars(port
);
221 transmit_chars(port
);
222 spin_unlock_irqrestore(&port
->lock
, flags
);
225 tty_flip_buffer_push(tty
);
230 /* port->lock is not held. */
231 static unsigned int sunhv_tx_empty(struct uart_port
*port
)
233 /* Transmitter is always empty for us. If the circ buffer
234 * is non-empty or there is an x_char pending, our caller
235 * will do the right thing and ignore what we return here.
240 /* port->lock held by caller. */
241 static void sunhv_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
246 /* port->lock is held by caller and interrupts are disabled. */
247 static unsigned int sunhv_get_mctrl(struct uart_port
*port
)
249 return TIOCM_DSR
| TIOCM_CAR
| TIOCM_CTS
;
252 /* port->lock held by caller. */
253 static void sunhv_stop_tx(struct uart_port
*port
)
258 /* port->lock held by caller. */
259 static void sunhv_start_tx(struct uart_port
*port
)
261 transmit_chars(port
);
264 /* port->lock is not held. */
265 static void sunhv_send_xchar(struct uart_port
*port
, char ch
)
270 spin_lock_irqsave(&port
->lock
, flags
);
272 while (limit
-- > 0) {
273 long status
= sun4v_con_putchar(ch
);
274 if (status
== HV_EOK
)
279 spin_unlock_irqrestore(&port
->lock
, flags
);
282 /* port->lock held by caller. */
283 static void sunhv_stop_rx(struct uart_port
*port
)
287 /* port->lock held by caller. */
288 static void sunhv_enable_ms(struct uart_port
*port
)
292 /* port->lock is not held. */
293 static void sunhv_break_ctl(struct uart_port
*port
, int break_state
)
299 spin_lock_irqsave(&port
->lock
, flags
);
301 while (limit
-- > 0) {
302 long status
= sun4v_con_putchar(CON_BREAK
);
303 if (status
== HV_EOK
)
308 spin_unlock_irqrestore(&port
->lock
, flags
);
312 /* port->lock is not held. */
313 static int sunhv_startup(struct uart_port
*port
)
318 /* port->lock is not held. */
319 static void sunhv_shutdown(struct uart_port
*port
)
323 /* port->lock is not held. */
324 static void sunhv_set_termios(struct uart_port
*port
, struct ktermios
*termios
,
325 struct ktermios
*old
)
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
;
332 spin_lock_irqsave(&port
->lock
, flags
);
334 iflag
= termios
->c_iflag
;
335 cflag
= termios
->c_cflag
;
337 port
->ignore_status_mask
= 0;
339 port
->ignore_status_mask
|= IGNORE_BREAK
;
340 if ((cflag
& CREAD
) == 0)
341 port
->ignore_status_mask
|= IGNORE_ALL
;
344 uart_update_timeout(port
, cflag
,
345 (port
->uartclk
/ (16 * quot
)));
347 spin_unlock_irqrestore(&port
->lock
, flags
);
350 static const char *sunhv_type(struct uart_port
*port
)
352 return "SUN4V HCONS";
355 static void sunhv_release_port(struct uart_port
*port
)
359 static int sunhv_request_port(struct uart_port
*port
)
364 static void sunhv_config_port(struct uart_port
*port
, int flags
)
368 static int sunhv_verify_port(struct uart_port
*port
, struct serial_struct
*ser
)
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 .enable_ms
= sunhv_enable_ms
,
382 .break_ctl
= sunhv_break_ctl
,
383 .startup
= sunhv_startup
,
384 .shutdown
= sunhv_shutdown
,
385 .set_termios
= sunhv_set_termios
,
387 .release_port
= sunhv_release_port
,
388 .request_port
= sunhv_request_port
,
389 .config_port
= sunhv_config_port
,
390 .verify_port
= sunhv_verify_port
,
393 static struct uart_driver sunhv_reg
= {
394 .owner
= THIS_MODULE
,
395 .driver_name
= "sunhv",
400 static struct uart_port
*sunhv_port
;
402 /* Copy 's' into the con_write_page, decoding "\n" into
403 * "\r\n" along the way. We have to return two lengths
404 * because the caller needs to know how much to advance
405 * 's' and also how many bytes to output via con_write_page.
407 static int fill_con_write_page(const char *s
, unsigned int n
,
408 unsigned long *page_bytes
)
410 const char *orig_s
= s
;
411 char *p
= con_write_page
;
412 int left
= PAGE_SIZE
;
425 *page_bytes
= p
- con_write_page
;
429 static void sunhv_console_write_paged(struct console
*con
, const char *s
, unsigned n
)
431 struct uart_port
*port
= sunhv_port
;
435 local_irq_save(flags
);
438 } else if (oops_in_progress
) {
439 locked
= spin_trylock(&port
->lock
);
441 spin_lock(&port
->lock
);
444 unsigned long ra
= __pa(con_write_page
);
445 unsigned long page_bytes
;
446 unsigned int cpy
= fill_con_write_page(s
, n
,
451 while (page_bytes
> 0) {
452 unsigned long written
;
458 stat
= sun4v_con_write(ra
, page_bytes
,
466 page_bytes
-= written
;
472 spin_unlock(&port
->lock
);
473 local_irq_restore(flags
);
476 static inline void sunhv_console_putchar(struct uart_port
*port
, char c
)
480 while (limit
-- > 0) {
481 long status
= sun4v_con_putchar(c
);
482 if (status
== HV_EOK
)
488 static void sunhv_console_write_bychar(struct console
*con
, const char *s
, unsigned n
)
490 struct uart_port
*port
= sunhv_port
;
494 local_irq_save(flags
);
497 } else if (oops_in_progress
) {
498 locked
= spin_trylock(&port
->lock
);
500 spin_lock(&port
->lock
);
502 for (i
= 0; i
< n
; i
++) {
504 sunhv_console_putchar(port
, '\r');
505 sunhv_console_putchar(port
, *s
++);
509 spin_unlock(&port
->lock
);
510 local_irq_restore(flags
);
513 static struct console sunhv_console
= {
515 .write
= sunhv_console_write_bychar
,
516 .device
= uart_console_device
,
517 .flags
= CON_PRINTBUFFER
,
522 static int __devinit
hv_probe(struct platform_device
*op
)
524 struct uart_port
*port
;
528 if (op
->archdata
.irqs
[0] == 0xffffffff)
531 port
= kzalloc(sizeof(struct uart_port
), GFP_KERNEL
);
536 if (sun4v_hvapi_register(HV_GRP_CORE
, 1, &minor
) == 0 &&
539 con_write_page
= kzalloc(PAGE_SIZE
, GFP_KERNEL
);
543 con_read_page
= kzalloc(PAGE_SIZE
, GFP_KERNEL
);
545 goto out_free_con_write_page
;
547 sunhv_console
.write
= sunhv_console_write_paged
;
548 sunhv_ops
= &bywrite_ops
;
554 port
->ops
= &sunhv_pops
;
555 port
->type
= PORT_SUNHV
;
556 port
->uartclk
= ( 29491200 / 16 ); /* arbitrary */
558 port
->membase
= (unsigned char __iomem
*) __pa(port
);
560 port
->irq
= op
->archdata
.irqs
[0];
562 port
->dev
= &op
->dev
;
564 err
= sunserial_register_minors(&sunhv_reg
, 1);
566 goto out_free_con_read_page
;
568 sunserial_console_match(&sunhv_console
, op
->dev
.of_node
,
569 &sunhv_reg
, port
->line
, false);
571 err
= uart_add_one_port(&sunhv_reg
, port
);
573 goto out_unregister_driver
;
575 err
= request_irq(port
->irq
, sunhv_interrupt
, 0, "hvcons", port
);
577 goto out_remove_port
;
579 dev_set_drvdata(&op
->dev
, port
);
584 uart_remove_one_port(&sunhv_reg
, port
);
586 out_unregister_driver
:
587 sunserial_unregister_minors(&sunhv_reg
, 1);
589 out_free_con_read_page
:
590 kfree(con_read_page
);
592 out_free_con_write_page
:
593 kfree(con_write_page
);
601 static int __devexit
hv_remove(struct platform_device
*dev
)
603 struct uart_port
*port
= dev_get_drvdata(&dev
->dev
);
605 free_irq(port
->irq
, port
);
607 uart_remove_one_port(&sunhv_reg
, port
);
609 sunserial_unregister_minors(&sunhv_reg
, 1);
614 dev_set_drvdata(&dev
->dev
, NULL
);
619 static const struct of_device_id hv_match
[] = {
626 .compatible
= "SUNW,sun4v-console",
630 MODULE_DEVICE_TABLE(of
, hv_match
);
632 static struct platform_driver hv_driver
= {
635 .owner
= THIS_MODULE
,
636 .of_match_table
= hv_match
,
639 .remove
= __devexit_p(hv_remove
),
642 static int __init
sunhv_init(void)
644 if (tlb_type
!= hypervisor
)
647 return platform_driver_register(&hv_driver
);
650 static void __exit
sunhv_exit(void)
652 platform_driver_unregister(&hv_driver
);
655 module_init(sunhv_init
);
656 module_exit(sunhv_exit
);
658 MODULE_AUTHOR("David S. Miller");
659 MODULE_DESCRIPTION("SUN4V Hypervisor console driver");
660 MODULE_VERSION("2.0");
661 MODULE_LICENSE("GPL");