1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (C) 2012 Intel, Inc.
5 * Copyright (C) 2017 Imagination Technologies Ltd.
6 */
7
8 #include <linux/console.h>
9 #include <linux/interrupt.h>
10 #include <linux/platform_device.h>
11 #include <linux/tty.h>
12 #include <linux/tty_flip.h>
13 #include <linux/slab.h>
14 #include <linux/io.h>
15 #include <linux/module.h>
16 #include <linux/goldfish.h>
17 #include <linux/mm.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/serial_core.h>
20 #include <linux/wordpart.h>
21
22 /* Goldfish tty register's offsets */
23 #define GOLDFISH_TTY_REG_BYTES_READY 0x04
24 #define GOLDFISH_TTY_REG_CMD 0x08
25 #define GOLDFISH_TTY_REG_DATA_PTR 0x10
26 #define GOLDFISH_TTY_REG_DATA_LEN 0x14
27 #define GOLDFISH_TTY_REG_DATA_PTR_HIGH 0x18
28 #define GOLDFISH_TTY_REG_VERSION 0x20
29
30 /* Goldfish tty commands */
31 #define GOLDFISH_TTY_CMD_INT_DISABLE 0
32 #define GOLDFISH_TTY_CMD_INT_ENABLE 1
33 #define GOLDFISH_TTY_CMD_WRITE_BUFFER 2
34 #define GOLDFISH_TTY_CMD_READ_BUFFER 3
35
36 struct goldfish_tty {
37 struct tty_port port;
38 spinlock_t lock;
39 void __iomem *base;
40 u32 irq;
41 struct console console;
42 u32 version;
43 struct device *dev;
44 };
45
46 static DEFINE_MUTEX(goldfish_tty_lock);
47 static struct tty_driver *goldfish_tty_driver;
48 static u32 goldfish_tty_line_count = 8;
49 static u32 goldfish_tty_current_line_count;
50 static struct goldfish_tty *goldfish_ttys;
51
gf_write_addr(unsigned long addr,void __iomem * portl,void __iomem * porth)52 static inline void gf_write_addr(unsigned long addr, void __iomem *portl, void __iomem *porth)
53 {
54 gf_iowrite32(lower_32_bits(addr), portl);
55 #ifdef CONFIG_64BIT
56 gf_iowrite32(upper_32_bits(addr), porth);
57 #endif
58 }
59
do_rw_io(struct goldfish_tty * qtty,unsigned long address,size_t count,bool is_write)60 static void do_rw_io(struct goldfish_tty *qtty, unsigned long address,
61 size_t count, bool is_write)
62 {
63 void __iomem *base = qtty->base;
64
65 guard(spinlock_irqsave)(&qtty->lock);
66
67 gf_write_addr(address, base + GOLDFISH_TTY_REG_DATA_PTR,
68 base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
69 gf_iowrite32(count, base + GOLDFISH_TTY_REG_DATA_LEN);
70
71 if (is_write)
72 gf_iowrite32(GOLDFISH_TTY_CMD_WRITE_BUFFER,
73 base + GOLDFISH_TTY_REG_CMD);
74 else
75 gf_iowrite32(GOLDFISH_TTY_CMD_READ_BUFFER,
76 base + GOLDFISH_TTY_REG_CMD);
77 }
78
goldfish_tty_rw(struct goldfish_tty * qtty,unsigned long addr,size_t count,bool is_write)79 static void goldfish_tty_rw(struct goldfish_tty *qtty, unsigned long addr,
80 size_t count, bool is_write)
81 {
82 dma_addr_t dma_handle;
83 enum dma_data_direction dma_dir;
84
85 dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
86 if (qtty->version > 0) {
87 /*
88 * Goldfish TTY for Ranchu platform uses
89 * physical addresses and DMA for read/write operations
90 */
91 unsigned long addr_end = addr + count;
92
93 while (addr < addr_end) {
94 unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE;
95 unsigned long next =
96 pg_end < addr_end ? pg_end : addr_end;
97 unsigned long avail = next - addr;
98
99 /*
100 * Map the buffer's virtual address to the DMA address
101 * so the buffer can be accessed by the device.
102 */
103 dma_handle = dma_map_single(qtty->dev, (void *)addr,
104 avail, dma_dir);
105
106 if (dma_mapping_error(qtty->dev, dma_handle)) {
107 dev_err(qtty->dev, "tty: DMA mapping error.\n");
108 return;
109 }
110 do_rw_io(qtty, dma_handle, avail, is_write);
111
112 /*
113 * Unmap the previously mapped region after
114 * the completion of the read/write operation.
115 */
116 dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir);
117
118 addr += avail;
119 }
120 } else {
121 /*
122 * Old style Goldfish TTY used on the Goldfish platform
123 * uses virtual addresses.
124 */
125 do_rw_io(qtty, addr, count, is_write);
126 }
127 }
128
goldfish_tty_do_write(int line,const u8 * buf,size_t count)129 static void goldfish_tty_do_write(int line, const u8 *buf, size_t count)
130 {
131 struct goldfish_tty *qtty = &goldfish_ttys[line];
132
133 goldfish_tty_rw(qtty, (unsigned long)buf, count, true);
134 }
135
goldfish_tty_interrupt(int irq,void * dev_id)136 static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id)
137 {
138 struct goldfish_tty *qtty = dev_id;
139 void __iomem *base = qtty->base;
140 u8 *buf;
141 u32 count;
142
143 count = gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY);
144 if (count == 0)
145 return IRQ_NONE;
146
147 count = tty_prepare_flip_string(&qtty->port, &buf, count);
148
149 goldfish_tty_rw(qtty, (unsigned long)buf, count, false);
150
151 tty_flip_buffer_push(&qtty->port);
152 return IRQ_HANDLED;
153 }
154
goldfish_tty_activate(struct tty_port * port,struct tty_struct * tty)155 static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty)
156 {
157 struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
158 port);
159 gf_iowrite32(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
160 return 0;
161 }
162
goldfish_tty_shutdown(struct tty_port * port)163 static void goldfish_tty_shutdown(struct tty_port *port)
164 {
165 struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
166 port);
167 gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
168 }
169
goldfish_tty_open(struct tty_struct * tty,struct file * filp)170 static int goldfish_tty_open(struct tty_struct *tty, struct file *filp)
171 {
172 struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
173 return tty_port_open(&qtty->port, tty, filp);
174 }
175
goldfish_tty_close(struct tty_struct * tty,struct file * filp)176 static void goldfish_tty_close(struct tty_struct *tty, struct file *filp)
177 {
178 tty_port_close(tty->port, tty, filp);
179 }
180
goldfish_tty_hangup(struct tty_struct * tty)181 static void goldfish_tty_hangup(struct tty_struct *tty)
182 {
183 tty_port_hangup(tty->port);
184 }
185
goldfish_tty_write(struct tty_struct * tty,const u8 * buf,size_t count)186 static ssize_t goldfish_tty_write(struct tty_struct *tty, const u8 *buf,
187 size_t count)
188 {
189 goldfish_tty_do_write(tty->index, buf, count);
190 return count;
191 }
192
goldfish_tty_write_room(struct tty_struct * tty)193 static unsigned int goldfish_tty_write_room(struct tty_struct *tty)
194 {
195 return 0x10000;
196 }
197
goldfish_tty_chars_in_buffer(struct tty_struct * tty)198 static unsigned int goldfish_tty_chars_in_buffer(struct tty_struct *tty)
199 {
200 struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
201 void __iomem *base = qtty->base;
202 return gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY);
203 }
204
goldfish_tty_console_write(struct console * co,const char * b,unsigned count)205 static void goldfish_tty_console_write(struct console *co, const char *b,
206 unsigned count)
207 {
208 goldfish_tty_do_write(co->index, b, count);
209 }
210
goldfish_tty_console_device(struct console * c,int * index)211 static struct tty_driver *goldfish_tty_console_device(struct console *c,
212 int *index)
213 {
214 *index = c->index;
215 return goldfish_tty_driver;
216 }
217
goldfish_tty_console_setup(struct console * co,char * options)218 static int goldfish_tty_console_setup(struct console *co, char *options)
219 {
220 if ((unsigned)co->index >= goldfish_tty_line_count)
221 return -ENODEV;
222 if (!goldfish_ttys[co->index].base)
223 return -ENODEV;
224 return 0;
225 }
226
227 static const struct tty_port_operations goldfish_port_ops = {
228 .activate = goldfish_tty_activate,
229 .shutdown = goldfish_tty_shutdown
230 };
231
232 static const struct tty_operations goldfish_tty_ops = {
233 .open = goldfish_tty_open,
234 .close = goldfish_tty_close,
235 .hangup = goldfish_tty_hangup,
236 .write = goldfish_tty_write,
237 .write_room = goldfish_tty_write_room,
238 .chars_in_buffer = goldfish_tty_chars_in_buffer,
239 };
240
goldfish_tty_create_driver(void)241 static int goldfish_tty_create_driver(void)
242 {
243 int ret;
244 struct tty_driver *tty;
245
246 goldfish_ttys = kzalloc_objs(*goldfish_ttys, goldfish_tty_line_count);
247 if (goldfish_ttys == NULL) {
248 ret = -ENOMEM;
249 goto err_alloc_goldfish_ttys_failed;
250 }
251 tty = tty_alloc_driver(goldfish_tty_line_count,
252 TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
253 TTY_DRIVER_DYNAMIC_DEV);
254 if (IS_ERR(tty)) {
255 ret = PTR_ERR(tty);
256 goto err_tty_alloc_driver_failed;
257 }
258 tty->driver_name = "goldfish";
259 tty->name = "ttyGF";
260 tty->type = TTY_DRIVER_TYPE_SERIAL;
261 tty->subtype = SERIAL_TYPE_NORMAL;
262 tty->init_termios = tty_std_termios;
263 tty_set_operations(tty, &goldfish_tty_ops);
264 ret = tty_register_driver(tty);
265 if (ret)
266 goto err_tty_register_driver_failed;
267
268 goldfish_tty_driver = tty;
269 return 0;
270
271 err_tty_register_driver_failed:
272 tty_driver_kref_put(tty);
273 err_tty_alloc_driver_failed:
274 kfree(goldfish_ttys);
275 goldfish_ttys = NULL;
276 err_alloc_goldfish_ttys_failed:
277 return ret;
278 }
279
goldfish_tty_delete_driver(void)280 static void goldfish_tty_delete_driver(void)
281 {
282 tty_unregister_driver(goldfish_tty_driver);
283 tty_driver_kref_put(goldfish_tty_driver);
284 goldfish_tty_driver = NULL;
285 kfree(goldfish_ttys);
286 goldfish_ttys = NULL;
287 }
288
goldfish_tty_probe(struct platform_device * pdev)289 static int goldfish_tty_probe(struct platform_device *pdev)
290 {
291 struct goldfish_tty *qtty;
292 int ret = -ENODEV;
293 struct resource *r;
294 struct device *ttydev;
295 void __iomem *base;
296 int irq;
297 unsigned int line;
298
299 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
300 if (!r) {
301 pr_err("goldfish_tty: No MEM resource available!\n");
302 return -ENOMEM;
303 }
304
305 base = ioremap(r->start, 0x1000);
306 if (!base) {
307 pr_err("goldfish_tty: Unable to ioremap base!\n");
308 return -ENOMEM;
309 }
310
311 irq = platform_get_irq(pdev, 0);
312 if (irq < 0) {
313 ret = irq;
314 goto err_unmap;
315 }
316
317 mutex_lock(&goldfish_tty_lock);
318
319 if (pdev->id == PLATFORM_DEVID_NONE)
320 line = goldfish_tty_current_line_count;
321 else
322 line = pdev->id;
323
324 if (line >= goldfish_tty_line_count) {
325 pr_err("goldfish_tty: Reached maximum tty number of %d.\n",
326 goldfish_tty_current_line_count);
327 ret = -ENOMEM;
328 goto err_unlock;
329 }
330
331 if (goldfish_tty_current_line_count == 0) {
332 ret = goldfish_tty_create_driver();
333 if (ret)
334 goto err_unlock;
335 }
336 goldfish_tty_current_line_count++;
337
338 qtty = &goldfish_ttys[line];
339 spin_lock_init(&qtty->lock);
340 tty_port_init(&qtty->port);
341 qtty->port.ops = &goldfish_port_ops;
342 qtty->base = base;
343 qtty->irq = irq;
344 qtty->dev = &pdev->dev;
345
346 /*
347 * Goldfish TTY device used by the Goldfish emulator
348 * should identify itself with 0, forcing the driver
349 * to use virtual addresses. Goldfish TTY device
350 * on Ranchu emulator (qemu2) returns 1 here and
351 * driver will use physical addresses.
352 */
353 qtty->version = gf_ioread32(base + GOLDFISH_TTY_REG_VERSION);
354
355 /*
356 * Goldfish TTY device on Ranchu emulator (qemu2)
357 * will use DMA for read/write IO operations.
358 */
359 if (qtty->version > 0) {
360 /*
361 * Initialize dma_mask to 32-bits.
362 */
363 if (!pdev->dev.dma_mask)
364 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
365 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
366 if (ret) {
367 dev_err(&pdev->dev, "No suitable DMA available.\n");
368 goto err_dec_line_count;
369 }
370 }
371
372 gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
373
374 ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED,
375 "goldfish_tty", qtty);
376 if (ret) {
377 pr_err("goldfish_tty: No IRQ available!\n");
378 goto err_dec_line_count;
379 }
380
381 ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver,
382 line, &pdev->dev);
383 if (IS_ERR(ttydev)) {
384 ret = PTR_ERR(ttydev);
385 goto err_tty_register_device_failed;
386 }
387
388 strcpy(qtty->console.name, "ttyGF");
389 qtty->console.write = goldfish_tty_console_write;
390 qtty->console.device = goldfish_tty_console_device;
391 qtty->console.setup = goldfish_tty_console_setup;
392 qtty->console.flags = CON_PRINTBUFFER;
393 qtty->console.index = line;
394 register_console(&qtty->console);
395 platform_set_drvdata(pdev, qtty);
396
397 mutex_unlock(&goldfish_tty_lock);
398 return 0;
399
400 err_tty_register_device_failed:
401 free_irq(irq, qtty);
402 err_dec_line_count:
403 tty_port_destroy(&qtty->port);
404 goldfish_tty_current_line_count--;
405 if (goldfish_tty_current_line_count == 0)
406 goldfish_tty_delete_driver();
407 err_unlock:
408 mutex_unlock(&goldfish_tty_lock);
409 err_unmap:
410 iounmap(base);
411 return ret;
412 }
413
goldfish_tty_remove(struct platform_device * pdev)414 static void goldfish_tty_remove(struct platform_device *pdev)
415 {
416 struct goldfish_tty *qtty = platform_get_drvdata(pdev);
417
418 guard(mutex)(&goldfish_tty_lock);
419
420 unregister_console(&qtty->console);
421 tty_unregister_device(goldfish_tty_driver, qtty->console.index);
422 iounmap(qtty->base);
423 qtty->base = NULL;
424 free_irq(qtty->irq, qtty);
425 tty_port_destroy(&qtty->port);
426 goldfish_tty_current_line_count--;
427 if (goldfish_tty_current_line_count == 0)
428 goldfish_tty_delete_driver();
429 }
430
431 #ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
gf_early_console_putchar(struct uart_port * port,unsigned char ch)432 static void gf_early_console_putchar(struct uart_port *port, unsigned char ch)
433 {
434 gf_iowrite32(ch, port->membase);
435 }
436
gf_early_write(struct console * con,const char * s,unsigned int n)437 static void gf_early_write(struct console *con, const char *s, unsigned int n)
438 {
439 struct earlycon_device *dev = con->data;
440
441 uart_console_write(&dev->port, s, n, gf_early_console_putchar);
442 }
443
gf_earlycon_setup(struct earlycon_device * device,const char * opt)444 static int __init gf_earlycon_setup(struct earlycon_device *device,
445 const char *opt)
446 {
447 if (!device->port.membase)
448 return -ENODEV;
449
450 device->con->write = gf_early_write;
451 return 0;
452 }
453
454 OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup);
455 #endif
456
457 static const struct of_device_id goldfish_tty_of_match[] = {
458 { .compatible = "google,goldfish-tty", },
459 {},
460 };
461
462 MODULE_DEVICE_TABLE(of, goldfish_tty_of_match);
463
464 static struct platform_driver goldfish_tty_platform_driver = {
465 .probe = goldfish_tty_probe,
466 .remove = goldfish_tty_remove,
467 .driver = {
468 .name = "goldfish_tty",
469 .of_match_table = goldfish_tty_of_match,
470 }
471 };
472
473 module_platform_driver(goldfish_tty_platform_driver);
474
475 MODULE_DESCRIPTION("Goldfish TTY Driver");
476 MODULE_LICENSE("GPL v2");
477