Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2007 Google, Inc.
0004  * Copyright (C) 2012 Intel, Inc.
0005  * Copyright (C) 2017 Imagination Technologies Ltd.
0006  */
0007 
0008 #include <linux/console.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/tty.h>
0012 #include <linux/tty_flip.h>
0013 #include <linux/slab.h>
0014 #include <linux/io.h>
0015 #include <linux/module.h>
0016 #include <linux/mod_devicetable.h>
0017 #include <linux/goldfish.h>
0018 #include <linux/mm.h>
0019 #include <linux/dma-mapping.h>
0020 #include <linux/serial_core.h>
0021 
0022 /* Goldfish tty register's offsets */
0023 #define GOLDFISH_TTY_REG_BYTES_READY    0x04
0024 #define GOLDFISH_TTY_REG_CMD        0x08
0025 #define GOLDFISH_TTY_REG_DATA_PTR   0x10
0026 #define GOLDFISH_TTY_REG_DATA_LEN   0x14
0027 #define GOLDFISH_TTY_REG_DATA_PTR_HIGH  0x18
0028 #define GOLDFISH_TTY_REG_VERSION    0x20
0029 
0030 /* Goldfish tty commands */
0031 #define GOLDFISH_TTY_CMD_INT_DISABLE    0
0032 #define GOLDFISH_TTY_CMD_INT_ENABLE 1
0033 #define GOLDFISH_TTY_CMD_WRITE_BUFFER   2
0034 #define GOLDFISH_TTY_CMD_READ_BUFFER    3
0035 
0036 struct goldfish_tty {
0037     struct tty_port port;
0038     spinlock_t lock;
0039     void __iomem *base;
0040     u32 irq;
0041     int opencount;
0042     struct console console;
0043     u32 version;
0044     struct device *dev;
0045 };
0046 
0047 static DEFINE_MUTEX(goldfish_tty_lock);
0048 static struct tty_driver *goldfish_tty_driver;
0049 static u32 goldfish_tty_line_count = 8;
0050 static u32 goldfish_tty_current_line_count;
0051 static struct goldfish_tty *goldfish_ttys;
0052 
0053 static void do_rw_io(struct goldfish_tty *qtty,
0054              unsigned long address,
0055              unsigned int count,
0056              int is_write)
0057 {
0058     unsigned long irq_flags;
0059     void __iomem *base = qtty->base;
0060 
0061     spin_lock_irqsave(&qtty->lock, irq_flags);
0062     gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR,
0063              base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
0064     gf_iowrite32(count, base + GOLDFISH_TTY_REG_DATA_LEN);
0065 
0066     if (is_write)
0067         gf_iowrite32(GOLDFISH_TTY_CMD_WRITE_BUFFER,
0068                base + GOLDFISH_TTY_REG_CMD);
0069     else
0070         gf_iowrite32(GOLDFISH_TTY_CMD_READ_BUFFER,
0071                base + GOLDFISH_TTY_REG_CMD);
0072 
0073     spin_unlock_irqrestore(&qtty->lock, irq_flags);
0074 }
0075 
0076 static void goldfish_tty_rw(struct goldfish_tty *qtty,
0077                 unsigned long addr,
0078                 unsigned int count,
0079                 int is_write)
0080 {
0081     dma_addr_t dma_handle;
0082     enum dma_data_direction dma_dir;
0083 
0084     dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
0085     if (qtty->version > 0) {
0086         /*
0087          * Goldfish TTY for Ranchu platform uses
0088          * physical addresses and DMA for read/write operations
0089          */
0090         unsigned long addr_end = addr + count;
0091 
0092         while (addr < addr_end) {
0093             unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE;
0094             unsigned long next =
0095                     pg_end < addr_end ? pg_end : addr_end;
0096             unsigned long avail = next - addr;
0097 
0098             /*
0099              * Map the buffer's virtual address to the DMA address
0100              * so the buffer can be accessed by the device.
0101              */
0102             dma_handle = dma_map_single(qtty->dev, (void *)addr,
0103                             avail, dma_dir);
0104 
0105             if (dma_mapping_error(qtty->dev, dma_handle)) {
0106                 dev_err(qtty->dev, "tty: DMA mapping error.\n");
0107                 return;
0108             }
0109             do_rw_io(qtty, dma_handle, avail, is_write);
0110 
0111             /*
0112              * Unmap the previously mapped region after
0113              * the completion of the read/write operation.
0114              */
0115             dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir);
0116 
0117             addr += avail;
0118         }
0119     } else {
0120         /*
0121          * Old style Goldfish TTY used on the Goldfish platform
0122          * uses virtual addresses.
0123          */
0124         do_rw_io(qtty, addr, count, is_write);
0125     }
0126 }
0127 
0128 static void goldfish_tty_do_write(int line, const char *buf,
0129                   unsigned int count)
0130 {
0131     struct goldfish_tty *qtty = &goldfish_ttys[line];
0132     unsigned long address = (unsigned long)(void *)buf;
0133 
0134     goldfish_tty_rw(qtty, address, count, 1);
0135 }
0136 
0137 static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id)
0138 {
0139     struct goldfish_tty *qtty = dev_id;
0140     void __iomem *base = qtty->base;
0141     unsigned long address;
0142     unsigned char *buf;
0143     u32 count;
0144 
0145     count = gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY);
0146     if (count == 0)
0147         return IRQ_NONE;
0148 
0149     count = tty_prepare_flip_string(&qtty->port, &buf, count);
0150 
0151     address = (unsigned long)(void *)buf;
0152     goldfish_tty_rw(qtty, address, count, 0);
0153 
0154     tty_flip_buffer_push(&qtty->port);
0155     return IRQ_HANDLED;
0156 }
0157 
0158 static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty)
0159 {
0160     struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
0161                                     port);
0162     gf_iowrite32(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
0163     return 0;
0164 }
0165 
0166 static void goldfish_tty_shutdown(struct tty_port *port)
0167 {
0168     struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
0169                                     port);
0170     gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
0171 }
0172 
0173 static int goldfish_tty_open(struct tty_struct *tty, struct file *filp)
0174 {
0175     struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
0176     return tty_port_open(&qtty->port, tty, filp);
0177 }
0178 
0179 static void goldfish_tty_close(struct tty_struct *tty, struct file *filp)
0180 {
0181     tty_port_close(tty->port, tty, filp);
0182 }
0183 
0184 static void goldfish_tty_hangup(struct tty_struct *tty)
0185 {
0186     tty_port_hangup(tty->port);
0187 }
0188 
0189 static int goldfish_tty_write(struct tty_struct *tty, const unsigned char *buf,
0190                                 int count)
0191 {
0192     goldfish_tty_do_write(tty->index, buf, count);
0193     return count;
0194 }
0195 
0196 static unsigned int goldfish_tty_write_room(struct tty_struct *tty)
0197 {
0198     return 0x10000;
0199 }
0200 
0201 static unsigned int goldfish_tty_chars_in_buffer(struct tty_struct *tty)
0202 {
0203     struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
0204     void __iomem *base = qtty->base;
0205     return gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY);
0206 }
0207 
0208 static void goldfish_tty_console_write(struct console *co, const char *b,
0209                                 unsigned count)
0210 {
0211     goldfish_tty_do_write(co->index, b, count);
0212 }
0213 
0214 static struct tty_driver *goldfish_tty_console_device(struct console *c,
0215                                 int *index)
0216 {
0217     *index = c->index;
0218     return goldfish_tty_driver;
0219 }
0220 
0221 static int goldfish_tty_console_setup(struct console *co, char *options)
0222 {
0223     if ((unsigned)co->index >= goldfish_tty_line_count)
0224         return -ENODEV;
0225     if (!goldfish_ttys[co->index].base)
0226         return -ENODEV;
0227     return 0;
0228 }
0229 
0230 static const struct tty_port_operations goldfish_port_ops = {
0231     .activate = goldfish_tty_activate,
0232     .shutdown = goldfish_tty_shutdown
0233 };
0234 
0235 static const struct tty_operations goldfish_tty_ops = {
0236     .open = goldfish_tty_open,
0237     .close = goldfish_tty_close,
0238     .hangup = goldfish_tty_hangup,
0239     .write = goldfish_tty_write,
0240     .write_room = goldfish_tty_write_room,
0241     .chars_in_buffer = goldfish_tty_chars_in_buffer,
0242 };
0243 
0244 static int goldfish_tty_create_driver(void)
0245 {
0246     int ret;
0247     struct tty_driver *tty;
0248 
0249     goldfish_ttys = kcalloc(goldfish_tty_line_count,
0250                 sizeof(*goldfish_ttys),
0251                 GFP_KERNEL);
0252     if (goldfish_ttys == NULL) {
0253         ret = -ENOMEM;
0254         goto err_alloc_goldfish_ttys_failed;
0255     }
0256     tty = tty_alloc_driver(goldfish_tty_line_count,
0257             TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
0258             TTY_DRIVER_DYNAMIC_DEV);
0259     if (IS_ERR(tty)) {
0260         ret = PTR_ERR(tty);
0261         goto err_tty_alloc_driver_failed;
0262     }
0263     tty->driver_name = "goldfish";
0264     tty->name = "ttyGF";
0265     tty->type = TTY_DRIVER_TYPE_SERIAL;
0266     tty->subtype = SERIAL_TYPE_NORMAL;
0267     tty->init_termios = tty_std_termios;
0268     tty_set_operations(tty, &goldfish_tty_ops);
0269     ret = tty_register_driver(tty);
0270     if (ret)
0271         goto err_tty_register_driver_failed;
0272 
0273     goldfish_tty_driver = tty;
0274     return 0;
0275 
0276 err_tty_register_driver_failed:
0277     tty_driver_kref_put(tty);
0278 err_tty_alloc_driver_failed:
0279     kfree(goldfish_ttys);
0280     goldfish_ttys = NULL;
0281 err_alloc_goldfish_ttys_failed:
0282     return ret;
0283 }
0284 
0285 static void goldfish_tty_delete_driver(void)
0286 {
0287     tty_unregister_driver(goldfish_tty_driver);
0288     tty_driver_kref_put(goldfish_tty_driver);
0289     goldfish_tty_driver = NULL;
0290     kfree(goldfish_ttys);
0291     goldfish_ttys = NULL;
0292 }
0293 
0294 static int goldfish_tty_probe(struct platform_device *pdev)
0295 {
0296     struct goldfish_tty *qtty;
0297     int ret = -ENODEV;
0298     struct resource *r;
0299     struct device *ttydev;
0300     void __iomem *base;
0301     int irq;
0302     unsigned int line;
0303 
0304     r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0305     if (!r) {
0306         pr_err("goldfish_tty: No MEM resource available!\n");
0307         return -ENOMEM;
0308     }
0309 
0310     base = ioremap(r->start, 0x1000);
0311     if (!base) {
0312         pr_err("goldfish_tty: Unable to ioremap base!\n");
0313         return -ENOMEM;
0314     }
0315 
0316     irq = platform_get_irq(pdev, 0);
0317     if (irq < 0) {
0318         ret = irq;
0319         goto err_unmap;
0320     }
0321 
0322     mutex_lock(&goldfish_tty_lock);
0323 
0324     if (pdev->id == PLATFORM_DEVID_NONE)
0325         line = goldfish_tty_current_line_count;
0326     else
0327         line = pdev->id;
0328 
0329     if (line >= goldfish_tty_line_count) {
0330         pr_err("goldfish_tty: Reached maximum tty number of %d.\n",
0331                goldfish_tty_current_line_count);
0332         ret = -ENOMEM;
0333         goto err_unlock;
0334     }
0335 
0336     if (goldfish_tty_current_line_count == 0) {
0337         ret = goldfish_tty_create_driver();
0338         if (ret)
0339             goto err_unlock;
0340     }
0341     goldfish_tty_current_line_count++;
0342 
0343     qtty = &goldfish_ttys[line];
0344     spin_lock_init(&qtty->lock);
0345     tty_port_init(&qtty->port);
0346     qtty->port.ops = &goldfish_port_ops;
0347     qtty->base = base;
0348     qtty->irq = irq;
0349     qtty->dev = &pdev->dev;
0350 
0351     /*
0352      * Goldfish TTY device used by the Goldfish emulator
0353      * should identify itself with 0, forcing the driver
0354      * to use virtual addresses. Goldfish TTY device
0355      * on Ranchu emulator (qemu2) returns 1 here and
0356      * driver will use physical addresses.
0357      */
0358     qtty->version = gf_ioread32(base + GOLDFISH_TTY_REG_VERSION);
0359 
0360     /*
0361      * Goldfish TTY device on Ranchu emulator (qemu2)
0362      * will use DMA for read/write IO operations.
0363      */
0364     if (qtty->version > 0) {
0365         /*
0366          * Initialize dma_mask to 32-bits.
0367          */
0368         if (!pdev->dev.dma_mask)
0369             pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
0370         ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0371         if (ret) {
0372             dev_err(&pdev->dev, "No suitable DMA available.\n");
0373             goto err_dec_line_count;
0374         }
0375     }
0376 
0377     gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
0378 
0379     ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED,
0380               "goldfish_tty", qtty);
0381     if (ret) {
0382         pr_err("goldfish_tty: No IRQ available!\n");
0383         goto err_dec_line_count;
0384     }
0385 
0386     ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver,
0387                       line, &pdev->dev);
0388     if (IS_ERR(ttydev)) {
0389         ret = PTR_ERR(ttydev);
0390         goto err_tty_register_device_failed;
0391     }
0392 
0393     strcpy(qtty->console.name, "ttyGF");
0394     qtty->console.write = goldfish_tty_console_write;
0395     qtty->console.device = goldfish_tty_console_device;
0396     qtty->console.setup = goldfish_tty_console_setup;
0397     qtty->console.flags = CON_PRINTBUFFER;
0398     qtty->console.index = line;
0399     register_console(&qtty->console);
0400     platform_set_drvdata(pdev, qtty);
0401 
0402     mutex_unlock(&goldfish_tty_lock);
0403     return 0;
0404 
0405 err_tty_register_device_failed:
0406     free_irq(irq, qtty);
0407 err_dec_line_count:
0408     tty_port_destroy(&qtty->port);
0409     goldfish_tty_current_line_count--;
0410     if (goldfish_tty_current_line_count == 0)
0411         goldfish_tty_delete_driver();
0412 err_unlock:
0413     mutex_unlock(&goldfish_tty_lock);
0414 err_unmap:
0415     iounmap(base);
0416     return ret;
0417 }
0418 
0419 static int goldfish_tty_remove(struct platform_device *pdev)
0420 {
0421     struct goldfish_tty *qtty = platform_get_drvdata(pdev);
0422 
0423     mutex_lock(&goldfish_tty_lock);
0424 
0425     unregister_console(&qtty->console);
0426     tty_unregister_device(goldfish_tty_driver, qtty->console.index);
0427     iounmap(qtty->base);
0428     qtty->base = NULL;
0429     free_irq(qtty->irq, qtty);
0430     tty_port_destroy(&qtty->port);
0431     goldfish_tty_current_line_count--;
0432     if (goldfish_tty_current_line_count == 0)
0433         goldfish_tty_delete_driver();
0434     mutex_unlock(&goldfish_tty_lock);
0435     return 0;
0436 }
0437 
0438 #ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
0439 static void gf_early_console_putchar(struct uart_port *port, unsigned char ch)
0440 {
0441     gf_iowrite32(ch, port->membase);
0442 }
0443 
0444 static void gf_early_write(struct console *con, const char *s, unsigned int n)
0445 {
0446     struct earlycon_device *dev = con->data;
0447 
0448     uart_console_write(&dev->port, s, n, gf_early_console_putchar);
0449 }
0450 
0451 static int __init gf_earlycon_setup(struct earlycon_device *device,
0452                     const char *opt)
0453 {
0454     if (!device->port.membase)
0455         return -ENODEV;
0456 
0457     device->con->write = gf_early_write;
0458     return 0;
0459 }
0460 
0461 OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup);
0462 #endif
0463 
0464 static const struct of_device_id goldfish_tty_of_match[] = {
0465     { .compatible = "google,goldfish-tty", },
0466     {},
0467 };
0468 
0469 MODULE_DEVICE_TABLE(of, goldfish_tty_of_match);
0470 
0471 static struct platform_driver goldfish_tty_platform_driver = {
0472     .probe = goldfish_tty_probe,
0473     .remove = goldfish_tty_remove,
0474     .driver = {
0475         .name = "goldfish_tty",
0476         .of_match_table = goldfish_tty_of_match,
0477     }
0478 };
0479 
0480 module_platform_driver(goldfish_tty_platform_driver);
0481 
0482 MODULE_LICENSE("GPL v2");