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