1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2012 Intel, Inc.
4 * Copyright (C) 2013 Intel, Inc.
5 * Copyright (C) 2014 Linaro Limited
6 * Copyright (C) 2011-2016 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 /* This source file contains the implementation of a special device driver
20 * that intends to provide a *very* fast communication channel between the
21 * guest system and the QEMU emulator.
22 *
23 * Usage from the guest is simply the following (error handling simplified):
24 *
25 * int fd = open("/dev/qemu_pipe",O_RDWR);
26 * .... write() or read() through the pipe.
27 *
28 * This driver doesn't deal with the exact protocol used during the session.
29 * It is intended to be as simple as something like:
30 *
31 * // do this _just_ after opening the fd to connect to a specific
32 * // emulator service.
33 * const char* msg = "<pipename>";
34 * if (write(fd, msg, strlen(msg)+1) < 0) {
35 * ... could not connect to <pipename> service
36 * close(fd);
37 * }
38 *
39 * // after this, simply read() and write() to communicate with the
40 * // service. Exact protocol details left as an exercise to the reader.
41 *
42 * This driver is very fast because it doesn't copy any data through
43 * intermediate buffers, since the emulator is capable of translating
44 * guest user addresses into host ones.
45 *
46 * Note that we must however ensure that each user page involved in the
47 * exchange is properly mapped during a transfer.
48 */
49
50 #include <linux/module.h>
51 #include <linux/mod_devicetable.h>
52 #include <linux/interrupt.h>
53 #include <linux/kernel.h>
54 #include <linux/platform_device.h>
55 #include <linux/io.h>
56 #include <linux/acpi.h>
57 #include "goldfish_pipe_qemu.h"
58 #include "goldfish_pipe.h"
59 #include "goldfish_pipe_v1.h"
60 #include "goldfish_pipe_v2.h"
61
62 /*
63 * Update this when something changes in the driver's behavior so the host
64 * can benefit from knowing it
65 * Notes:
66 * version 2 was an intermediate release and isn't supported anymore.
67 * version 3 is goldfish_pipe_v2 without DMA support.
68 * version 4 (current) is goldfish_pipe_v2 with DMA support.
69 */
70 enum {
71 PIPE_DRIVER_VERSION = 4,
72 PIPE_CURRENT_DEVICE_VERSION = 2
73 };
74
goldfish_pipe_probe(struct platform_device * pdev)75 static int goldfish_pipe_probe(struct platform_device *pdev)
76 {
77 struct resource *r;
78 char __iomem *base;
79 int irq;
80 int version;
81
82 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
83 if (!r || resource_size(r) < PAGE_SIZE) {
84 dev_err(&pdev->dev, "can't allocate i/o page\n");
85 return -EINVAL;
86 }
87 base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
88 if (!base) {
89 dev_err(&pdev->dev, "ioremap failed\n");
90 return -EINVAL;
91 }
92
93 r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
94 if (!r)
95 return -EINVAL;
96
97 irq = r->start;
98
99 /*
100 * Exchange the versions with the host device
101 *
102 * Note: v1 driver used to not report its version, so we write it before
103 * reading device version back: this allows the host implementation to
104 * detect the old driver (if there was no version write before read).
105 */
106 writel(PIPE_DRIVER_VERSION, base + PIPE_V2_REG_VERSION);
107 version = readl(base + PIPE_V2_REG_VERSION);
108
109 if (version < PIPE_CURRENT_DEVICE_VERSION)
110 return goldfish_pipe_device_v1_init(pdev, base, irq);
111 else
112 return goldfish_pipe_device_v2_init(pdev, base, irq);
113 }
114
goldfish_pipe_remove(struct platform_device * pdev)115 static int goldfish_pipe_remove(struct platform_device *pdev)
116 {
117 struct goldfish_pipe_dev_base *dev = platform_get_drvdata(pdev);
118
119 return dev->deinit(dev, pdev);
120 }
121
122 static const struct acpi_device_id goldfish_pipe_acpi_match[] = {
123 { "GFSH0003", 0 },
124 { },
125 };
126 MODULE_DEVICE_TABLE(acpi, goldfish_pipe_acpi_match);
127
128 static const struct of_device_id goldfish_pipe_of_match[] = {
129 { .compatible = "google,android-pipe", },
130 {},
131 };
132 MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match);
133
134 static struct platform_driver goldfish_pipe_driver = {
135 .probe = goldfish_pipe_probe,
136 .remove = goldfish_pipe_remove,
137 .driver = {
138 .name = "goldfish_pipe",
139 .of_match_table = goldfish_pipe_of_match,
140 .acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match),
141 }
142 };
143
144 module_platform_driver(goldfish_pipe_driver);
145 MODULE_AUTHOR("David Turner <digit@google.com>");
146 MODULE_LICENSE("GPL v2");
147