1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (C) 2012 Intel, Inc.
5 * Copyright (C) 2017 Imagination Technologies Ltd.
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>
15 #include <linux/module.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/goldfish.h>
19 #include <linux/dma-mapping.h>
20 #include <linux/serial_core.h>
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
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
42 struct console console
;
47 static DEFINE_MUTEX(goldfish_tty_lock
);
48 static struct tty_driver
*goldfish_tty_driver
;
49 static u32 goldfish_tty_line_count
= 8;
50 static u32 goldfish_tty_current_line_count
;
51 static struct goldfish_tty
*goldfish_ttys
;
53 static void do_rw_io(struct goldfish_tty
*qtty
,
54 unsigned long address
,
58 unsigned long irq_flags
;
59 void __iomem
*base
= qtty
->base
;
61 spin_lock_irqsave(&qtty
->lock
, irq_flags
);
62 gf_write_ptr((void *)address
, base
+ GOLDFISH_TTY_REG_DATA_PTR
,
63 base
+ GOLDFISH_TTY_REG_DATA_PTR_HIGH
);
64 writel(count
, base
+ GOLDFISH_TTY_REG_DATA_LEN
);
67 writel(GOLDFISH_TTY_CMD_WRITE_BUFFER
,
68 base
+ GOLDFISH_TTY_REG_CMD
);
70 writel(GOLDFISH_TTY_CMD_READ_BUFFER
,
71 base
+ GOLDFISH_TTY_REG_CMD
);
73 spin_unlock_irqrestore(&qtty
->lock
, irq_flags
);
76 static void goldfish_tty_rw(struct goldfish_tty
*qtty
,
81 dma_addr_t dma_handle
;
82 enum dma_data_direction dma_dir
;
84 dma_dir
= (is_write
? DMA_TO_DEVICE
: DMA_FROM_DEVICE
);
85 if (qtty
->version
> 0) {
87 * Goldfish TTY for Ranchu platform uses
88 * physical addresses and DMA for read/write operations
90 unsigned long addr_end
= addr
+ count
;
92 while (addr
< addr_end
) {
93 unsigned long pg_end
= (addr
& PAGE_MASK
) + PAGE_SIZE
;
95 pg_end
< addr_end
? pg_end
: addr_end
;
96 unsigned long avail
= next
- addr
;
99 * Map the buffer's virtual address to the DMA address
100 * so the buffer can be accessed by the device.
102 dma_handle
= dma_map_single(qtty
->dev
, (void *)addr
,
105 if (dma_mapping_error(qtty
->dev
, dma_handle
)) {
106 dev_err(qtty
->dev
, "tty: DMA mapping error.\n");
109 do_rw_io(qtty
, dma_handle
, avail
, is_write
);
112 * Unmap the previously mapped region after
113 * the completion of the read/write operation.
115 dma_unmap_single(qtty
->dev
, dma_handle
, avail
, dma_dir
);
121 * Old style Goldfish TTY used on the Goldfish platform
122 * uses virtual addresses.
124 do_rw_io(qtty
, addr
, count
, is_write
);
128 static void goldfish_tty_do_write(int line
, const char *buf
,
131 struct goldfish_tty
*qtty
= &goldfish_ttys
[line
];
132 unsigned long address
= (unsigned long)(void *)buf
;
134 goldfish_tty_rw(qtty
, address
, count
, 1);
137 static irqreturn_t
goldfish_tty_interrupt(int irq
, void *dev_id
)
139 struct goldfish_tty
*qtty
= dev_id
;
140 void __iomem
*base
= qtty
->base
;
141 unsigned long address
;
145 count
= readl(base
+ GOLDFISH_TTY_REG_BYTES_READY
);
149 count
= tty_prepare_flip_string(&qtty
->port
, &buf
, count
);
151 address
= (unsigned long)(void *)buf
;
152 goldfish_tty_rw(qtty
, address
, count
, 0);
154 tty_schedule_flip(&qtty
->port
);
158 static int goldfish_tty_activate(struct tty_port
*port
, struct tty_struct
*tty
)
160 struct goldfish_tty
*qtty
= container_of(port
, struct goldfish_tty
,
162 writel(GOLDFISH_TTY_CMD_INT_ENABLE
, qtty
->base
+ GOLDFISH_TTY_REG_CMD
);
166 static void goldfish_tty_shutdown(struct tty_port
*port
)
168 struct goldfish_tty
*qtty
= container_of(port
, struct goldfish_tty
,
170 writel(GOLDFISH_TTY_CMD_INT_DISABLE
, qtty
->base
+ GOLDFISH_TTY_REG_CMD
);
173 static int goldfish_tty_open(struct tty_struct
*tty
, struct file
*filp
)
175 struct goldfish_tty
*qtty
= &goldfish_ttys
[tty
->index
];
176 return tty_port_open(&qtty
->port
, tty
, filp
);
179 static void goldfish_tty_close(struct tty_struct
*tty
, struct file
*filp
)
181 tty_port_close(tty
->port
, tty
, filp
);
184 static void goldfish_tty_hangup(struct tty_struct
*tty
)
186 tty_port_hangup(tty
->port
);
189 static int goldfish_tty_write(struct tty_struct
*tty
, const unsigned char *buf
,
192 goldfish_tty_do_write(tty
->index
, buf
, count
);
196 static int goldfish_tty_write_room(struct tty_struct
*tty
)
201 static int goldfish_tty_chars_in_buffer(struct tty_struct
*tty
)
203 struct goldfish_tty
*qtty
= &goldfish_ttys
[tty
->index
];
204 void __iomem
*base
= qtty
->base
;
205 return readl(base
+ GOLDFISH_TTY_REG_BYTES_READY
);
208 static void goldfish_tty_console_write(struct console
*co
, const char *b
,
211 goldfish_tty_do_write(co
->index
, b
, count
);
214 static struct tty_driver
*goldfish_tty_console_device(struct console
*c
,
218 return goldfish_tty_driver
;
221 static int goldfish_tty_console_setup(struct console
*co
, char *options
)
223 if ((unsigned)co
->index
>= goldfish_tty_line_count
)
225 if (!goldfish_ttys
[co
->index
].base
)
230 static const struct tty_port_operations goldfish_port_ops
= {
231 .activate
= goldfish_tty_activate
,
232 .shutdown
= goldfish_tty_shutdown
235 static const struct tty_operations goldfish_tty_ops
= {
236 .open
= goldfish_tty_open
,
237 .close
= goldfish_tty_close
,
238 .hangup
= goldfish_tty_hangup
,
239 .write
= goldfish_tty_write
,
240 .write_room
= goldfish_tty_write_room
,
241 .chars_in_buffer
= goldfish_tty_chars_in_buffer
,
244 static int goldfish_tty_create_driver(void)
247 struct tty_driver
*tty
;
249 goldfish_ttys
= kcalloc(goldfish_tty_line_count
,
250 sizeof(*goldfish_ttys
),
252 if (goldfish_ttys
== NULL
) {
254 goto err_alloc_goldfish_ttys_failed
;
256 tty
= alloc_tty_driver(goldfish_tty_line_count
);
259 goto err_alloc_tty_driver_failed
;
261 tty
->driver_name
= "goldfish";
263 tty
->type
= TTY_DRIVER_TYPE_SERIAL
;
264 tty
->subtype
= SERIAL_TYPE_NORMAL
;
265 tty
->init_termios
= tty_std_termios
;
266 tty
->flags
= TTY_DRIVER_RESET_TERMIOS
| TTY_DRIVER_REAL_RAW
|
267 TTY_DRIVER_DYNAMIC_DEV
;
268 tty_set_operations(tty
, &goldfish_tty_ops
);
269 ret
= tty_register_driver(tty
);
271 goto err_tty_register_driver_failed
;
273 goldfish_tty_driver
= tty
;
276 err_tty_register_driver_failed
:
278 err_alloc_tty_driver_failed
:
279 kfree(goldfish_ttys
);
280 goldfish_ttys
= NULL
;
281 err_alloc_goldfish_ttys_failed
:
285 static void goldfish_tty_delete_driver(void)
287 tty_unregister_driver(goldfish_tty_driver
);
288 put_tty_driver(goldfish_tty_driver
);
289 goldfish_tty_driver
= NULL
;
290 kfree(goldfish_ttys
);
291 goldfish_ttys
= NULL
;
294 static int goldfish_tty_probe(struct platform_device
*pdev
)
296 struct goldfish_tty
*qtty
;
299 struct device
*ttydev
;
304 r
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
306 pr_err("goldfish_tty: No MEM resource available!\n");
310 base
= ioremap(r
->start
, 0x1000);
312 pr_err("goldfish_tty: Unable to ioremap base!\n");
316 r
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
318 pr_err("goldfish_tty: No IRQ resource available!\n");
324 mutex_lock(&goldfish_tty_lock
);
326 if (pdev
->id
== PLATFORM_DEVID_NONE
)
327 line
= goldfish_tty_current_line_count
;
331 if (line
>= goldfish_tty_line_count
) {
332 pr_err("goldfish_tty: Reached maximum tty number of %d.\n",
333 goldfish_tty_current_line_count
);
338 if (goldfish_tty_current_line_count
== 0) {
339 ret
= goldfish_tty_create_driver();
343 goldfish_tty_current_line_count
++;
345 qtty
= &goldfish_ttys
[line
];
346 spin_lock_init(&qtty
->lock
);
347 tty_port_init(&qtty
->port
);
348 qtty
->port
.ops
= &goldfish_port_ops
;
351 qtty
->dev
= &pdev
->dev
;
354 * Goldfish TTY device used by the Goldfish emulator
355 * should identify itself with 0, forcing the driver
356 * to use virtual addresses. Goldfish TTY device
357 * on Ranchu emulator (qemu2) returns 1 here and
358 * driver will use physical addresses.
360 qtty
->version
= readl(base
+ GOLDFISH_TTY_REG_VERSION
);
363 * Goldfish TTY device on Ranchu emulator (qemu2)
364 * will use DMA for read/write IO operations.
366 if (qtty
->version
> 0) {
368 * Initialize dma_mask to 32-bits.
370 if (!pdev
->dev
.dma_mask
)
371 pdev
->dev
.dma_mask
= &pdev
->dev
.coherent_dma_mask
;
372 ret
= dma_set_mask(&pdev
->dev
, DMA_BIT_MASK(32));
374 dev_err(&pdev
->dev
, "No suitable DMA available.\n");
375 goto err_dec_line_count
;
379 writel(GOLDFISH_TTY_CMD_INT_DISABLE
, base
+ GOLDFISH_TTY_REG_CMD
);
381 ret
= request_irq(irq
, goldfish_tty_interrupt
, IRQF_SHARED
,
382 "goldfish_tty", qtty
);
384 pr_err("goldfish_tty: No IRQ available!\n");
385 goto err_dec_line_count
;
388 ttydev
= tty_port_register_device(&qtty
->port
, goldfish_tty_driver
,
390 if (IS_ERR(ttydev
)) {
391 ret
= PTR_ERR(ttydev
);
392 goto err_tty_register_device_failed
;
395 strcpy(qtty
->console
.name
, "ttyGF");
396 qtty
->console
.write
= goldfish_tty_console_write
;
397 qtty
->console
.device
= goldfish_tty_console_device
;
398 qtty
->console
.setup
= goldfish_tty_console_setup
;
399 qtty
->console
.flags
= CON_PRINTBUFFER
;
400 qtty
->console
.index
= line
;
401 register_console(&qtty
->console
);
402 platform_set_drvdata(pdev
, qtty
);
404 mutex_unlock(&goldfish_tty_lock
);
407 err_tty_register_device_failed
:
410 goldfish_tty_current_line_count
--;
411 if (goldfish_tty_current_line_count
== 0)
412 goldfish_tty_delete_driver();
414 mutex_unlock(&goldfish_tty_lock
);
420 static int goldfish_tty_remove(struct platform_device
*pdev
)
422 struct goldfish_tty
*qtty
= platform_get_drvdata(pdev
);
424 mutex_lock(&goldfish_tty_lock
);
426 unregister_console(&qtty
->console
);
427 tty_unregister_device(goldfish_tty_driver
, qtty
->console
.index
);
430 free_irq(qtty
->irq
, pdev
);
431 goldfish_tty_current_line_count
--;
432 if (goldfish_tty_current_line_count
== 0)
433 goldfish_tty_delete_driver();
434 mutex_unlock(&goldfish_tty_lock
);
438 #ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
439 static void gf_early_console_putchar(struct uart_port
*port
, int ch
)
441 __raw_writel(ch
, port
->membase
);
444 static void gf_early_write(struct console
*con
, const char *s
, unsigned int n
)
446 struct earlycon_device
*dev
= con
->data
;
448 uart_console_write(&dev
->port
, s
, n
, gf_early_console_putchar
);
451 static int __init
gf_earlycon_setup(struct earlycon_device
*device
,
454 if (!device
->port
.membase
)
457 device
->con
->write
= gf_early_write
;
461 OF_EARLYCON_DECLARE(early_gf_tty
, "google,goldfish-tty", gf_earlycon_setup
);
464 static const struct of_device_id goldfish_tty_of_match
[] = {
465 { .compatible
= "google,goldfish-tty", },
469 MODULE_DEVICE_TABLE(of
, goldfish_tty_of_match
);
471 static struct platform_driver goldfish_tty_platform_driver
= {
472 .probe
= goldfish_tty_probe
,
473 .remove
= goldfish_tty_remove
,
475 .name
= "goldfish_tty",
476 .of_match_table
= goldfish_tty_of_match
,
480 module_platform_driver(goldfish_tty_platform_driver
);
482 MODULE_LICENSE("GPL v2");