diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-02-23 09:11:12 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-02-23 09:11:12 -0500 |
commit | ab646a24bb9b6125f3c23ef908b7c5b44b1b4e69 (patch) | |
tree | 5327ca6b6309851accbc609a3893c6f4b1f0dfe4 | |
parent | d65b4e98d7ea3038b767b70fe8be959b2913f16d (diff) | |
parent | e12bc14b88d44e5c1456dccb59ff58103f6c6edc (diff) |
Merge tag 'rpmsg-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc into next/rpmsg
* tag 'rpmsg-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc:
remoteproc: s/big switch/lookup table/
remoteproc: bail out if firmware has different endianess
remoteproc: don't use virtio's weak barriers
rpmsg: rename virtqueue_add_buf_gfp to virtqueue_add_buf
rpmsg: depend on EXPERIMENTAL
remoteproc: depend on EXPERIMENTAL
rpmsg: add Kconfig menu
remoteproc: add Kconfig menu
remoteproc: look for truncated firmware images
remoteproc/omap: utilize module_platform_driver
remoteproc: remove unused resource type
remoteproc: avoid registering a virtio device if not supported
remoteproc: do not require an iommu
samples/rpmsg: add an rpmsg driver sample
rpmsg: add virtio-based remote processor messaging bus
remoteproc/omap: add a remoteproc driver for OMAP4
remoteproc: create rpmsg virtio device
remoteproc: add debugfs entries
remoteproc: add framework for controlling remote processors
26 files changed, 4833 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-rpmsg b/Documentation/ABI/testing/sysfs-bus-rpmsg new file mode 100644 index 000000000000..189e419a5a2d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-rpmsg | |||
@@ -0,0 +1,75 @@ | |||
1 | What: /sys/bus/rpmsg/devices/.../name | ||
2 | Date: June 2011 | ||
3 | KernelVersion: 3.3 | ||
4 | Contact: Ohad Ben-Cohen <ohad@wizery.com> | ||
5 | Description: | ||
6 | Every rpmsg device is a communication channel with a remote | ||
7 | processor. Channels are identified with a (textual) name, | ||
8 | which is maximum 32 bytes long (defined as RPMSG_NAME_SIZE in | ||
9 | rpmsg.h). | ||
10 | |||
11 | This sysfs entry contains the name of this channel. | ||
12 | |||
13 | What: /sys/bus/rpmsg/devices/.../src | ||
14 | Date: June 2011 | ||
15 | KernelVersion: 3.3 | ||
16 | Contact: Ohad Ben-Cohen <ohad@wizery.com> | ||
17 | Description: | ||
18 | Every rpmsg device is a communication channel with a remote | ||
19 | processor. Channels have a local ("source") rpmsg address, | ||
20 | and remote ("destination") rpmsg address. When an entity | ||
21 | starts listening on one end of a channel, it assigns it with | ||
22 | a unique rpmsg address (a 32 bits integer). This way when | ||
23 | inbound messages arrive to this address, the rpmsg core | ||
24 | dispatches them to the listening entity (a kernel driver). | ||
25 | |||
26 | This sysfs entry contains the src (local) rpmsg address | ||
27 | of this channel. If it contains 0xffffffff, then an address | ||
28 | wasn't assigned (can happen if no driver exists for this | ||
29 | channel). | ||
30 | |||
31 | What: /sys/bus/rpmsg/devices/.../dst | ||
32 | Date: June 2011 | ||
33 | KernelVersion: 3.3 | ||
34 | Contact: Ohad Ben-Cohen <ohad@wizery.com> | ||
35 | Description: | ||
36 | Every rpmsg device is a communication channel with a remote | ||
37 | processor. Channels have a local ("source") rpmsg address, | ||
38 | and remote ("destination") rpmsg address. When an entity | ||
39 | starts listening on one end of a channel, it assigns it with | ||
40 | a unique rpmsg address (a 32 bits integer). This way when | ||
41 | inbound messages arrive to this address, the rpmsg core | ||
42 | dispatches them to the listening entity. | ||
43 | |||
44 | This sysfs entry contains the dst (remote) rpmsg address | ||
45 | of this channel. If it contains 0xffffffff, then an address | ||
46 | wasn't assigned (can happen if the kernel driver that | ||
47 | is attached to this channel is exposing a service to the | ||
48 | remote processor. This make it a local rpmsg server, | ||
49 | and it is listening for inbound messages that may be sent | ||
50 | from any remote rpmsg client; it is not bound to a single | ||
51 | remote entity). | ||
52 | |||
53 | What: /sys/bus/rpmsg/devices/.../announce | ||
54 | Date: June 2011 | ||
55 | KernelVersion: 3.3 | ||
56 | Contact: Ohad Ben-Cohen <ohad@wizery.com> | ||
57 | Description: | ||
58 | Every rpmsg device is a communication channel with a remote | ||
59 | processor. Channels are identified by a textual name (see | ||
60 | /sys/bus/rpmsg/devices/.../name above) and have a local | ||
61 | ("source") rpmsg address, and remote ("destination") rpmsg | ||
62 | address. | ||
63 | |||
64 | A channel is first created when an entity, whether local | ||
65 | or remote, starts listening on it for messages (and is thus | ||
66 | called an rpmsg server). | ||
67 | |||
68 | When that happens, a "name service" announcement is sent | ||
69 | to the other processor, in order to let it know about the | ||
70 | creation of the channel (this way remote clients know they | ||
71 | can start sending messages). | ||
72 | |||
73 | This sysfs entry tells us whether the channel is a local | ||
74 | server channel that is announced (values are either | ||
75 | true or false). | ||
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt new file mode 100644 index 000000000000..23ff7349ffe7 --- /dev/null +++ b/Documentation/remoteproc.txt | |||
@@ -0,0 +1,324 @@ | |||
1 | Remote Processor Framework | ||
2 | |||
3 | 1. Introduction | ||
4 | |||
5 | Modern SoCs typically have heterogeneous remote processor devices in asymmetric | ||
6 | multiprocessing (AMP) configurations, which may be running different instances | ||
7 | of operating system, whether it's Linux or any other flavor of real-time OS. | ||
8 | |||
9 | OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP. | ||
10 | In a typical configuration, the dual cortex-A9 is running Linux in a SMP | ||
11 | configuration, and each of the other three cores (two M3 cores and a DSP) | ||
12 | is running its own instance of RTOS in an AMP configuration. | ||
13 | |||
14 | The remoteproc framework allows different platforms/architectures to | ||
15 | control (power on, load firmware, power off) those remote processors while | ||
16 | abstracting the hardware differences, so the entire driver doesn't need to be | ||
17 | duplicated. In addition, this framework also adds rpmsg virtio devices | ||
18 | for remote processors that supports this kind of communication. This way, | ||
19 | platform-specific remoteproc drivers only need to provide a few low-level | ||
20 | handlers, and then all rpmsg drivers will then just work | ||
21 | (for more information about the virtio-based rpmsg bus and its drivers, | ||
22 | please read Documentation/rpmsg.txt). | ||
23 | |||
24 | 2. User API | ||
25 | |||
26 | int rproc_boot(struct rproc *rproc) | ||
27 | - Boot a remote processor (i.e. load its firmware, power it on, ...). | ||
28 | If the remote processor is already powered on, this function immediately | ||
29 | returns (successfully). | ||
30 | Returns 0 on success, and an appropriate error value otherwise. | ||
31 | Note: to use this function you should already have a valid rproc | ||
32 | handle. There are several ways to achieve that cleanly (devres, pdata, | ||
33 | the way remoteproc_rpmsg.c does this, or, if this becomes prevalent, we | ||
34 | might also consider using dev_archdata for this). See also | ||
35 | rproc_get_by_name() below. | ||
36 | |||
37 | void rproc_shutdown(struct rproc *rproc) | ||
38 | - Power off a remote processor (previously booted with rproc_boot()). | ||
39 | In case @rproc is still being used by an additional user(s), then | ||
40 | this function will just decrement the power refcount and exit, | ||
41 | without really powering off the device. | ||
42 | Every call to rproc_boot() must (eventually) be accompanied by a call | ||
43 | to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug. | ||
44 | Notes: | ||
45 | - we're not decrementing the rproc's refcount, only the power refcount. | ||
46 | which means that the @rproc handle stays valid even after | ||
47 | rproc_shutdown() returns, and users can still use it with a subsequent | ||
48 | rproc_boot(), if needed. | ||
49 | - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly | ||
50 | because rproc_shutdown() _does not_ decrement the refcount of @rproc. | ||
51 | To decrement the refcount of @rproc, use rproc_put() (but _only_ if | ||
52 | you acquired @rproc using rproc_get_by_name()). | ||
53 | |||
54 | struct rproc *rproc_get_by_name(const char *name) | ||
55 | - Find an rproc handle using the remote processor's name, and then | ||
56 | boot it. If it's already powered on, then just immediately return | ||
57 | (successfully). Returns the rproc handle on success, and NULL on failure. | ||
58 | This function increments the remote processor's refcount, so always | ||
59 | use rproc_put() to decrement it back once rproc isn't needed anymore. | ||
60 | Note: currently rproc_get_by_name() and rproc_put() are not used anymore | ||
61 | by the rpmsg bus and its drivers. We need to scrutinize the use cases | ||
62 | that still need them, and see if we can migrate them to use the non | ||
63 | name-based boot/shutdown interface. | ||
64 | |||
65 | void rproc_put(struct rproc *rproc) | ||
66 | - Decrement @rproc's power refcount and shut it down if it reaches zero | ||
67 | (essentially by just calling rproc_shutdown), and then decrement @rproc's | ||
68 | validity refcount too. | ||
69 | After this function returns, @rproc may _not_ be used anymore, and its | ||
70 | handle should be considered invalid. | ||
71 | This function should be called _iff_ the @rproc handle was grabbed by | ||
72 | calling rproc_get_by_name(). | ||
73 | |||
74 | 3. Typical usage | ||
75 | |||
76 | #include <linux/remoteproc.h> | ||
77 | |||
78 | /* in case we were given a valid 'rproc' handle */ | ||
79 | int dummy_rproc_example(struct rproc *my_rproc) | ||
80 | { | ||
81 | int ret; | ||
82 | |||
83 | /* let's power on and boot our remote processor */ | ||
84 | ret = rproc_boot(my_rproc); | ||
85 | if (ret) { | ||
86 | /* | ||
87 | * something went wrong. handle it and leave. | ||
88 | */ | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * our remote processor is now powered on... give it some work | ||
93 | */ | ||
94 | |||
95 | /* let's shut it down now */ | ||
96 | rproc_shutdown(my_rproc); | ||
97 | } | ||
98 | |||
99 | 4. API for implementors | ||
100 | |||
101 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
102 | const struct rproc_ops *ops, | ||
103 | const char *firmware, int len) | ||
104 | - Allocate a new remote processor handle, but don't register | ||
105 | it yet. Required parameters are the underlying device, the | ||
106 | name of this remote processor, platform-specific ops handlers, | ||
107 | the name of the firmware to boot this rproc with, and the | ||
108 | length of private data needed by the allocating rproc driver (in bytes). | ||
109 | |||
110 | This function should be used by rproc implementations during | ||
111 | initialization of the remote processor. | ||
112 | After creating an rproc handle using this function, and when ready, | ||
113 | implementations should then call rproc_register() to complete | ||
114 | the registration of the remote processor. | ||
115 | On success, the new rproc is returned, and on failure, NULL. | ||
116 | |||
117 | Note: _never_ directly deallocate @rproc, even if it was not registered | ||
118 | yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free(). | ||
119 | |||
120 | void rproc_free(struct rproc *rproc) | ||
121 | - Free an rproc handle that was allocated by rproc_alloc. | ||
122 | This function should _only_ be used if @rproc was only allocated, | ||
123 | but not registered yet. | ||
124 | If @rproc was already successfully registered (by calling | ||
125 | rproc_register()), then use rproc_unregister() instead. | ||
126 | |||
127 | int rproc_register(struct rproc *rproc) | ||
128 | - Register @rproc with the remoteproc framework, after it has been | ||
129 | allocated with rproc_alloc(). | ||
130 | This is called by the platform-specific rproc implementation, whenever | ||
131 | a new remote processor device is probed. | ||
132 | Returns 0 on success and an appropriate error code otherwise. | ||
133 | Note: this function initiates an asynchronous firmware loading | ||
134 | context, which will look for virtio devices supported by the rproc's | ||
135 | firmware. | ||
136 | If found, those virtio devices will be created and added, so as a result | ||
137 | of registering this remote processor, additional virtio drivers might get | ||
138 | probed. | ||
139 | Currently, though, we only support a single RPMSG virtio vdev per remote | ||
140 | processor. | ||
141 | |||
142 | int rproc_unregister(struct rproc *rproc) | ||
143 | - Unregister a remote processor, and decrement its refcount. | ||
144 | If its refcount drops to zero, then @rproc will be freed. If not, | ||
145 | it will be freed later once the last reference is dropped. | ||
146 | |||
147 | This function should be called when the platform specific rproc | ||
148 | implementation decides to remove the rproc device. it should | ||
149 | _only_ be called if a previous invocation of rproc_register() | ||
150 | has completed successfully. | ||
151 | |||
152 | After rproc_unregister() returns, @rproc is _not_ valid anymore and | ||
153 | it shouldn't be used. More specifically, don't call rproc_free() | ||
154 | or try to directly free @rproc after rproc_unregister() returns; | ||
155 | none of these are needed, and calling them is a bug. | ||
156 | |||
157 | Returns 0 on success and -EINVAL if @rproc isn't valid. | ||
158 | |||
159 | 5. Implementation callbacks | ||
160 | |||
161 | These callbacks should be provided by platform-specific remoteproc | ||
162 | drivers: | ||
163 | |||
164 | /** | ||
165 | * struct rproc_ops - platform-specific device handlers | ||
166 | * @start: power on the device and boot it | ||
167 | * @stop: power off the device | ||
168 | * @kick: kick a virtqueue (virtqueue id given as a parameter) | ||
169 | */ | ||
170 | struct rproc_ops { | ||
171 | int (*start)(struct rproc *rproc); | ||
172 | int (*stop)(struct rproc *rproc); | ||
173 | void (*kick)(struct rproc *rproc, int vqid); | ||
174 | }; | ||
175 | |||
176 | Every remoteproc implementation should at least provide the ->start and ->stop | ||
177 | handlers. If rpmsg functionality is also desired, then the ->kick handler | ||
178 | should be provided as well. | ||
179 | |||
180 | The ->start() handler takes an rproc handle and should then power on the | ||
181 | device and boot it (use rproc->priv to access platform-specific private data). | ||
182 | The boot address, in case needed, can be found in rproc->bootaddr (remoteproc | ||
183 | core puts there the ELF entry point). | ||
184 | On success, 0 should be returned, and on failure, an appropriate error code. | ||
185 | |||
186 | The ->stop() handler takes an rproc handle and powers the device down. | ||
187 | On success, 0 is returned, and on failure, an appropriate error code. | ||
188 | |||
189 | The ->kick() handler takes an rproc handle, and an index of a virtqueue | ||
190 | where new message was placed in. Implementations should interrupt the remote | ||
191 | processor and let it know it has pending messages. Notifying remote processors | ||
192 | the exact virtqueue index to look in is optional: it is easy (and not | ||
193 | too expensive) to go through the existing virtqueues and look for new buffers | ||
194 | in the used rings. | ||
195 | |||
196 | 6. Binary Firmware Structure | ||
197 | |||
198 | At this point remoteproc only supports ELF32 firmware binaries. However, | ||
199 | it is quite expected that other platforms/devices which we'd want to | ||
200 | support with this framework will be based on different binary formats. | ||
201 | |||
202 | When those use cases show up, we will have to decouple the binary format | ||
203 | from the framework core, so we can support several binary formats without | ||
204 | duplicating common code. | ||
205 | |||
206 | When the firmware is parsed, its various segments are loaded to memory | ||
207 | according to the specified device address (might be a physical address | ||
208 | if the remote processor is accessing memory directly). | ||
209 | |||
210 | In addition to the standard ELF segments, most remote processors would | ||
211 | also include a special section which we call "the resource table". | ||
212 | |||
213 | The resource table contains system resources that the remote processor | ||
214 | requires before it should be powered on, such as allocation of physically | ||
215 | contiguous memory, or iommu mapping of certain on-chip peripherals. | ||
216 | Remotecore will only power up the device after all the resource table's | ||
217 | requirement are met. | ||
218 | |||
219 | In addition to system resources, the resource table may also contain | ||
220 | resource entries that publish the existence of supported features | ||
221 | or configurations by the remote processor, such as trace buffers and | ||
222 | supported virtio devices (and their configurations). | ||
223 | |||
224 | Currently the resource table is just an array of: | ||
225 | |||
226 | /** | ||
227 | * struct fw_resource - describes an entry from the resource section | ||
228 | * @type: resource type | ||
229 | * @id: index number of the resource | ||
230 | * @da: device address of the resource | ||
231 | * @pa: physical address of the resource | ||
232 | * @len: size, in bytes, of the resource | ||
233 | * @flags: properties of the resource, e.g. iommu protection required | ||
234 | * @reserved: must be 0 atm | ||
235 | * @name: name of resource | ||
236 | */ | ||
237 | struct fw_resource { | ||
238 | u32 type; | ||
239 | u32 id; | ||
240 | u64 da; | ||
241 | u64 pa; | ||
242 | u32 len; | ||
243 | u32 flags; | ||
244 | u8 reserved[16]; | ||
245 | u8 name[48]; | ||
246 | } __packed; | ||
247 | |||
248 | Some resources entries are mere announcements, where the host is informed | ||
249 | of specific remoteproc configuration. Other entries require the host to | ||
250 | do something (e.g. reserve a requested resource) and possibly also reply | ||
251 | by overwriting a member inside 'struct fw_resource' with info about the | ||
252 | allocated resource. | ||
253 | |||
254 | Different resource entries use different members of this struct, | ||
255 | with different meanings. This is pretty limiting and error-prone, | ||
256 | so the plan is to move to variable-length TLV-based resource entries, | ||
257 | where each resource will begin with a type and length fields, followed by | ||
258 | its own specific structure. | ||
259 | |||
260 | Here are the resource types that are currently being used: | ||
261 | |||
262 | /** | ||
263 | * enum fw_resource_type - types of resource entries | ||
264 | * | ||
265 | * @RSC_CARVEOUT: request for allocation of a physically contiguous | ||
266 | * memory region. | ||
267 | * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. | ||
268 | * @RSC_TRACE: announces the availability of a trace buffer into which | ||
269 | * the remote processor will be writing logs. In this case, | ||
270 | * 'da' indicates the device address where logs are written to, | ||
271 | * and 'len' is the size of the trace buffer. | ||
272 | * @RSC_VRING: request for allocation of a virtio vring (address should | ||
273 | * be indicated in 'da', and 'len' should contain the number | ||
274 | * of buffers supported by the vring). | ||
275 | * @RSC_VIRTIO_DEV: announces support for a virtio device, and serves as | ||
276 | * the virtio header. 'da' contains the virtio device | ||
277 | * features, 'pa' holds the virtio guest features (host | ||
278 | * will write them here after they're negotiated), 'len' | ||
279 | * holds the virtio status, and 'flags' holds the virtio | ||
280 | * device id (currently only VIRTIO_ID_RPMSG is supported). | ||
281 | */ | ||
282 | enum fw_resource_type { | ||
283 | RSC_CARVEOUT = 0, | ||
284 | RSC_DEVMEM = 1, | ||
285 | RSC_TRACE = 2, | ||
286 | RSC_VRING = 3, | ||
287 | RSC_VIRTIO_DEV = 4, | ||
288 | RSC_VIRTIO_CFG = 5, | ||
289 | }; | ||
290 | |||
291 | Most of the resource entries share the basic idea of address/length | ||
292 | negotiation with the host: the firmware usually asks for memory | ||
293 | of size 'len' bytes, and the host needs to allocate it and provide | ||
294 | the device/physical address (when relevant) in 'da'/'pa' respectively. | ||
295 | |||
296 | If the firmware is compiled with hard coded device addresses, and | ||
297 | can't handle dynamically allocated 'da' values, then the 'da' field | ||
298 | will contain the expected device addresses (today we actually only support | ||
299 | this scheme, as there aren't yet any use cases for dynamically allocated | ||
300 | device addresses). | ||
301 | |||
302 | We also expect that platform-specific resource entries will show up | ||
303 | at some point. When that happens, we could easily add a new RSC_PLAFORM | ||
304 | type, and hand those resources to the platform-specific rproc driver to handle. | ||
305 | |||
306 | 7. Virtio and remoteproc | ||
307 | |||
308 | The firmware should provide remoteproc information about virtio devices | ||
309 | that it supports, and their configurations: a RSC_VIRTIO_DEV resource entry | ||
310 | should specify the virtio device id, and subsequent RSC_VRING resource entries | ||
311 | should indicate the vring size (i.e. how many buffers do they support) and | ||
312 | where should they be mapped (i.e. which device address). Note: the alignment | ||
313 | between the consumer and producer parts of the vring is assumed to be 4096. | ||
314 | |||
315 | At this point we only support a single virtio rpmsg device per remote | ||
316 | processor, but the plan is to remove this limitation. In addition, once we | ||
317 | move to TLV-based resource table, the plan is to have a single RSC_VIRTIO | ||
318 | entry per supported virtio device, which will include the virtio header, | ||
319 | the vrings information and the virtio config space. | ||
320 | |||
321 | Of course, RSC_VIRTIO resource entries are only good enough for static | ||
322 | allocation of virtio devices. Dynamic allocations will also be made possible | ||
323 | using the rpmsg bus (similar to how we already do dynamic allocations of | ||
324 | rpmsg channels; read more about it in rpmsg.txt). | ||
diff --git a/Documentation/rpmsg.txt b/Documentation/rpmsg.txt new file mode 100644 index 000000000000..409d9f964c5b --- /dev/null +++ b/Documentation/rpmsg.txt | |||
@@ -0,0 +1,293 @@ | |||
1 | Remote Processor Messaging (rpmsg) Framework | ||
2 | |||
3 | Note: this document describes the rpmsg bus and how to write rpmsg drivers. | ||
4 | To learn how to add rpmsg support for new platforms, check out remoteproc.txt | ||
5 | (also a resident of Documentation/). | ||
6 | |||
7 | 1. Introduction | ||
8 | |||
9 | Modern SoCs typically employ heterogeneous remote processor devices in | ||
10 | asymmetric multiprocessing (AMP) configurations, which may be running | ||
11 | different instances of operating system, whether it's Linux or any other | ||
12 | flavor of real-time OS. | ||
13 | |||
14 | OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP. | ||
15 | Typically, the dual cortex-A9 is running Linux in a SMP configuration, | ||
16 | and each of the other three cores (two M3 cores and a DSP) is running | ||
17 | its own instance of RTOS in an AMP configuration. | ||
18 | |||
19 | Typically AMP remote processors employ dedicated DSP codecs and multimedia | ||
20 | hardware accelerators, and therefore are often used to offload CPU-intensive | ||
21 | multimedia tasks from the main application processor. | ||
22 | |||
23 | These remote processors could also be used to control latency-sensitive | ||
24 | sensors, drive random hardware blocks, or just perform background tasks | ||
25 | while the main CPU is idling. | ||
26 | |||
27 | Users of those remote processors can either be userland apps (e.g. multimedia | ||
28 | frameworks talking with remote OMX components) or kernel drivers (controlling | ||
29 | hardware accessible only by the remote processor, reserving kernel-controlled | ||
30 | resources on behalf of the remote processor, etc..). | ||
31 | |||
32 | Rpmsg is a virtio-based messaging bus that allows kernel drivers to communicate | ||
33 | with remote processors available on the system. In turn, drivers could then | ||
34 | expose appropriate user space interfaces, if needed. | ||
35 | |||
36 | When writing a driver that exposes rpmsg communication to userland, please | ||
37 | keep in mind that remote processors might have direct access to the | ||
38 | system's physical memory and other sensitive hardware resources (e.g. on | ||
39 | OMAP4, remote cores and hardware accelerators may have direct access to the | ||
40 | physical memory, gpio banks, dma controllers, i2c bus, gptimers, mailbox | ||
41 | devices, hwspinlocks, etc..). Moreover, those remote processors might be | ||
42 | running RTOS where every task can access the entire memory/devices exposed | ||
43 | to the processor. To minimize the risks of rogue (or buggy) userland code | ||
44 | exploiting remote bugs, and by that taking over the system, it is often | ||
45 | desired to limit userland to specific rpmsg channels (see definition below) | ||
46 | it can send messages on, and if possible, minimize how much control | ||
47 | it has over the content of the messages. | ||
48 | |||
49 | Every rpmsg device is a communication channel with a remote processor (thus | ||
50 | rpmsg devices are called channels). Channels are identified by a textual name | ||
51 | and have a local ("source") rpmsg address, and remote ("destination") rpmsg | ||
52 | address. | ||
53 | |||
54 | When a driver starts listening on a channel, its rx callback is bound with | ||
55 | a unique rpmsg local address (a 32-bit integer). This way when inbound messages | ||
56 | arrive, the rpmsg core dispatches them to the appropriate driver according | ||
57 | to their destination address (this is done by invoking the driver's rx handler | ||
58 | with the payload of the inbound message). | ||
59 | |||
60 | |||
61 | 2. User API | ||
62 | |||
63 | int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len); | ||
64 | - sends a message across to the remote processor on a given channel. | ||
65 | The caller should specify the channel, the data it wants to send, | ||
66 | and its length (in bytes). The message will be sent on the specified | ||
67 | channel, i.e. its source and destination address fields will be | ||
68 | set to the channel's src and dst addresses. | ||
69 | |||
70 | In case there are no TX buffers available, the function will block until | ||
71 | one becomes available (i.e. until the remote processor consumes | ||
72 | a tx buffer and puts it back on virtio's used descriptor ring), | ||
73 | or a timeout of 15 seconds elapses. When the latter happens, | ||
74 | -ERESTARTSYS is returned. | ||
75 | The function can only be called from a process context (for now). | ||
76 | Returns 0 on success and an appropriate error value on failure. | ||
77 | |||
78 | int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst); | ||
79 | - sends a message across to the remote processor on a given channel, | ||
80 | to a destination address provided by the caller. | ||
81 | The caller should specify the channel, the data it wants to send, | ||
82 | its length (in bytes), and an explicit destination address. | ||
83 | The message will then be sent to the remote processor to which the | ||
84 | channel belongs, using the channel's src address, and the user-provided | ||
85 | dst address (thus the channel's dst address will be ignored). | ||
86 | |||
87 | In case there are no TX buffers available, the function will block until | ||
88 | one becomes available (i.e. until the remote processor consumes | ||
89 | a tx buffer and puts it back on virtio's used descriptor ring), | ||
90 | or a timeout of 15 seconds elapses. When the latter happens, | ||
91 | -ERESTARTSYS is returned. | ||
92 | The function can only be called from a process context (for now). | ||
93 | Returns 0 on success and an appropriate error value on failure. | ||
94 | |||
95 | int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
96 | void *data, int len); | ||
97 | - sends a message across to the remote processor, using the src and dst | ||
98 | addresses provided by the user. | ||
99 | The caller should specify the channel, the data it wants to send, | ||
100 | its length (in bytes), and explicit source and destination addresses. | ||
101 | The message will then be sent to the remote processor to which the | ||
102 | channel belongs, but the channel's src and dst addresses will be | ||
103 | ignored (and the user-provided addresses will be used instead). | ||
104 | |||
105 | In case there are no TX buffers available, the function will block until | ||
106 | one becomes available (i.e. until the remote processor consumes | ||
107 | a tx buffer and puts it back on virtio's used descriptor ring), | ||
108 | or a timeout of 15 seconds elapses. When the latter happens, | ||
109 | -ERESTARTSYS is returned. | ||
110 | The function can only be called from a process context (for now). | ||
111 | Returns 0 on success and an appropriate error value on failure. | ||
112 | |||
113 | int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len); | ||
114 | - sends a message across to the remote processor on a given channel. | ||
115 | The caller should specify the channel, the data it wants to send, | ||
116 | and its length (in bytes). The message will be sent on the specified | ||
117 | channel, i.e. its source and destination address fields will be | ||
118 | set to the channel's src and dst addresses. | ||
119 | |||
120 | In case there are no TX buffers available, the function will immediately | ||
121 | return -ENOMEM without waiting until one becomes available. | ||
122 | The function can only be called from a process context (for now). | ||
123 | Returns 0 on success and an appropriate error value on failure. | ||
124 | |||
125 | int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) | ||
126 | - sends a message across to the remote processor on a given channel, | ||
127 | to a destination address provided by the user. | ||
128 | The user should specify the channel, the data it wants to send, | ||
129 | its length (in bytes), and an explicit destination address. | ||
130 | The message will then be sent to the remote processor to which the | ||
131 | channel belongs, using the channel's src address, and the user-provided | ||
132 | dst address (thus the channel's dst address will be ignored). | ||
133 | |||
134 | In case there are no TX buffers available, the function will immediately | ||
135 | return -ENOMEM without waiting until one becomes available. | ||
136 | The function can only be called from a process context (for now). | ||
137 | Returns 0 on success and an appropriate error value on failure. | ||
138 | |||
139 | int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
140 | void *data, int len); | ||
141 | - sends a message across to the remote processor, using source and | ||
142 | destination addresses provided by the user. | ||
143 | The user should specify the channel, the data it wants to send, | ||
144 | its length (in bytes), and explicit source and destination addresses. | ||
145 | The message will then be sent to the remote processor to which the | ||
146 | channel belongs, but the channel's src and dst addresses will be | ||
147 | ignored (and the user-provided addresses will be used instead). | ||
148 | |||
149 | In case there are no TX buffers available, the function will immediately | ||
150 | return -ENOMEM without waiting until one becomes available. | ||
151 | The function can only be called from a process context (for now). | ||
152 | Returns 0 on success and an appropriate error value on failure. | ||
153 | |||
154 | struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, | ||
155 | void (*cb)(struct rpmsg_channel *, void *, int, void *, u32), | ||
156 | void *priv, u32 addr); | ||
157 | - every rpmsg address in the system is bound to an rx callback (so when | ||
158 | inbound messages arrive, they are dispatched by the rpmsg bus using the | ||
159 | appropriate callback handler) by means of an rpmsg_endpoint struct. | ||
160 | |||
161 | This function allows drivers to create such an endpoint, and by that, | ||
162 | bind a callback, and possibly some private data too, to an rpmsg address | ||
163 | (either one that is known in advance, or one that will be dynamically | ||
164 | assigned for them). | ||
165 | |||
166 | Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint | ||
167 | is already created for them when they are probed by the rpmsg bus | ||
168 | (using the rx callback they provide when they registered to the rpmsg bus). | ||
169 | |||
170 | So things should just work for simple drivers: they already have an | ||
171 | endpoint, their rx callback is bound to their rpmsg address, and when | ||
172 | relevant inbound messages arrive (i.e. messages which their dst address | ||
173 | equals to the src address of their rpmsg channel), the driver's handler | ||
174 | is invoked to process it. | ||
175 | |||
176 | That said, more complicated drivers might do need to allocate | ||
177 | additional rpmsg addresses, and bind them to different rx callbacks. | ||
178 | To accomplish that, those drivers need to call this function. | ||
179 | Drivers should provide their channel (so the new endpoint would bind | ||
180 | to the same remote processor their channel belongs to), an rx callback | ||
181 | function, an optional private data (which is provided back when the | ||
182 | rx callback is invoked), and an address they want to bind with the | ||
183 | callback. If addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will | ||
184 | dynamically assign them an available rpmsg address (drivers should have | ||
185 | a very good reason why not to always use RPMSG_ADDR_ANY here). | ||
186 | |||
187 | Returns a pointer to the endpoint on success, or NULL on error. | ||
188 | |||
189 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept); | ||
190 | - destroys an existing rpmsg endpoint. user should provide a pointer | ||
191 | to an rpmsg endpoint that was previously created with rpmsg_create_ept(). | ||
192 | |||
193 | int register_rpmsg_driver(struct rpmsg_driver *rpdrv); | ||
194 | - registers an rpmsg driver with the rpmsg bus. user should provide | ||
195 | a pointer to an rpmsg_driver struct, which contains the driver's | ||
196 | ->probe() and ->remove() functions, an rx callback, and an id_table | ||
197 | specifying the names of the channels this driver is interested to | ||
198 | be probed with. | ||
199 | |||
200 | void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv); | ||
201 | - unregisters an rpmsg driver from the rpmsg bus. user should provide | ||
202 | a pointer to a previously-registered rpmsg_driver struct. | ||
203 | Returns 0 on success, and an appropriate error value on failure. | ||
204 | |||
205 | |||
206 | 3. Typical usage | ||
207 | |||
208 | The following is a simple rpmsg driver, that sends an "hello!" message | ||
209 | on probe(), and whenever it receives an incoming message, it dumps its | ||
210 | content to the console. | ||
211 | |||
212 | #include <linux/kernel.h> | ||
213 | #include <linux/module.h> | ||
214 | #include <linux/rpmsg.h> | ||
215 | |||
216 | static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, | ||
217 | void *priv, u32 src) | ||
218 | { | ||
219 | print_hex_dump(KERN_INFO, "incoming message:", DUMP_PREFIX_NONE, | ||
220 | 16, 1, data, len, true); | ||
221 | } | ||
222 | |||
223 | static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) | ||
224 | { | ||
225 | int err; | ||
226 | |||
227 | dev_info(&rpdev->dev, "chnl: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst); | ||
228 | |||
229 | /* send a message on our channel */ | ||
230 | err = rpmsg_send(rpdev, "hello!", 6); | ||
231 | if (err) { | ||
232 | pr_err("rpmsg_send failed: %d\n", err); | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev) | ||
240 | { | ||
241 | dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n"); | ||
242 | } | ||
243 | |||
244 | static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = { | ||
245 | { .name = "rpmsg-client-sample" }, | ||
246 | { }, | ||
247 | }; | ||
248 | MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table); | ||
249 | |||
250 | static struct rpmsg_driver rpmsg_sample_client = { | ||
251 | .drv.name = KBUILD_MODNAME, | ||
252 | .drv.owner = THIS_MODULE, | ||
253 | .id_table = rpmsg_driver_sample_id_table, | ||
254 | .probe = rpmsg_sample_probe, | ||
255 | .callback = rpmsg_sample_cb, | ||
256 | .remove = __devexit_p(rpmsg_sample_remove), | ||
257 | }; | ||
258 | |||
259 | static int __init init(void) | ||
260 | { | ||
261 | return register_rpmsg_driver(&rpmsg_sample_client); | ||
262 | } | ||
263 | module_init(init); | ||
264 | |||
265 | static void __exit fini(void) | ||
266 | { | ||
267 | unregister_rpmsg_driver(&rpmsg_sample_client); | ||
268 | } | ||
269 | module_exit(fini); | ||
270 | |||
271 | Note: a similar sample which can be built and loaded can be found | ||
272 | in samples/rpmsg/. | ||
273 | |||
274 | 4. Allocations of rpmsg channels: | ||
275 | |||
276 | At this point we only support dynamic allocations of rpmsg channels. | ||
277 | |||
278 | This is possible only with remote processors that have the VIRTIO_RPMSG_F_NS | ||
279 | virtio device feature set. This feature bit means that the remote | ||
280 | processor supports dynamic name service announcement messages. | ||
281 | |||
282 | When this feature is enabled, creation of rpmsg devices (i.e. channels) | ||
283 | is completely dynamic: the remote processor announces the existence of a | ||
284 | remote rpmsg service by sending a name service message (which contains | ||
285 | the name and rpmsg addr of the remote service, see struct rpmsg_ns_msg). | ||
286 | |||
287 | This message is then handled by the rpmsg bus, which in turn dynamically | ||
288 | creates and registers an rpmsg channel (which represents the remote service). | ||
289 | If/when a relevant rpmsg driver is registered, it will be immediately probed | ||
290 | by the bus, and can then start sending messages to the remote service. | ||
291 | |||
292 | The plan is also to add static creation of rpmsg channels via the virtio | ||
293 | config space, but it's not implemented yet. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 55ca0bea142c..50a62ad6d2ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5550,6 +5550,13 @@ S: Supported | |||
5550 | F: drivers/base/regmap/ | 5550 | F: drivers/base/regmap/ |
5551 | F: include/linux/regmap.h | 5551 | F: include/linux/regmap.h |
5552 | 5552 | ||
5553 | REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM | ||
5554 | M: Ohad Ben-Cohen <ohad@wizery.com> | ||
5555 | S: Maintained | ||
5556 | F: drivers/remoteproc/ | ||
5557 | F: Documentation/remoteproc.txt | ||
5558 | F: include/linux/remoteproc.txt | ||
5559 | |||
5553 | RFKILL | 5560 | RFKILL |
5554 | M: Johannes Berg <johannes@sipsolutions.net> | 5561 | M: Johannes Berg <johannes@sipsolutions.net> |
5555 | L: linux-wireless@vger.kernel.org | 5562 | L: linux-wireless@vger.kernel.org |
diff --git a/arch/arm/plat-omap/include/plat/remoteproc.h b/arch/arm/plat-omap/include/plat/remoteproc.h new file mode 100644 index 000000000000..b10eac89e2e9 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/remoteproc.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Remote Processor - omap-specific bits | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _PLAT_REMOTEPROC_H | ||
18 | #define _PLAT_REMOTEPROC_H | ||
19 | |||
20 | struct rproc_ops; | ||
21 | struct platform_device; | ||
22 | |||
23 | /* | ||
24 | * struct omap_rproc_pdata - omap remoteproc's platform data | ||
25 | * @name: the remoteproc's name | ||
26 | * @oh_name: omap hwmod device | ||
27 | * @oh_name_opt: optional, secondary omap hwmod device | ||
28 | * @firmware: name of firmware file to load | ||
29 | * @mbox_name: name of omap mailbox device to use with this rproc | ||
30 | * @ops: start/stop rproc handlers | ||
31 | * @device_enable: omap-specific handler for enabling a device | ||
32 | * @device_shutdown: omap-specific handler for shutting down a device | ||
33 | */ | ||
34 | struct omap_rproc_pdata { | ||
35 | const char *name; | ||
36 | const char *oh_name; | ||
37 | const char *oh_name_opt; | ||
38 | const char *firmware; | ||
39 | const char *mbox_name; | ||
40 | const struct rproc_ops *ops; | ||
41 | int (*device_enable) (struct platform_device *pdev); | ||
42 | int (*device_shutdown) (struct platform_device *pdev); | ||
43 | }; | ||
44 | |||
45 | #if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE) | ||
46 | |||
47 | void __init omap_rproc_reserve_cma(void); | ||
48 | |||
49 | #else | ||
50 | |||
51 | void __init omap_rproc_reserve_cma(void) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | #endif | ||
56 | |||
57 | #endif /* _PLAT_REMOTEPROC_H */ | ||
diff --git a/drivers/Kconfig b/drivers/Kconfig index 5afe5d1f199b..516faf6d88ba 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -132,6 +132,10 @@ source "drivers/clocksource/Kconfig" | |||
132 | 132 | ||
133 | source "drivers/iommu/Kconfig" | 133 | source "drivers/iommu/Kconfig" |
134 | 134 | ||
135 | source "drivers/remoteproc/Kconfig" | ||
136 | |||
137 | source "drivers/rpmsg/Kconfig" | ||
138 | |||
135 | source "drivers/virt/Kconfig" | 139 | source "drivers/virt/Kconfig" |
136 | 140 | ||
137 | source "drivers/devfreq/Kconfig" | 141 | source "drivers/devfreq/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index c07be024b962..3fdc17709d36 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -126,6 +126,8 @@ obj-y += clk/ | |||
126 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ | 126 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ |
127 | obj-$(CONFIG_NFC) += nfc/ | 127 | obj-$(CONFIG_NFC) += nfc/ |
128 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | 128 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ |
129 | obj-$(CONFIG_REMOTEPROC) += remoteproc/ | ||
130 | obj-$(CONFIG_RPMSG) += rpmsg/ | ||
129 | 131 | ||
130 | # Virtualization drivers | 132 | # Virtualization drivers |
131 | obj-$(CONFIG_VIRT_DRIVERS) += virt/ | 133 | obj-$(CONFIG_VIRT_DRIVERS) += virt/ |
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig new file mode 100644 index 000000000000..25fc4ccbc2ea --- /dev/null +++ b/drivers/remoteproc/Kconfig | |||
@@ -0,0 +1,29 @@ | |||
1 | menu "Remoteproc drivers (EXPERIMENTAL)" | ||
2 | |||
3 | # REMOTEPROC gets selected by whoever wants it | ||
4 | config REMOTEPROC | ||
5 | tristate | ||
6 | depends on EXPERIMENTAL | ||
7 | |||
8 | config OMAP_REMOTEPROC | ||
9 | tristate "OMAP remoteproc support" | ||
10 | depends on ARCH_OMAP4 | ||
11 | select OMAP_IOMMU | ||
12 | select REMOTEPROC | ||
13 | select OMAP_MBOX_FWK | ||
14 | select RPMSG | ||
15 | default m | ||
16 | help | ||
17 | Say y here to support OMAP's remote processors (dual M3 | ||
18 | and DSP on OMAP4) via the remote processor framework. | ||
19 | |||
20 | Currently only supported on OMAP4. | ||
21 | |||
22 | Usually you want to say y here, in order to enable multimedia | ||
23 | use-cases to run on your platform (multimedia codecs are | ||
24 | offloaded to remote DSP processors using this framework). | ||
25 | |||
26 | It's safe to say n here if you're not interested in multimedia | ||
27 | offloading or just want a bare minimum kernel. | ||
28 | |||
29 | endmenu | ||
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile new file mode 100644 index 000000000000..df0897f69e16 --- /dev/null +++ b/drivers/remoteproc/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # | ||
2 | # Generic framework for controlling remote processors | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_REMOTEPROC) += remoteproc.o | ||
6 | remoteproc-y := remoteproc_core.o | ||
7 | remoteproc-y += remoteproc_debugfs.o | ||
8 | remoteproc-y += remoteproc_rpmsg.o | ||
9 | obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o | ||
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c new file mode 100644 index 000000000000..aa3ce52dc65e --- /dev/null +++ b/drivers/remoteproc/omap_remoteproc.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * OMAP Remote Processor driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * Fernando Guzman Lugo <fernando.lugo@ti.com> | ||
10 | * Mark Grosen <mgrosen@ti.com> | ||
11 | * Suman Anna <s-anna@ti.com> | ||
12 | * Hari Kanigeri <h-kanigeri2@ti.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * version 2 as published by the Free Software Foundation. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/dma-mapping.h> | ||
29 | #include <linux/remoteproc.h> | ||
30 | |||
31 | #include <plat/mailbox.h> | ||
32 | #include <plat/remoteproc.h> | ||
33 | |||
34 | #include "omap_remoteproc.h" | ||
35 | #include "remoteproc_internal.h" | ||
36 | |||
37 | /** | ||
38 | * struct omap_rproc - omap remote processor state | ||
39 | * @mbox: omap mailbox handle | ||
40 | * @nb: notifier block that will be invoked on inbound mailbox messages | ||
41 | * @rproc: rproc handle | ||
42 | */ | ||
43 | struct omap_rproc { | ||
44 | struct omap_mbox *mbox; | ||
45 | struct notifier_block nb; | ||
46 | struct rproc *rproc; | ||
47 | }; | ||
48 | |||
49 | /** | ||
50 | * omap_rproc_mbox_callback() - inbound mailbox message handler | ||
51 | * @this: notifier block | ||
52 | * @index: unused | ||
53 | * @data: mailbox payload | ||
54 | * | ||
55 | * This handler is invoked by omap's mailbox driver whenever a mailbox | ||
56 | * message is received. Usually, the mailbox payload simply contains | ||
57 | * the index of the virtqueue that is kicked by the remote processor, | ||
58 | * and we let remoteproc core handle it. | ||
59 | * | ||
60 | * In addition to virtqueue indices, we also have some out-of-band values | ||
61 | * that indicates different events. Those values are deliberately very | ||
62 | * big so they don't coincide with virtqueue indices. | ||
63 | */ | ||
64 | static int omap_rproc_mbox_callback(struct notifier_block *this, | ||
65 | unsigned long index, void *data) | ||
66 | { | ||
67 | mbox_msg_t msg = (mbox_msg_t) data; | ||
68 | struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb); | ||
69 | struct device *dev = oproc->rproc->dev; | ||
70 | const char *name = oproc->rproc->name; | ||
71 | |||
72 | dev_dbg(dev, "mbox msg: 0x%x\n", msg); | ||
73 | |||
74 | switch (msg) { | ||
75 | case RP_MBOX_CRASH: | ||
76 | /* just log this for now. later, we'll also do recovery */ | ||
77 | dev_err(dev, "omap rproc %s crashed\n", name); | ||
78 | break; | ||
79 | case RP_MBOX_ECHO_REPLY: | ||
80 | dev_info(dev, "received echo reply from %s\n", name); | ||
81 | break; | ||
82 | default: | ||
83 | /* ignore vq indices which are too large to be valid */ | ||
84 | if (msg >= 2) { | ||
85 | dev_warn(dev, "invalid mbox msg: 0x%x\n", msg); | ||
86 | break; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * At this point, 'msg' contains the index of the vring | ||
91 | * which was just triggered. | ||
92 | */ | ||
93 | if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE) | ||
94 | dev_dbg(dev, "no message was found in vqid %d\n", msg); | ||
95 | } | ||
96 | |||
97 | return NOTIFY_DONE; | ||
98 | } | ||
99 | |||
100 | /* kick a virtqueue */ | ||
101 | static void omap_rproc_kick(struct rproc *rproc, int vqid) | ||
102 | { | ||
103 | struct omap_rproc *oproc = rproc->priv; | ||
104 | int ret; | ||
105 | |||
106 | /* send the index of the triggered virtqueue in the mailbox payload */ | ||
107 | ret = omap_mbox_msg_send(oproc->mbox, vqid); | ||
108 | if (ret) | ||
109 | dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret); | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Power up the remote processor. | ||
114 | * | ||
115 | * This function will be invoked only after the firmware for this rproc | ||
116 | * was loaded, parsed successfully, and all of its resource requirements | ||
117 | * were met. | ||
118 | */ | ||
119 | static int omap_rproc_start(struct rproc *rproc) | ||
120 | { | ||
121 | struct omap_rproc *oproc = rproc->priv; | ||
122 | struct platform_device *pdev = to_platform_device(rproc->dev); | ||
123 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
124 | int ret; | ||
125 | |||
126 | oproc->nb.notifier_call = omap_rproc_mbox_callback; | ||
127 | |||
128 | /* every omap rproc is assigned a mailbox instance for messaging */ | ||
129 | oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb); | ||
130 | if (IS_ERR(oproc->mbox)) { | ||
131 | ret = PTR_ERR(oproc->mbox); | ||
132 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Ping the remote processor. this is only for sanity-sake; | ||
138 | * there is no functional effect whatsoever. | ||
139 | * | ||
140 | * Note that the reply will _not_ arrive immediately: this message | ||
141 | * will wait in the mailbox fifo until the remote processor is booted. | ||
142 | */ | ||
143 | ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST); | ||
144 | if (ret) { | ||
145 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | ||
146 | goto put_mbox; | ||
147 | } | ||
148 | |||
149 | ret = pdata->device_enable(pdev); | ||
150 | if (ret) { | ||
151 | dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret); | ||
152 | goto put_mbox; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | put_mbox: | ||
158 | omap_mbox_put(oproc->mbox, &oproc->nb); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | /* power off the remote processor */ | ||
163 | static int omap_rproc_stop(struct rproc *rproc) | ||
164 | { | ||
165 | struct platform_device *pdev = to_platform_device(rproc->dev); | ||
166 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
167 | struct omap_rproc *oproc = rproc->priv; | ||
168 | int ret; | ||
169 | |||
170 | ret = pdata->device_shutdown(pdev); | ||
171 | if (ret) | ||
172 | return ret; | ||
173 | |||
174 | omap_mbox_put(oproc->mbox, &oproc->nb); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static struct rproc_ops omap_rproc_ops = { | ||
180 | .start = omap_rproc_start, | ||
181 | .stop = omap_rproc_stop, | ||
182 | .kick = omap_rproc_kick, | ||
183 | }; | ||
184 | |||
185 | static int __devinit omap_rproc_probe(struct platform_device *pdev) | ||
186 | { | ||
187 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
188 | struct omap_rproc *oproc; | ||
189 | struct rproc *rproc; | ||
190 | int ret; | ||
191 | |||
192 | ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | ||
193 | if (ret) { | ||
194 | dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops, | ||
199 | pdata->firmware, sizeof(*oproc)); | ||
200 | if (!rproc) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | oproc = rproc->priv; | ||
204 | oproc->rproc = rproc; | ||
205 | |||
206 | platform_set_drvdata(pdev, rproc); | ||
207 | |||
208 | ret = rproc_register(rproc); | ||
209 | if (ret) | ||
210 | goto free_rproc; | ||
211 | |||
212 | return 0; | ||
213 | |||
214 | free_rproc: | ||
215 | rproc_free(rproc); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static int __devexit omap_rproc_remove(struct platform_device *pdev) | ||
220 | { | ||
221 | struct rproc *rproc = platform_get_drvdata(pdev); | ||
222 | |||
223 | return rproc_unregister(rproc); | ||
224 | } | ||
225 | |||
226 | static struct platform_driver omap_rproc_driver = { | ||
227 | .probe = omap_rproc_probe, | ||
228 | .remove = __devexit_p(omap_rproc_remove), | ||
229 | .driver = { | ||
230 | .name = "omap-rproc", | ||
231 | .owner = THIS_MODULE, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | module_platform_driver(omap_rproc_driver); | ||
236 | |||
237 | MODULE_LICENSE("GPL v2"); | ||
238 | MODULE_DESCRIPTION("OMAP Remote Processor control driver"); | ||
diff --git a/drivers/remoteproc/omap_remoteproc.h b/drivers/remoteproc/omap_remoteproc.h new file mode 100644 index 000000000000..f6d2036d383d --- /dev/null +++ b/drivers/remoteproc/omap_remoteproc.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Remote processor messaging | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * * Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * * Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * * Neither the name Texas Instruments nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _OMAP_RPMSG_H | ||
36 | #define _OMAP_RPMSG_H | ||
37 | |||
38 | /* | ||
39 | * enum - Predefined Mailbox Messages | ||
40 | * | ||
41 | * @RP_MBOX_READY: informs the M3's that we're up and running. this is | ||
42 | * part of the init sequence sent that the M3 expects to see immediately | ||
43 | * after it is booted. | ||
44 | * | ||
45 | * @RP_MBOX_PENDING_MSG: informs the receiver that there is an inbound | ||
46 | * message waiting in its own receive-side vring. please note that currently | ||
47 | * this message is optional: alternatively, one can explicitly send the index | ||
48 | * of the triggered virtqueue itself. the preferred approach will be decided | ||
49 | * as we progress and experiment with those two different approaches. | ||
50 | * | ||
51 | * @RP_MBOX_CRASH: this message is sent if BIOS crashes | ||
52 | * | ||
53 | * @RP_MBOX_ECHO_REQUEST: a mailbox-level "ping" message. | ||
54 | * | ||
55 | * @RP_MBOX_ECHO_REPLY: a mailbox-level reply to a "ping" | ||
56 | * | ||
57 | * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the | ||
58 | * recovery mechanism (to some extent). | ||
59 | */ | ||
60 | enum omap_rp_mbox_messages { | ||
61 | RP_MBOX_READY = 0xFFFFFF00, | ||
62 | RP_MBOX_PENDING_MSG = 0xFFFFFF01, | ||
63 | RP_MBOX_CRASH = 0xFFFFFF02, | ||
64 | RP_MBOX_ECHO_REQUEST = 0xFFFFFF03, | ||
65 | RP_MBOX_ECHO_REPLY = 0xFFFFFF04, | ||
66 | RP_MBOX_ABORT_REQUEST = 0xFFFFFF05, | ||
67 | }; | ||
68 | |||
69 | #endif /* _OMAP_RPMSG_H */ | ||
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c new file mode 100644 index 000000000000..729911b67a9a --- /dev/null +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -0,0 +1,1450 @@ | |||
1 | /* | ||
2 | * Remote Processor Framework | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * Mark Grosen <mgrosen@ti.com> | ||
10 | * Fernando Guzman Lugo <fernando.lugo@ti.com> | ||
11 | * Suman Anna <s-anna@ti.com> | ||
12 | * Robert Tivy <rtivy@ti.com> | ||
13 | * Armando Uribe De Leon <x0095078@ti.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * version 2 as published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/firmware.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/debugfs.h> | ||
36 | #include <linux/remoteproc.h> | ||
37 | #include <linux/iommu.h> | ||
38 | #include <linux/klist.h> | ||
39 | #include <linux/elf.h> | ||
40 | #include <linux/virtio_ids.h> | ||
41 | #include <linux/virtio_ring.h> | ||
42 | #include <asm/byteorder.h> | ||
43 | |||
44 | #include "remoteproc_internal.h" | ||
45 | |||
46 | static void klist_rproc_get(struct klist_node *n); | ||
47 | static void klist_rproc_put(struct klist_node *n); | ||
48 | |||
49 | /* | ||
50 | * klist of the available remote processors. | ||
51 | * | ||
52 | * We need this in order to support name-based lookups (needed by the | ||
53 | * rproc_get_by_name()). | ||
54 | * | ||
55 | * That said, we don't use rproc_get_by_name() anymore within the rpmsg | ||
56 | * framework. The use cases that do require its existence should be | ||
57 | * scrutinized, and hopefully migrated to rproc_boot() using device-based | ||
58 | * binding. | ||
59 | * | ||
60 | * If/when this materializes, we could drop the klist (and the by_name | ||
61 | * API). | ||
62 | */ | ||
63 | static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put); | ||
64 | |||
65 | typedef int (*rproc_handle_resources_t)(struct rproc *rproc, | ||
66 | struct fw_resource *rsc, int len); | ||
67 | typedef int (*rproc_handle_resource_t)(struct rproc *rproc, | ||
68 | struct fw_resource *rsc); | ||
69 | |||
70 | /* | ||
71 | * This is the IOMMU fault handler we register with the IOMMU API | ||
72 | * (when relevant; not all remote processors access memory through | ||
73 | * an IOMMU). | ||
74 | * | ||
75 | * IOMMU core will invoke this handler whenever the remote processor | ||
76 | * will try to access an unmapped device address. | ||
77 | * | ||
78 | * Currently this is mostly a stub, but it will be later used to trigger | ||
79 | * the recovery of the remote processor. | ||
80 | */ | ||
81 | static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, | ||
82 | unsigned long iova, int flags) | ||
83 | { | ||
84 | dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags); | ||
85 | |||
86 | /* | ||
87 | * Let the iommu core know we're not really handling this fault; | ||
88 | * we just plan to use this as a recovery trigger. | ||
89 | */ | ||
90 | return -ENOSYS; | ||
91 | } | ||
92 | |||
93 | static int rproc_enable_iommu(struct rproc *rproc) | ||
94 | { | ||
95 | struct iommu_domain *domain; | ||
96 | struct device *dev = rproc->dev; | ||
97 | int ret; | ||
98 | |||
99 | /* | ||
100 | * We currently use iommu_present() to decide if an IOMMU | ||
101 | * setup is needed. | ||
102 | * | ||
103 | * This works for simple cases, but will easily fail with | ||
104 | * platforms that do have an IOMMU, but not for this specific | ||
105 | * rproc. | ||
106 | * | ||
107 | * This will be easily solved by introducing hw capabilities | ||
108 | * that will be set by the remoteproc driver. | ||
109 | */ | ||
110 | if (!iommu_present(dev->bus)) { | ||
111 | dev_dbg(dev, "iommu not found\n"); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | domain = iommu_domain_alloc(dev->bus); | ||
116 | if (!domain) { | ||
117 | dev_err(dev, "can't alloc iommu domain\n"); | ||
118 | return -ENOMEM; | ||
119 | } | ||
120 | |||
121 | iommu_set_fault_handler(domain, rproc_iommu_fault); | ||
122 | |||
123 | ret = iommu_attach_device(domain, dev); | ||
124 | if (ret) { | ||
125 | dev_err(dev, "can't attach iommu device: %d\n", ret); | ||
126 | goto free_domain; | ||
127 | } | ||
128 | |||
129 | rproc->domain = domain; | ||
130 | |||
131 | return 0; | ||
132 | |||
133 | free_domain: | ||
134 | iommu_domain_free(domain); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static void rproc_disable_iommu(struct rproc *rproc) | ||
139 | { | ||
140 | struct iommu_domain *domain = rproc->domain; | ||
141 | struct device *dev = rproc->dev; | ||
142 | |||
143 | if (!domain) | ||
144 | return; | ||
145 | |||
146 | iommu_detach_device(domain, dev); | ||
147 | iommu_domain_free(domain); | ||
148 | |||
149 | return; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Some remote processors will ask us to allocate them physically contiguous | ||
154 | * memory regions (which we call "carveouts"), and map them to specific | ||
155 | * device addresses (which are hardcoded in the firmware). | ||
156 | * | ||
157 | * They may then ask us to copy objects into specific device addresses (e.g. | ||
158 | * code/data sections) or expose us certain symbols in other device address | ||
159 | * (e.g. their trace buffer). | ||
160 | * | ||
161 | * This function is an internal helper with which we can go over the allocated | ||
162 | * carveouts and translate specific device address to kernel virtual addresses | ||
163 | * so we can access the referenced memory. | ||
164 | * | ||
165 | * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too, | ||
166 | * but only on kernel direct mapped RAM memory. Instead, we're just using | ||
167 | * here the output of the DMA API, which should be more correct. | ||
168 | */ | ||
169 | static void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) | ||
170 | { | ||
171 | struct rproc_mem_entry *carveout; | ||
172 | void *ptr = NULL; | ||
173 | |||
174 | list_for_each_entry(carveout, &rproc->carveouts, node) { | ||
175 | int offset = da - carveout->da; | ||
176 | |||
177 | /* try next carveout if da is too small */ | ||
178 | if (offset < 0) | ||
179 | continue; | ||
180 | |||
181 | /* try next carveout if da is too large */ | ||
182 | if (offset + len > carveout->len) | ||
183 | continue; | ||
184 | |||
185 | ptr = carveout->va + offset; | ||
186 | |||
187 | break; | ||
188 | } | ||
189 | |||
190 | return ptr; | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * rproc_load_segments() - load firmware segments to memory | ||
195 | * @rproc: remote processor which will be booted using these fw segments | ||
196 | * @elf_data: the content of the ELF firmware image | ||
197 | * @len: firmware size (in bytes) | ||
198 | * | ||
199 | * This function loads the firmware segments to memory, where the remote | ||
200 | * processor expects them. | ||
201 | * | ||
202 | * Some remote processors will expect their code and data to be placed | ||
203 | * in specific device addresses, and can't have them dynamically assigned. | ||
204 | * | ||
205 | * We currently support only those kind of remote processors, and expect | ||
206 | * the program header's paddr member to contain those addresses. We then go | ||
207 | * through the physically contiguous "carveout" memory regions which we | ||
208 | * allocated (and mapped) earlier on behalf of the remote processor, | ||
209 | * and "translate" device address to kernel addresses, so we can copy the | ||
210 | * segments where they are expected. | ||
211 | * | ||
212 | * Currently we only support remote processors that required carveout | ||
213 | * allocations and got them mapped onto their iommus. Some processors | ||
214 | * might be different: they might not have iommus, and would prefer to | ||
215 | * directly allocate memory for every segment/resource. This is not yet | ||
216 | * supported, though. | ||
217 | */ | ||
218 | static int | ||
219 | rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) | ||
220 | { | ||
221 | struct device *dev = rproc->dev; | ||
222 | struct elf32_hdr *ehdr; | ||
223 | struct elf32_phdr *phdr; | ||
224 | int i, ret = 0; | ||
225 | |||
226 | ehdr = (struct elf32_hdr *)elf_data; | ||
227 | phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff); | ||
228 | |||
229 | /* go through the available ELF segments */ | ||
230 | for (i = 0; i < ehdr->e_phnum; i++, phdr++) { | ||
231 | u32 da = phdr->p_paddr; | ||
232 | u32 memsz = phdr->p_memsz; | ||
233 | u32 filesz = phdr->p_filesz; | ||
234 | u32 offset = phdr->p_offset; | ||
235 | void *ptr; | ||
236 | |||
237 | if (phdr->p_type != PT_LOAD) | ||
238 | continue; | ||
239 | |||
240 | dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", | ||
241 | phdr->p_type, da, memsz, filesz); | ||
242 | |||
243 | if (filesz > memsz) { | ||
244 | dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", | ||
245 | filesz, memsz); | ||
246 | ret = -EINVAL; | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | if (offset + filesz > len) { | ||
251 | dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", | ||
252 | offset + filesz, len); | ||
253 | ret = -EINVAL; | ||
254 | break; | ||
255 | } | ||
256 | |||
257 | /* grab the kernel address for this device address */ | ||
258 | ptr = rproc_da_to_va(rproc, da, memsz); | ||
259 | if (!ptr) { | ||
260 | dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz); | ||
261 | ret = -EINVAL; | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | /* put the segment where the remote processor expects it */ | ||
266 | if (phdr->p_filesz) | ||
267 | memcpy(ptr, elf_data + phdr->p_offset, filesz); | ||
268 | |||
269 | /* | ||
270 | * Zero out remaining memory for this segment. | ||
271 | * | ||
272 | * This isn't strictly required since dma_alloc_coherent already | ||
273 | * did this for us. albeit harmless, we may consider removing | ||
274 | * this. | ||
275 | */ | ||
276 | if (memsz > filesz) | ||
277 | memset(ptr + filesz, 0, memsz - filesz); | ||
278 | } | ||
279 | |||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * rproc_handle_virtio_hdr() - handle a virtio header resource | ||
285 | * @rproc: the remote processor | ||
286 | * @rsc: the resource descriptor | ||
287 | * | ||
288 | * The existence of this virtio hdr resource entry means that the firmware | ||
289 | * of this @rproc supports this virtio device. | ||
290 | * | ||
291 | * Currently we support only a single virtio device of type VIRTIO_ID_RPMSG, | ||
292 | * but the plan is to remove this limitation and support any number | ||
293 | * of virtio devices (and of any type). We'll also add support for dynamically | ||
294 | * adding (and removing) virtio devices over the rpmsg bus, but small | ||
295 | * firmwares that doesn't want to get involved with rpmsg will be able | ||
296 | * to simple use the resource table for this. | ||
297 | * | ||
298 | * At this point this virtio header entry is rather simple: it just | ||
299 | * announces the virtio device id and the supported virtio device features. | ||
300 | * The plan though is to extend this to include the vring information and | ||
301 | * the virtio config space, too (but first, some resource table overhaul | ||
302 | * is needed: move from fixed-sized to variable-length TLV entries). | ||
303 | * | ||
304 | * For now, the 'flags' member of the resource entry contains the virtio | ||
305 | * device id, the 'da' member contains the device features, and 'pa' is | ||
306 | * where we need to store the guest features once negotiation completes. | ||
307 | * As usual, the 'id' member of this resource contains the index of this | ||
308 | * resource type (i.e. is this the first virtio hdr entry, the 2nd, ...). | ||
309 | * | ||
310 | * Returns 0 on success, or an appropriate error code otherwise | ||
311 | */ | ||
312 | static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc) | ||
313 | { | ||
314 | struct rproc_vdev *rvdev; | ||
315 | |||
316 | /* we only support VIRTIO_ID_RPMSG devices for now */ | ||
317 | if (rsc->flags != VIRTIO_ID_RPMSG) { | ||
318 | dev_warn(rproc->dev, "unsupported vdev: %d\n", rsc->flags); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | /* we only support a single vdev per rproc for now */ | ||
323 | if (rsc->id || rproc->rvdev) { | ||
324 | dev_warn(rproc->dev, "redundant vdev entry: %s\n", rsc->name); | ||
325 | return -EINVAL; | ||
326 | } | ||
327 | |||
328 | rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL); | ||
329 | if (!rvdev) | ||
330 | return -ENOMEM; | ||
331 | |||
332 | /* remember the device features */ | ||
333 | rvdev->dfeatures = rsc->da; | ||
334 | |||
335 | rproc->rvdev = rvdev; | ||
336 | rvdev->rproc = rproc; | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * rproc_handle_vring() - handle a vring fw resource | ||
343 | * @rproc: the remote processor | ||
344 | * @rsc: the vring resource descriptor | ||
345 | * | ||
346 | * This resource entry requires allocation of non-cacheable memory | ||
347 | * for a virtio vring. Currently we only support two vrings per remote | ||
348 | * processor, required for the virtio rpmsg device. | ||
349 | * | ||
350 | * The 'len' member of @rsc should contain the number of buffers this vring | ||
351 | * support and 'da' should either contain the device address where | ||
352 | * the remote processor is expecting the vring, or indicate that | ||
353 | * dynamically allocation of the vring's device address is supported. | ||
354 | * | ||
355 | * Note: 'da' is currently not handled. This will be revised when the generic | ||
356 | * iommu-based DMA API will arrive, or a dynanic & non-iommu use case show | ||
357 | * up. Meanwhile, statically-addressed iommu-based images should use | ||
358 | * RSC_DEVMEM resource entries to map their require 'da' to the physical | ||
359 | * address of their base CMA region. | ||
360 | * | ||
361 | * Returns 0 on success, or an appropriate error code otherwise | ||
362 | */ | ||
363 | static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc) | ||
364 | { | ||
365 | struct device *dev = rproc->dev; | ||
366 | struct rproc_vdev *rvdev = rproc->rvdev; | ||
367 | dma_addr_t dma; | ||
368 | int size, id = rsc->id; | ||
369 | void *va; | ||
370 | |||
371 | /* no vdev is in place ? */ | ||
372 | if (!rvdev) { | ||
373 | dev_err(dev, "vring requested without a virtio dev entry\n"); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | |||
377 | /* the firmware must provide the expected queue size */ | ||
378 | if (!rsc->len) { | ||
379 | dev_err(dev, "missing expected queue size\n"); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | |||
383 | /* we currently support two vrings per rproc (for rx and tx) */ | ||
384 | if (id >= ARRAY_SIZE(rvdev->vring)) { | ||
385 | dev_err(dev, "%s: invalid vring id %d\n", rsc->name, id); | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | /* have we already allocated this vring id ? */ | ||
390 | if (rvdev->vring[id].len) { | ||
391 | dev_err(dev, "%s: duplicated id %d\n", rsc->name, id); | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | /* actual size of vring (in bytes) */ | ||
396 | size = PAGE_ALIGN(vring_size(rsc->len, AMP_VRING_ALIGN)); | ||
397 | |||
398 | /* | ||
399 | * Allocate non-cacheable memory for the vring. In the future | ||
400 | * this call will also configure the IOMMU for us | ||
401 | */ | ||
402 | va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL); | ||
403 | if (!va) { | ||
404 | dev_err(dev, "dma_alloc_coherent failed\n"); | ||
405 | return -ENOMEM; | ||
406 | } | ||
407 | |||
408 | dev_dbg(dev, "vring%d: va %p dma %x qsz %d ring size %x\n", id, va, | ||
409 | dma, rsc->len, size); | ||
410 | |||
411 | rvdev->vring[id].len = rsc->len; | ||
412 | rvdev->vring[id].va = va; | ||
413 | rvdev->vring[id].dma = dma; | ||
414 | |||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | /** | ||
419 | * rproc_handle_trace() - handle a shared trace buffer resource | ||
420 | * @rproc: the remote processor | ||
421 | * @rsc: the trace resource descriptor | ||
422 | * | ||
423 | * In case the remote processor dumps trace logs into memory, | ||
424 | * export it via debugfs. | ||
425 | * | ||
426 | * Currently, the 'da' member of @rsc should contain the device address | ||
427 | * where the remote processor is dumping the traces. Later we could also | ||
428 | * support dynamically allocating this address using the generic | ||
429 | * DMA API (but currently there isn't a use case for that). | ||
430 | * | ||
431 | * Returns 0 on success, or an appropriate error code otherwise | ||
432 | */ | ||
433 | static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc) | ||
434 | { | ||
435 | struct rproc_mem_entry *trace; | ||
436 | struct device *dev = rproc->dev; | ||
437 | void *ptr; | ||
438 | char name[15]; | ||
439 | |||
440 | /* what's the kernel address of this resource ? */ | ||
441 | ptr = rproc_da_to_va(rproc, rsc->da, rsc->len); | ||
442 | if (!ptr) { | ||
443 | dev_err(dev, "erroneous trace resource entry\n"); | ||
444 | return -EINVAL; | ||
445 | } | ||
446 | |||
447 | trace = kzalloc(sizeof(*trace), GFP_KERNEL); | ||
448 | if (!trace) { | ||
449 | dev_err(dev, "kzalloc trace failed\n"); | ||
450 | return -ENOMEM; | ||
451 | } | ||
452 | |||
453 | /* set the trace buffer dma properties */ | ||
454 | trace->len = rsc->len; | ||
455 | trace->va = ptr; | ||
456 | |||
457 | /* make sure snprintf always null terminates, even if truncating */ | ||
458 | snprintf(name, sizeof(name), "trace%d", rproc->num_traces); | ||
459 | |||
460 | /* create the debugfs entry */ | ||
461 | trace->priv = rproc_create_trace_file(name, rproc, trace); | ||
462 | if (!trace->priv) { | ||
463 | trace->va = NULL; | ||
464 | kfree(trace); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | list_add_tail(&trace->node, &rproc->traces); | ||
469 | |||
470 | rproc->num_traces++; | ||
471 | |||
472 | dev_dbg(dev, "%s added: va %p, da 0x%llx, len 0x%x\n", name, ptr, | ||
473 | rsc->da, rsc->len); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * rproc_handle_devmem() - handle devmem resource entry | ||
480 | * @rproc: remote processor handle | ||
481 | * @rsc: the devmem resource entry | ||
482 | * | ||
483 | * Remote processors commonly need to access certain on-chip peripherals. | ||
484 | * | ||
485 | * Some of these remote processors access memory via an iommu device, | ||
486 | * and might require us to configure their iommu before they can access | ||
487 | * the on-chip peripherals they need. | ||
488 | * | ||
489 | * This resource entry is a request to map such a peripheral device. | ||
490 | * | ||
491 | * These devmem entries will contain the physical address of the device in | ||
492 | * the 'pa' member. If a specific device address is expected, then 'da' will | ||
493 | * contain it (currently this is the only use case supported). 'len' will | ||
494 | * contain the size of the physical region we need to map. | ||
495 | * | ||
496 | * Currently we just "trust" those devmem entries to contain valid physical | ||
497 | * addresses, but this is going to change: we want the implementations to | ||
498 | * tell us ranges of physical addresses the firmware is allowed to request, | ||
499 | * and not allow firmwares to request access to physical addresses that | ||
500 | * are outside those ranges. | ||
501 | */ | ||
502 | static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc) | ||
503 | { | ||
504 | struct rproc_mem_entry *mapping; | ||
505 | int ret; | ||
506 | |||
507 | /* no point in handling this resource without a valid iommu domain */ | ||
508 | if (!rproc->domain) | ||
509 | return -EINVAL; | ||
510 | |||
511 | mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); | ||
512 | if (!mapping) { | ||
513 | dev_err(rproc->dev, "kzalloc mapping failed\n"); | ||
514 | return -ENOMEM; | ||
515 | } | ||
516 | |||
517 | ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags); | ||
518 | if (ret) { | ||
519 | dev_err(rproc->dev, "failed to map devmem: %d\n", ret); | ||
520 | goto out; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * We'll need this info later when we'll want to unmap everything | ||
525 | * (e.g. on shutdown). | ||
526 | * | ||
527 | * We can't trust the remote processor not to change the resource | ||
528 | * table, so we must maintain this info independently. | ||
529 | */ | ||
530 | mapping->da = rsc->da; | ||
531 | mapping->len = rsc->len; | ||
532 | list_add_tail(&mapping->node, &rproc->mappings); | ||
533 | |||
534 | dev_dbg(rproc->dev, "mapped devmem pa 0x%llx, da 0x%llx, len 0x%x\n", | ||
535 | rsc->pa, rsc->da, rsc->len); | ||
536 | |||
537 | return 0; | ||
538 | |||
539 | out: | ||
540 | kfree(mapping); | ||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * rproc_handle_carveout() - handle phys contig memory allocation requests | ||
546 | * @rproc: rproc handle | ||
547 | * @rsc: the resource entry | ||
548 | * | ||
549 | * This function will handle firmware requests for allocation of physically | ||
550 | * contiguous memory regions. | ||
551 | * | ||
552 | * These request entries should come first in the firmware's resource table, | ||
553 | * as other firmware entries might request placing other data objects inside | ||
554 | * these memory regions (e.g. data/code segments, trace resource entries, ...). | ||
555 | * | ||
556 | * Allocating memory this way helps utilizing the reserved physical memory | ||
557 | * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries | ||
558 | * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB | ||
559 | * pressure is important; it may have a substantial impact on performance. | ||
560 | */ | ||
561 | static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc) | ||
562 | { | ||
563 | struct rproc_mem_entry *carveout, *mapping; | ||
564 | struct device *dev = rproc->dev; | ||
565 | dma_addr_t dma; | ||
566 | void *va; | ||
567 | int ret; | ||
568 | |||
569 | mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); | ||
570 | if (!mapping) { | ||
571 | dev_err(dev, "kzalloc mapping failed\n"); | ||
572 | return -ENOMEM; | ||
573 | } | ||
574 | |||
575 | carveout = kzalloc(sizeof(*carveout), GFP_KERNEL); | ||
576 | if (!carveout) { | ||
577 | dev_err(dev, "kzalloc carveout failed\n"); | ||
578 | ret = -ENOMEM; | ||
579 | goto free_mapping; | ||
580 | } | ||
581 | |||
582 | va = dma_alloc_coherent(dev, rsc->len, &dma, GFP_KERNEL); | ||
583 | if (!va) { | ||
584 | dev_err(dev, "failed to dma alloc carveout: %d\n", rsc->len); | ||
585 | ret = -ENOMEM; | ||
586 | goto free_carv; | ||
587 | } | ||
588 | |||
589 | dev_dbg(dev, "carveout va %p, dma %x, len 0x%x\n", va, dma, rsc->len); | ||
590 | |||
591 | /* | ||
592 | * Ok, this is non-standard. | ||
593 | * | ||
594 | * Sometimes we can't rely on the generic iommu-based DMA API | ||
595 | * to dynamically allocate the device address and then set the IOMMU | ||
596 | * tables accordingly, because some remote processors might | ||
597 | * _require_ us to use hard coded device addresses that their | ||
598 | * firmware was compiled with. | ||
599 | * | ||
600 | * In this case, we must use the IOMMU API directly and map | ||
601 | * the memory to the device address as expected by the remote | ||
602 | * processor. | ||
603 | * | ||
604 | * Obviously such remote processor devices should not be configured | ||
605 | * to use the iommu-based DMA API: we expect 'dma' to contain the | ||
606 | * physical address in this case. | ||
607 | */ | ||
608 | if (rproc->domain) { | ||
609 | ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len, | ||
610 | rsc->flags); | ||
611 | if (ret) { | ||
612 | dev_err(dev, "iommu_map failed: %d\n", ret); | ||
613 | goto dma_free; | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * We'll need this info later when we'll want to unmap | ||
618 | * everything (e.g. on shutdown). | ||
619 | * | ||
620 | * We can't trust the remote processor not to change the | ||
621 | * resource table, so we must maintain this info independently. | ||
622 | */ | ||
623 | mapping->da = rsc->da; | ||
624 | mapping->len = rsc->len; | ||
625 | list_add_tail(&mapping->node, &rproc->mappings); | ||
626 | |||
627 | dev_dbg(dev, "carveout mapped 0x%llx to 0x%x\n", rsc->da, dma); | ||
628 | |||
629 | /* | ||
630 | * Some remote processors might need to know the pa | ||
631 | * even though they are behind an IOMMU. E.g., OMAP4's | ||
632 | * remote M3 processor needs this so it can control | ||
633 | * on-chip hardware accelerators that are not behind | ||
634 | * the IOMMU, and therefor must know the pa. | ||
635 | * | ||
636 | * Generally we don't want to expose physical addresses | ||
637 | * if we don't have to (remote processors are generally | ||
638 | * _not_ trusted), so we might want to do this only for | ||
639 | * remote processor that _must_ have this (e.g. OMAP4's | ||
640 | * dual M3 subsystem). | ||
641 | */ | ||
642 | rsc->pa = dma; | ||
643 | } | ||
644 | |||
645 | carveout->va = va; | ||
646 | carveout->len = rsc->len; | ||
647 | carveout->dma = dma; | ||
648 | carveout->da = rsc->da; | ||
649 | |||
650 | list_add_tail(&carveout->node, &rproc->carveouts); | ||
651 | |||
652 | return 0; | ||
653 | |||
654 | dma_free: | ||
655 | dma_free_coherent(dev, rsc->len, va, dma); | ||
656 | free_carv: | ||
657 | kfree(carveout); | ||
658 | free_mapping: | ||
659 | kfree(mapping); | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * A lookup table for resource handlers. The indices are defined in | ||
665 | * enum fw_resource_type. | ||
666 | */ | ||
667 | static rproc_handle_resource_t rproc_handle_rsc[] = { | ||
668 | [RSC_CARVEOUT] = rproc_handle_carveout, | ||
669 | [RSC_DEVMEM] = rproc_handle_devmem, | ||
670 | [RSC_TRACE] = rproc_handle_trace, | ||
671 | [RSC_VRING] = rproc_handle_vring, | ||
672 | [RSC_VIRTIO_DEV] = NULL, /* handled early upon registration */ | ||
673 | }; | ||
674 | |||
675 | /* handle firmware resource entries before booting the remote processor */ | ||
676 | static int | ||
677 | rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) | ||
678 | { | ||
679 | struct device *dev = rproc->dev; | ||
680 | rproc_handle_resource_t handler; | ||
681 | int ret = 0; | ||
682 | |||
683 | for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) { | ||
684 | dev_dbg(dev, "rsc: type %d, da 0x%llx, pa 0x%llx, len 0x%x, " | ||
685 | "id %d, name %s, flags %x\n", rsc->type, rsc->da, | ||
686 | rsc->pa, rsc->len, rsc->id, rsc->name, rsc->flags); | ||
687 | |||
688 | if (rsc->type >= RSC_LAST) { | ||
689 | dev_warn(dev, "unsupported resource %d\n", rsc->type); | ||
690 | continue; | ||
691 | } | ||
692 | |||
693 | handler = rproc_handle_rsc[rsc->type]; | ||
694 | if (!handler) | ||
695 | continue; | ||
696 | |||
697 | ret = handler(rproc, rsc); | ||
698 | if (ret) | ||
699 | break; | ||
700 | } | ||
701 | |||
702 | return ret; | ||
703 | } | ||
704 | |||
705 | /* handle firmware resource entries while registering the remote processor */ | ||
706 | static int | ||
707 | rproc_handle_virtio_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) | ||
708 | { | ||
709 | struct device *dev = rproc->dev; | ||
710 | int ret = -ENODEV; | ||
711 | |||
712 | for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) | ||
713 | if (rsc->type == RSC_VIRTIO_DEV) { | ||
714 | dev_dbg(dev, "found vdev %d/%s features %llx\n", | ||
715 | rsc->flags, rsc->name, rsc->da); | ||
716 | ret = rproc_handle_virtio_hdr(rproc, rsc); | ||
717 | break; | ||
718 | } | ||
719 | |||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * rproc_handle_resources() - find and handle the resource table | ||
725 | * @rproc: the rproc handle | ||
726 | * @elf_data: the content of the ELF firmware image | ||
727 | * @len: firmware size (in bytes) | ||
728 | * @handler: function that should be used to handle the resource table | ||
729 | * | ||
730 | * This function finds the resource table inside the remote processor's | ||
731 | * firmware, and invoke a user-supplied handler with it (we have two | ||
732 | * possible handlers: one is invoked upon registration of @rproc, | ||
733 | * in order to register the supported virito devices, and the other is | ||
734 | * invoked when @rproc is actually booted). | ||
735 | * | ||
736 | * Currently this function fails if a resource table doesn't exist. | ||
737 | * This restriction will be removed when we'll start supporting remote | ||
738 | * processors that don't need a resource table. | ||
739 | */ | ||
740 | static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data, | ||
741 | size_t len, rproc_handle_resources_t handler) | ||
742 | |||
743 | { | ||
744 | struct elf32_hdr *ehdr; | ||
745 | struct elf32_shdr *shdr; | ||
746 | const char *name_table; | ||
747 | int i, ret = -EINVAL; | ||
748 | |||
749 | ehdr = (struct elf32_hdr *)elf_data; | ||
750 | shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); | ||
751 | name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset; | ||
752 | |||
753 | /* look for the resource table and handle it */ | ||
754 | for (i = 0; i < ehdr->e_shnum; i++, shdr++) { | ||
755 | if (!strcmp(name_table + shdr->sh_name, ".resource_table")) { | ||
756 | struct fw_resource *table = (struct fw_resource *) | ||
757 | (elf_data + shdr->sh_offset); | ||
758 | |||
759 | if (shdr->sh_offset + shdr->sh_size > len) { | ||
760 | dev_err(rproc->dev, | ||
761 | "truncated fw: need 0x%x avail 0x%x\n", | ||
762 | shdr->sh_offset + shdr->sh_size, len); | ||
763 | ret = -EINVAL; | ||
764 | } | ||
765 | |||
766 | ret = handler(rproc, table, shdr->sh_size); | ||
767 | |||
768 | break; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | /** | ||
776 | * rproc_resource_cleanup() - clean up and free all acquired resources | ||
777 | * @rproc: rproc handle | ||
778 | * | ||
779 | * This function will free all resources acquired for @rproc, and it | ||
780 | * is called when @rproc shuts down, or just failed booting. | ||
781 | */ | ||
782 | static void rproc_resource_cleanup(struct rproc *rproc) | ||
783 | { | ||
784 | struct rproc_mem_entry *entry, *tmp; | ||
785 | struct device *dev = rproc->dev; | ||
786 | struct rproc_vdev *rvdev = rproc->rvdev; | ||
787 | int i; | ||
788 | |||
789 | /* clean up debugfs trace entries */ | ||
790 | list_for_each_entry_safe(entry, tmp, &rproc->traces, node) { | ||
791 | rproc_remove_trace_file(entry->priv); | ||
792 | rproc->num_traces--; | ||
793 | list_del(&entry->node); | ||
794 | kfree(entry); | ||
795 | } | ||
796 | |||
797 | /* free the coherent memory allocated for the vrings */ | ||
798 | for (i = 0; rvdev && i < ARRAY_SIZE(rvdev->vring); i++) { | ||
799 | int qsz = rvdev->vring[i].len; | ||
800 | void *va = rvdev->vring[i].va; | ||
801 | int dma = rvdev->vring[i].dma; | ||
802 | |||
803 | /* virtqueue size is expressed in number of buffers supported */ | ||
804 | if (qsz) { | ||
805 | /* how many bytes does this vring really occupy ? */ | ||
806 | int size = PAGE_ALIGN(vring_size(qsz, AMP_VRING_ALIGN)); | ||
807 | |||
808 | dma_free_coherent(rproc->dev, size, va, dma); | ||
809 | |||
810 | rvdev->vring[i].len = 0; | ||
811 | } | ||
812 | } | ||
813 | |||
814 | /* clean up carveout allocations */ | ||
815 | list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) { | ||
816 | dma_free_coherent(dev, entry->len, entry->va, entry->dma); | ||
817 | list_del(&entry->node); | ||
818 | kfree(entry); | ||
819 | } | ||
820 | |||
821 | /* clean up iommu mapping entries */ | ||
822 | list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) { | ||
823 | size_t unmapped; | ||
824 | |||
825 | unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); | ||
826 | if (unmapped != entry->len) { | ||
827 | /* nothing much to do besides complaining */ | ||
828 | dev_err(dev, "failed to unmap %u/%u\n", entry->len, | ||
829 | unmapped); | ||
830 | } | ||
831 | |||
832 | list_del(&entry->node); | ||
833 | kfree(entry); | ||
834 | } | ||
835 | } | ||
836 | |||
837 | /* make sure this fw image is sane */ | ||
838 | static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw) | ||
839 | { | ||
840 | const char *name = rproc->firmware; | ||
841 | struct device *dev = rproc->dev; | ||
842 | struct elf32_hdr *ehdr; | ||
843 | |||
844 | if (!fw) { | ||
845 | dev_err(dev, "failed to load %s\n", name); | ||
846 | return -EINVAL; | ||
847 | } | ||
848 | |||
849 | if (fw->size < sizeof(struct elf32_hdr)) { | ||
850 | dev_err(dev, "Image is too small\n"); | ||
851 | return -EINVAL; | ||
852 | } | ||
853 | |||
854 | ehdr = (struct elf32_hdr *)fw->data; | ||
855 | |||
856 | /* We assume the firmware has the same endianess as the host */ | ||
857 | # ifdef __LITTLE_ENDIAN | ||
858 | if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) { | ||
859 | # else /* BIG ENDIAN */ | ||
860 | if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) { | ||
861 | # endif | ||
862 | dev_err(dev, "Unsupported firmware endianess\n"); | ||
863 | return -EINVAL; | ||
864 | } | ||
865 | |||
866 | if (fw->size < ehdr->e_shoff + sizeof(struct elf32_shdr)) { | ||
867 | dev_err(dev, "Image is too small\n"); | ||
868 | return -EINVAL; | ||
869 | } | ||
870 | |||
871 | if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { | ||
872 | dev_err(dev, "Image is corrupted (bad magic)\n"); | ||
873 | return -EINVAL; | ||
874 | } | ||
875 | |||
876 | if (ehdr->e_phnum == 0) { | ||
877 | dev_err(dev, "No loadable segments\n"); | ||
878 | return -EINVAL; | ||
879 | } | ||
880 | |||
881 | if (ehdr->e_phoff > fw->size) { | ||
882 | dev_err(dev, "Firmware size is too small\n"); | ||
883 | return -EINVAL; | ||
884 | } | ||
885 | |||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | /* | ||
890 | * take a firmware and boot a remote processor with it. | ||
891 | */ | ||
892 | static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) | ||
893 | { | ||
894 | struct device *dev = rproc->dev; | ||
895 | const char *name = rproc->firmware; | ||
896 | struct elf32_hdr *ehdr; | ||
897 | int ret; | ||
898 | |||
899 | ret = rproc_fw_sanity_check(rproc, fw); | ||
900 | if (ret) | ||
901 | return ret; | ||
902 | |||
903 | ehdr = (struct elf32_hdr *)fw->data; | ||
904 | |||
905 | dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); | ||
906 | |||
907 | /* | ||
908 | * if enabling an IOMMU isn't relevant for this rproc, this is | ||
909 | * just a nop | ||
910 | */ | ||
911 | ret = rproc_enable_iommu(rproc); | ||
912 | if (ret) { | ||
913 | dev_err(dev, "can't enable iommu: %d\n", ret); | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * The ELF entry point is the rproc's boot addr (though this is not | ||
919 | * a configurable property of all remote processors: some will always | ||
920 | * boot at a specific hardcoded address). | ||
921 | */ | ||
922 | rproc->bootaddr = ehdr->e_entry; | ||
923 | |||
924 | /* handle fw resources which are required to boot rproc */ | ||
925 | ret = rproc_handle_resources(rproc, fw->data, fw->size, | ||
926 | rproc_handle_boot_rsc); | ||
927 | if (ret) { | ||
928 | dev_err(dev, "Failed to process resources: %d\n", ret); | ||
929 | goto clean_up; | ||
930 | } | ||
931 | |||
932 | /* load the ELF segments to memory */ | ||
933 | ret = rproc_load_segments(rproc, fw->data, fw->size); | ||
934 | if (ret) { | ||
935 | dev_err(dev, "Failed to load program segments: %d\n", ret); | ||
936 | goto clean_up; | ||
937 | } | ||
938 | |||
939 | /* power up the remote processor */ | ||
940 | ret = rproc->ops->start(rproc); | ||
941 | if (ret) { | ||
942 | dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret); | ||
943 | goto clean_up; | ||
944 | } | ||
945 | |||
946 | rproc->state = RPROC_RUNNING; | ||
947 | |||
948 | dev_info(dev, "remote processor %s is now up\n", rproc->name); | ||
949 | |||
950 | return 0; | ||
951 | |||
952 | clean_up: | ||
953 | rproc_resource_cleanup(rproc); | ||
954 | rproc_disable_iommu(rproc); | ||
955 | return ret; | ||
956 | } | ||
957 | |||
958 | /* | ||
959 | * take a firmware and look for virtio devices to register. | ||
960 | * | ||
961 | * Note: this function is called asynchronously upon registration of the | ||
962 | * remote processor (so we must wait until it completes before we try | ||
963 | * to unregister the device. one other option is just to use kref here, | ||
964 | * that might be cleaner). | ||
965 | */ | ||
966 | static void rproc_fw_config_virtio(const struct firmware *fw, void *context) | ||
967 | { | ||
968 | struct rproc *rproc = context; | ||
969 | struct device *dev = rproc->dev; | ||
970 | int ret; | ||
971 | |||
972 | if (rproc_fw_sanity_check(rproc, fw) < 0) | ||
973 | goto out; | ||
974 | |||
975 | /* does the fw supports any virtio devices ? */ | ||
976 | ret = rproc_handle_resources(rproc, fw->data, fw->size, | ||
977 | rproc_handle_virtio_rsc); | ||
978 | if (ret) { | ||
979 | dev_info(dev, "No fw virtio device was found\n"); | ||
980 | goto out; | ||
981 | } | ||
982 | |||
983 | /* add the virtio device (currently only rpmsg vdevs are supported) */ | ||
984 | ret = rproc_add_rpmsg_vdev(rproc); | ||
985 | if (ret) | ||
986 | goto out; | ||
987 | |||
988 | out: | ||
989 | if (fw) | ||
990 | release_firmware(fw); | ||
991 | /* allow rproc_unregister() contexts, if any, to proceed */ | ||
992 | complete_all(&rproc->firmware_loading_complete); | ||
993 | } | ||
994 | |||
995 | /** | ||
996 | * rproc_boot() - boot a remote processor | ||
997 | * @rproc: handle of a remote processor | ||
998 | * | ||
999 | * Boot a remote processor (i.e. load its firmware, power it on, ...). | ||
1000 | * | ||
1001 | * If the remote processor is already powered on, this function immediately | ||
1002 | * returns (successfully). | ||
1003 | * | ||
1004 | * Returns 0 on success, and an appropriate error value otherwise. | ||
1005 | */ | ||
1006 | int rproc_boot(struct rproc *rproc) | ||
1007 | { | ||
1008 | const struct firmware *firmware_p; | ||
1009 | struct device *dev; | ||
1010 | int ret; | ||
1011 | |||
1012 | if (!rproc) { | ||
1013 | pr_err("invalid rproc handle\n"); | ||
1014 | return -EINVAL; | ||
1015 | } | ||
1016 | |||
1017 | dev = rproc->dev; | ||
1018 | |||
1019 | ret = mutex_lock_interruptible(&rproc->lock); | ||
1020 | if (ret) { | ||
1021 | dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); | ||
1022 | return ret; | ||
1023 | } | ||
1024 | |||
1025 | /* loading a firmware is required */ | ||
1026 | if (!rproc->firmware) { | ||
1027 | dev_err(dev, "%s: no firmware to load\n", __func__); | ||
1028 | ret = -EINVAL; | ||
1029 | goto unlock_mutex; | ||
1030 | } | ||
1031 | |||
1032 | /* prevent underlying implementation from being removed */ | ||
1033 | if (!try_module_get(dev->driver->owner)) { | ||
1034 | dev_err(dev, "%s: can't get owner\n", __func__); | ||
1035 | ret = -EINVAL; | ||
1036 | goto unlock_mutex; | ||
1037 | } | ||
1038 | |||
1039 | /* skip the boot process if rproc is already powered up */ | ||
1040 | if (atomic_inc_return(&rproc->power) > 1) { | ||
1041 | ret = 0; | ||
1042 | goto unlock_mutex; | ||
1043 | } | ||
1044 | |||
1045 | dev_info(dev, "powering up %s\n", rproc->name); | ||
1046 | |||
1047 | /* load firmware */ | ||
1048 | ret = request_firmware(&firmware_p, rproc->firmware, dev); | ||
1049 | if (ret < 0) { | ||
1050 | dev_err(dev, "request_firmware failed: %d\n", ret); | ||
1051 | goto downref_rproc; | ||
1052 | } | ||
1053 | |||
1054 | ret = rproc_fw_boot(rproc, firmware_p); | ||
1055 | |||
1056 | release_firmware(firmware_p); | ||
1057 | |||
1058 | downref_rproc: | ||
1059 | if (ret) { | ||
1060 | module_put(dev->driver->owner); | ||
1061 | atomic_dec(&rproc->power); | ||
1062 | } | ||
1063 | unlock_mutex: | ||
1064 | mutex_unlock(&rproc->lock); | ||
1065 | return ret; | ||
1066 | } | ||
1067 | EXPORT_SYMBOL(rproc_boot); | ||
1068 | |||
1069 | /** | ||
1070 | * rproc_shutdown() - power off the remote processor | ||
1071 | * @rproc: the remote processor | ||
1072 | * | ||
1073 | * Power off a remote processor (previously booted with rproc_boot()). | ||
1074 | * | ||
1075 | * In case @rproc is still being used by an additional user(s), then | ||
1076 | * this function will just decrement the power refcount and exit, | ||
1077 | * without really powering off the device. | ||
1078 | * | ||
1079 | * Every call to rproc_boot() must (eventually) be accompanied by a call | ||
1080 | * to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug. | ||
1081 | * | ||
1082 | * Notes: | ||
1083 | * - we're not decrementing the rproc's refcount, only the power refcount. | ||
1084 | * which means that the @rproc handle stays valid even after rproc_shutdown() | ||
1085 | * returns, and users can still use it with a subsequent rproc_boot(), if | ||
1086 | * needed. | ||
1087 | * - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly | ||
1088 | * because rproc_shutdown() _does not_ decrement the refcount of @rproc. | ||
1089 | * To decrement the refcount of @rproc, use rproc_put() (but _only_ if | ||
1090 | * you acquired @rproc using rproc_get_by_name()). | ||
1091 | */ | ||
1092 | void rproc_shutdown(struct rproc *rproc) | ||
1093 | { | ||
1094 | struct device *dev = rproc->dev; | ||
1095 | int ret; | ||
1096 | |||
1097 | ret = mutex_lock_interruptible(&rproc->lock); | ||
1098 | if (ret) { | ||
1099 | dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); | ||
1100 | return; | ||
1101 | } | ||
1102 | |||
1103 | /* if the remote proc is still needed, bail out */ | ||
1104 | if (!atomic_dec_and_test(&rproc->power)) | ||
1105 | goto out; | ||
1106 | |||
1107 | /* power off the remote processor */ | ||
1108 | ret = rproc->ops->stop(rproc); | ||
1109 | if (ret) { | ||
1110 | atomic_inc(&rproc->power); | ||
1111 | dev_err(dev, "can't stop rproc: %d\n", ret); | ||
1112 | goto out; | ||
1113 | } | ||
1114 | |||
1115 | /* clean up all acquired resources */ | ||
1116 | rproc_resource_cleanup(rproc); | ||
1117 | |||
1118 | rproc_disable_iommu(rproc); | ||
1119 | |||
1120 | rproc->state = RPROC_OFFLINE; | ||
1121 | |||
1122 | dev_info(dev, "stopped remote processor %s\n", rproc->name); | ||
1123 | |||
1124 | out: | ||
1125 | mutex_unlock(&rproc->lock); | ||
1126 | if (!ret) | ||
1127 | module_put(dev->driver->owner); | ||
1128 | } | ||
1129 | EXPORT_SYMBOL(rproc_shutdown); | ||
1130 | |||
1131 | /** | ||
1132 | * rproc_release() - completely deletes the existence of a remote processor | ||
1133 | * @kref: the rproc's kref | ||
1134 | * | ||
1135 | * This function should _never_ be called directly. | ||
1136 | * | ||
1137 | * The only reasonable location to use it is as an argument when kref_put'ing | ||
1138 | * @rproc's refcount. | ||
1139 | * | ||
1140 | * This way it will be called when no one holds a valid pointer to this @rproc | ||
1141 | * anymore (and obviously after it is removed from the rprocs klist). | ||
1142 | * | ||
1143 | * Note: this function is not static because rproc_vdev_release() needs it when | ||
1144 | * it decrements @rproc's refcount. | ||
1145 | */ | ||
1146 | void rproc_release(struct kref *kref) | ||
1147 | { | ||
1148 | struct rproc *rproc = container_of(kref, struct rproc, refcount); | ||
1149 | |||
1150 | dev_info(rproc->dev, "removing %s\n", rproc->name); | ||
1151 | |||
1152 | rproc_delete_debug_dir(rproc); | ||
1153 | |||
1154 | /* at this point no one holds a reference to rproc anymore */ | ||
1155 | kfree(rproc); | ||
1156 | } | ||
1157 | |||
1158 | /* will be called when an rproc is added to the rprocs klist */ | ||
1159 | static void klist_rproc_get(struct klist_node *n) | ||
1160 | { | ||
1161 | struct rproc *rproc = container_of(n, struct rproc, node); | ||
1162 | |||
1163 | kref_get(&rproc->refcount); | ||
1164 | } | ||
1165 | |||
1166 | /* will be called when an rproc is removed from the rprocs klist */ | ||
1167 | static void klist_rproc_put(struct klist_node *n) | ||
1168 | { | ||
1169 | struct rproc *rproc = container_of(n, struct rproc, node); | ||
1170 | |||
1171 | kref_put(&rproc->refcount, rproc_release); | ||
1172 | } | ||
1173 | |||
1174 | static struct rproc *next_rproc(struct klist_iter *i) | ||
1175 | { | ||
1176 | struct klist_node *n; | ||
1177 | |||
1178 | n = klist_next(i); | ||
1179 | if (!n) | ||
1180 | return NULL; | ||
1181 | |||
1182 | return container_of(n, struct rproc, node); | ||
1183 | } | ||
1184 | |||
1185 | /** | ||
1186 | * rproc_get_by_name() - find a remote processor by name and boot it | ||
1187 | * @name: name of the remote processor | ||
1188 | * | ||
1189 | * Finds an rproc handle using the remote processor's name, and then | ||
1190 | * boot it. If it's already powered on, then just immediately return | ||
1191 | * (successfully). | ||
1192 | * | ||
1193 | * Returns the rproc handle on success, and NULL on failure. | ||
1194 | * | ||
1195 | * This function increments the remote processor's refcount, so always | ||
1196 | * use rproc_put() to decrement it back once rproc isn't needed anymore. | ||
1197 | * | ||
1198 | * Note: currently this function (and its counterpart rproc_put()) are not | ||
1199 | * used anymore by the rpmsg subsystem. We need to scrutinize the use cases | ||
1200 | * that still need them, and see if we can migrate them to use the non | ||
1201 | * name-based boot/shutdown interface. | ||
1202 | */ | ||
1203 | struct rproc *rproc_get_by_name(const char *name) | ||
1204 | { | ||
1205 | struct rproc *rproc; | ||
1206 | struct klist_iter i; | ||
1207 | int ret; | ||
1208 | |||
1209 | /* find the remote processor, and upref its refcount */ | ||
1210 | klist_iter_init(&rprocs, &i); | ||
1211 | while ((rproc = next_rproc(&i)) != NULL) | ||
1212 | if (!strcmp(rproc->name, name)) { | ||
1213 | kref_get(&rproc->refcount); | ||
1214 | break; | ||
1215 | } | ||
1216 | klist_iter_exit(&i); | ||
1217 | |||
1218 | /* can't find this rproc ? */ | ||
1219 | if (!rproc) { | ||
1220 | pr_err("can't find remote processor %s\n", name); | ||
1221 | return NULL; | ||
1222 | } | ||
1223 | |||
1224 | ret = rproc_boot(rproc); | ||
1225 | if (ret < 0) { | ||
1226 | kref_put(&rproc->refcount, rproc_release); | ||
1227 | return NULL; | ||
1228 | } | ||
1229 | |||
1230 | return rproc; | ||
1231 | } | ||
1232 | EXPORT_SYMBOL(rproc_get_by_name); | ||
1233 | |||
1234 | /** | ||
1235 | * rproc_put() - decrement the refcount of a remote processor, and shut it down | ||
1236 | * @rproc: the remote processor | ||
1237 | * | ||
1238 | * This function tries to shutdown @rproc, and it then decrements its | ||
1239 | * refcount. | ||
1240 | * | ||
1241 | * After this function returns, @rproc may _not_ be used anymore, and its | ||
1242 | * handle should be considered invalid. | ||
1243 | * | ||
1244 | * This function should be called _iff_ the @rproc handle was grabbed by | ||
1245 | * calling rproc_get_by_name(). | ||
1246 | */ | ||
1247 | void rproc_put(struct rproc *rproc) | ||
1248 | { | ||
1249 | /* try to power off the remote processor */ | ||
1250 | rproc_shutdown(rproc); | ||
1251 | |||
1252 | /* downref rproc's refcount */ | ||
1253 | kref_put(&rproc->refcount, rproc_release); | ||
1254 | } | ||
1255 | EXPORT_SYMBOL(rproc_put); | ||
1256 | |||
1257 | /** | ||
1258 | * rproc_register() - register a remote processor | ||
1259 | * @rproc: the remote processor handle to register | ||
1260 | * | ||
1261 | * Registers @rproc with the remoteproc framework, after it has been | ||
1262 | * allocated with rproc_alloc(). | ||
1263 | * | ||
1264 | * This is called by the platform-specific rproc implementation, whenever | ||
1265 | * a new remote processor device is probed. | ||
1266 | * | ||
1267 | * Returns 0 on success and an appropriate error code otherwise. | ||
1268 | * | ||
1269 | * Note: this function initiates an asynchronous firmware loading | ||
1270 | * context, which will look for virtio devices supported by the rproc's | ||
1271 | * firmware. | ||
1272 | * | ||
1273 | * If found, those virtio devices will be created and added, so as a result | ||
1274 | * of registering this remote processor, additional virtio drivers will be | ||
1275 | * probed. | ||
1276 | * | ||
1277 | * Currently, though, we only support a single RPMSG virtio vdev per remote | ||
1278 | * processor. | ||
1279 | */ | ||
1280 | int rproc_register(struct rproc *rproc) | ||
1281 | { | ||
1282 | struct device *dev = rproc->dev; | ||
1283 | int ret = 0; | ||
1284 | |||
1285 | /* expose to rproc_get_by_name users */ | ||
1286 | klist_add_tail(&rproc->node, &rprocs); | ||
1287 | |||
1288 | dev_info(rproc->dev, "%s is available\n", rproc->name); | ||
1289 | |||
1290 | dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n"); | ||
1291 | dev_info(dev, "THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.\n"); | ||
1292 | |||
1293 | /* create debugfs entries */ | ||
1294 | rproc_create_debug_dir(rproc); | ||
1295 | |||
1296 | /* rproc_unregister() calls must wait until async loader completes */ | ||
1297 | init_completion(&rproc->firmware_loading_complete); | ||
1298 | |||
1299 | /* | ||
1300 | * We must retrieve early virtio configuration info from | ||
1301 | * the firmware (e.g. whether to register a virtio rpmsg device, | ||
1302 | * what virtio features does it support, ...). | ||
1303 | * | ||
1304 | * We're initiating an asynchronous firmware loading, so we can | ||
1305 | * be built-in kernel code, without hanging the boot process. | ||
1306 | */ | ||
1307 | ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
1308 | rproc->firmware, dev, GFP_KERNEL, | ||
1309 | rproc, rproc_fw_config_virtio); | ||
1310 | if (ret < 0) { | ||
1311 | dev_err(dev, "request_firmware_nowait failed: %d\n", ret); | ||
1312 | complete_all(&rproc->firmware_loading_complete); | ||
1313 | klist_remove(&rproc->node); | ||
1314 | } | ||
1315 | |||
1316 | return ret; | ||
1317 | } | ||
1318 | EXPORT_SYMBOL(rproc_register); | ||
1319 | |||
1320 | /** | ||
1321 | * rproc_alloc() - allocate a remote processor handle | ||
1322 | * @dev: the underlying device | ||
1323 | * @name: name of this remote processor | ||
1324 | * @ops: platform-specific handlers (mainly start/stop) | ||
1325 | * @firmware: name of firmware file to load | ||
1326 | * @len: length of private data needed by the rproc driver (in bytes) | ||
1327 | * | ||
1328 | * Allocates a new remote processor handle, but does not register | ||
1329 | * it yet. | ||
1330 | * | ||
1331 | * This function should be used by rproc implementations during initialization | ||
1332 | * of the remote processor. | ||
1333 | * | ||
1334 | * After creating an rproc handle using this function, and when ready, | ||
1335 | * implementations should then call rproc_register() to complete | ||
1336 | * the registration of the remote processor. | ||
1337 | * | ||
1338 | * On success the new rproc is returned, and on failure, NULL. | ||
1339 | * | ||
1340 | * Note: _never_ directly deallocate @rproc, even if it was not registered | ||
1341 | * yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free(). | ||
1342 | */ | ||
1343 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
1344 | const struct rproc_ops *ops, | ||
1345 | const char *firmware, int len) | ||
1346 | { | ||
1347 | struct rproc *rproc; | ||
1348 | |||
1349 | if (!dev || !name || !ops) | ||
1350 | return NULL; | ||
1351 | |||
1352 | rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL); | ||
1353 | if (!rproc) { | ||
1354 | dev_err(dev, "%s: kzalloc failed\n", __func__); | ||
1355 | return NULL; | ||
1356 | } | ||
1357 | |||
1358 | rproc->dev = dev; | ||
1359 | rproc->name = name; | ||
1360 | rproc->ops = ops; | ||
1361 | rproc->firmware = firmware; | ||
1362 | rproc->priv = &rproc[1]; | ||
1363 | |||
1364 | atomic_set(&rproc->power, 0); | ||
1365 | |||
1366 | kref_init(&rproc->refcount); | ||
1367 | |||
1368 | mutex_init(&rproc->lock); | ||
1369 | |||
1370 | INIT_LIST_HEAD(&rproc->carveouts); | ||
1371 | INIT_LIST_HEAD(&rproc->mappings); | ||
1372 | INIT_LIST_HEAD(&rproc->traces); | ||
1373 | |||
1374 | rproc->state = RPROC_OFFLINE; | ||
1375 | |||
1376 | return rproc; | ||
1377 | } | ||
1378 | EXPORT_SYMBOL(rproc_alloc); | ||
1379 | |||
1380 | /** | ||
1381 | * rproc_free() - free an rproc handle that was allocated by rproc_alloc | ||
1382 | * @rproc: the remote processor handle | ||
1383 | * | ||
1384 | * This function should _only_ be used if @rproc was only allocated, | ||
1385 | * but not registered yet. | ||
1386 | * | ||
1387 | * If @rproc was already successfully registered (by calling rproc_register()), | ||
1388 | * then use rproc_unregister() instead. | ||
1389 | */ | ||
1390 | void rproc_free(struct rproc *rproc) | ||
1391 | { | ||
1392 | kfree(rproc); | ||
1393 | } | ||
1394 | EXPORT_SYMBOL(rproc_free); | ||
1395 | |||
1396 | /** | ||
1397 | * rproc_unregister() - unregister a remote processor | ||
1398 | * @rproc: rproc handle to unregister | ||
1399 | * | ||
1400 | * Unregisters a remote processor, and decrements its refcount. | ||
1401 | * If its refcount drops to zero, then @rproc will be freed. If not, | ||
1402 | * it will be freed later once the last reference is dropped. | ||
1403 | * | ||
1404 | * This function should be called when the platform specific rproc | ||
1405 | * implementation decides to remove the rproc device. it should | ||
1406 | * _only_ be called if a previous invocation of rproc_register() | ||
1407 | * has completed successfully. | ||
1408 | * | ||
1409 | * After rproc_unregister() returns, @rproc is _not_ valid anymore and | ||
1410 | * it shouldn't be used. More specifically, don't call rproc_free() | ||
1411 | * or try to directly free @rproc after rproc_unregister() returns; | ||
1412 | * none of these are needed, and calling them is a bug. | ||
1413 | * | ||
1414 | * Returns 0 on success and -EINVAL if @rproc isn't valid. | ||
1415 | */ | ||
1416 | int rproc_unregister(struct rproc *rproc) | ||
1417 | { | ||
1418 | if (!rproc) | ||
1419 | return -EINVAL; | ||
1420 | |||
1421 | /* if rproc is just being registered, wait */ | ||
1422 | wait_for_completion(&rproc->firmware_loading_complete); | ||
1423 | |||
1424 | /* was an rpmsg vdev created ? */ | ||
1425 | if (rproc->rvdev) | ||
1426 | rproc_remove_rpmsg_vdev(rproc); | ||
1427 | |||
1428 | klist_remove(&rproc->node); | ||
1429 | |||
1430 | kref_put(&rproc->refcount, rproc_release); | ||
1431 | |||
1432 | return 0; | ||
1433 | } | ||
1434 | EXPORT_SYMBOL(rproc_unregister); | ||
1435 | |||
1436 | static int __init remoteproc_init(void) | ||
1437 | { | ||
1438 | rproc_init_debugfs(); | ||
1439 | return 0; | ||
1440 | } | ||
1441 | module_init(remoteproc_init); | ||
1442 | |||
1443 | static void __exit remoteproc_exit(void) | ||
1444 | { | ||
1445 | rproc_exit_debugfs(); | ||
1446 | } | ||
1447 | module_exit(remoteproc_exit); | ||
1448 | |||
1449 | MODULE_LICENSE("GPL v2"); | ||
1450 | MODULE_DESCRIPTION("Generic Remote Processor Framework"); | ||
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c new file mode 100644 index 000000000000..70277a530133 --- /dev/null +++ b/drivers/remoteproc/remoteproc_debugfs.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * Remote Processor Framework | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Mark Grosen <mgrosen@ti.com> | ||
9 | * Brian Swetland <swetland@google.com> | ||
10 | * Fernando Guzman Lugo <fernando.lugo@ti.com> | ||
11 | * Suman Anna <s-anna@ti.com> | ||
12 | * Robert Tivy <rtivy@ti.com> | ||
13 | * Armando Uribe De Leon <x0095078@ti.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * version 2 as published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/debugfs.h> | ||
29 | #include <linux/remoteproc.h> | ||
30 | #include <linux/device.h> | ||
31 | |||
32 | /* remoteproc debugfs parent dir */ | ||
33 | static struct dentry *rproc_dbg; | ||
34 | |||
35 | /* | ||
36 | * Some remote processors may support dumping trace logs into a shared | ||
37 | * memory buffer. We expose this trace buffer using debugfs, so users | ||
38 | * can easily tell what's going on remotely. | ||
39 | * | ||
40 | * We will most probably improve the rproc tracing facilities later on, | ||
41 | * but this kind of lightweight and simple mechanism is always good to have, | ||
42 | * as it provides very early tracing with little to no dependencies at all. | ||
43 | */ | ||
44 | static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, | ||
45 | size_t count, loff_t *ppos) | ||
46 | { | ||
47 | struct rproc_mem_entry *trace = filp->private_data; | ||
48 | int len = strnlen(trace->va, trace->len); | ||
49 | |||
50 | return simple_read_from_buffer(userbuf, count, ppos, trace->va, len); | ||
51 | } | ||
52 | |||
53 | static int rproc_open_generic(struct inode *inode, struct file *file) | ||
54 | { | ||
55 | file->private_data = inode->i_private; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static const struct file_operations trace_rproc_ops = { | ||
61 | .read = rproc_trace_read, | ||
62 | .open = rproc_open_generic, | ||
63 | .llseek = generic_file_llseek, | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * A state-to-string lookup table, for exposing a human readable state | ||
68 | * via debugfs. Always keep in sync with enum rproc_state | ||
69 | */ | ||
70 | static const char * const rproc_state_string[] = { | ||
71 | "offline", | ||
72 | "suspended", | ||
73 | "running", | ||
74 | "crashed", | ||
75 | "invalid", | ||
76 | }; | ||
77 | |||
78 | /* expose the state of the remote processor via debugfs */ | ||
79 | static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, | ||
80 | size_t count, loff_t *ppos) | ||
81 | { | ||
82 | struct rproc *rproc = filp->private_data; | ||
83 | unsigned int state; | ||
84 | char buf[30]; | ||
85 | int i; | ||
86 | |||
87 | state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state; | ||
88 | |||
89 | i = snprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state], | ||
90 | rproc->state); | ||
91 | |||
92 | return simple_read_from_buffer(userbuf, count, ppos, buf, i); | ||
93 | } | ||
94 | |||
95 | static const struct file_operations rproc_state_ops = { | ||
96 | .read = rproc_state_read, | ||
97 | .open = rproc_open_generic, | ||
98 | .llseek = generic_file_llseek, | ||
99 | }; | ||
100 | |||
101 | /* expose the name of the remote processor via debugfs */ | ||
102 | static ssize_t rproc_name_read(struct file *filp, char __user *userbuf, | ||
103 | size_t count, loff_t *ppos) | ||
104 | { | ||
105 | struct rproc *rproc = filp->private_data; | ||
106 | /* need room for the name, a newline and a terminating null */ | ||
107 | char buf[100]; | ||
108 | int i; | ||
109 | |||
110 | i = snprintf(buf, sizeof(buf), "%.98s\n", rproc->name); | ||
111 | |||
112 | return simple_read_from_buffer(userbuf, count, ppos, buf, i); | ||
113 | } | ||
114 | |||
115 | static const struct file_operations rproc_name_ops = { | ||
116 | .read = rproc_name_read, | ||
117 | .open = rproc_open_generic, | ||
118 | .llseek = generic_file_llseek, | ||
119 | }; | ||
120 | |||
121 | void rproc_remove_trace_file(struct dentry *tfile) | ||
122 | { | ||
123 | debugfs_remove(tfile); | ||
124 | } | ||
125 | |||
126 | struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, | ||
127 | struct rproc_mem_entry *trace) | ||
128 | { | ||
129 | struct dentry *tfile; | ||
130 | |||
131 | tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, | ||
132 | trace, &trace_rproc_ops); | ||
133 | if (!tfile) { | ||
134 | dev_err(rproc->dev, "failed to create debugfs trace entry\n"); | ||
135 | return NULL; | ||
136 | } | ||
137 | |||
138 | return tfile; | ||
139 | } | ||
140 | |||
141 | void rproc_delete_debug_dir(struct rproc *rproc) | ||
142 | { | ||
143 | if (!rproc->dbg_dir) | ||
144 | return; | ||
145 | |||
146 | debugfs_remove_recursive(rproc->dbg_dir); | ||
147 | } | ||
148 | |||
149 | void rproc_create_debug_dir(struct rproc *rproc) | ||
150 | { | ||
151 | struct device *dev = rproc->dev; | ||
152 | |||
153 | if (!rproc_dbg) | ||
154 | return; | ||
155 | |||
156 | rproc->dbg_dir = debugfs_create_dir(dev_name(dev), rproc_dbg); | ||
157 | if (!rproc->dbg_dir) | ||
158 | return; | ||
159 | |||
160 | debugfs_create_file("name", 0400, rproc->dbg_dir, | ||
161 | rproc, &rproc_name_ops); | ||
162 | debugfs_create_file("state", 0400, rproc->dbg_dir, | ||
163 | rproc, &rproc_state_ops); | ||
164 | } | ||
165 | |||
166 | void __init rproc_init_debugfs(void) | ||
167 | { | ||
168 | if (debugfs_initialized()) { | ||
169 | rproc_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
170 | if (!rproc_dbg) | ||
171 | pr_err("can't create debugfs dir\n"); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | void __exit rproc_exit_debugfs(void) | ||
176 | { | ||
177 | if (rproc_dbg) | ||
178 | debugfs_remove(rproc_dbg); | ||
179 | } | ||
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h new file mode 100644 index 000000000000..8b2fc40e92d0 --- /dev/null +++ b/drivers/remoteproc/remoteproc_internal.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Remote processor framework | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #ifndef REMOTEPROC_INTERNAL_H | ||
21 | #define REMOTEPROC_INTERNAL_H | ||
22 | |||
23 | #include <linux/irqreturn.h> | ||
24 | |||
25 | struct rproc; | ||
26 | |||
27 | /* from remoteproc_core.c */ | ||
28 | void rproc_release(struct kref *kref); | ||
29 | irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id); | ||
30 | |||
31 | /* from remoteproc_rpmsg.c */ | ||
32 | int rproc_add_rpmsg_vdev(struct rproc *); | ||
33 | void rproc_remove_rpmsg_vdev(struct rproc *rproc); | ||
34 | |||
35 | /* from remoteproc_debugfs.c */ | ||
36 | void rproc_remove_trace_file(struct dentry *tfile); | ||
37 | struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, | ||
38 | struct rproc_mem_entry *trace); | ||
39 | void rproc_delete_debug_dir(struct rproc *rproc); | ||
40 | void rproc_create_debug_dir(struct rproc *rproc); | ||
41 | void rproc_init_debugfs(void); | ||
42 | void rproc_exit_debugfs(void); | ||
43 | |||
44 | #endif /* REMOTEPROC_INTERNAL_H */ | ||
diff --git a/drivers/remoteproc/remoteproc_rpmsg.c b/drivers/remoteproc/remoteproc_rpmsg.c new file mode 100644 index 000000000000..4f73e811bb80 --- /dev/null +++ b/drivers/remoteproc/remoteproc_rpmsg.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | * Remote processor messaging transport (OMAP platform-specific bits) | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/export.h> | ||
21 | #include <linux/remoteproc.h> | ||
22 | #include <linux/rpmsg.h> | ||
23 | #include <linux/virtio.h> | ||
24 | #include <linux/virtio_config.h> | ||
25 | #include <linux/virtio_ids.h> | ||
26 | #include <linux/virtio_ring.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/kref.h> | ||
29 | #include <linux/slab.h> | ||
30 | |||
31 | #include "remoteproc_internal.h" | ||
32 | |||
33 | /** | ||
34 | * struct rproc_virtio_vq_info - virtqueue state | ||
35 | * @vq_id: a unique index of this virtqueue (unique for this @rproc) | ||
36 | * @rproc: handle to the remote processor | ||
37 | * | ||
38 | * Such a struct will be maintained for every virtqueue we're | ||
39 | * using to communicate with the remote processor | ||
40 | */ | ||
41 | struct rproc_virtio_vq_info { | ||
42 | __u16 vq_id; | ||
43 | struct rproc *rproc; | ||
44 | }; | ||
45 | |||
46 | /* kick the remote processor, and let it know which virtqueue to poke at */ | ||
47 | static void rproc_virtio_notify(struct virtqueue *vq) | ||
48 | { | ||
49 | struct rproc_virtio_vq_info *rpvq = vq->priv; | ||
50 | struct rproc *rproc = rpvq->rproc; | ||
51 | |||
52 | dev_dbg(rproc->dev, "kicking vq id: %d\n", rpvq->vq_id); | ||
53 | |||
54 | rproc->ops->kick(rproc, rpvq->vq_id); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted | ||
59 | * @rproc: handle to the remote processor | ||
60 | * @vq_id: index of the signalled virtqueue | ||
61 | * | ||
62 | * This function should be called by the platform-specific rproc driver, | ||
63 | * when the remote processor signals that a specific virtqueue has pending | ||
64 | * messages available. | ||
65 | * | ||
66 | * Returns IRQ_NONE if no message was found in the @vq_id virtqueue, | ||
67 | * and otherwise returns IRQ_HANDLED. | ||
68 | */ | ||
69 | irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id) | ||
70 | { | ||
71 | return vring_interrupt(0, rproc->rvdev->vq[vq_id]); | ||
72 | } | ||
73 | EXPORT_SYMBOL(rproc_vq_interrupt); | ||
74 | |||
75 | static struct virtqueue *rp_find_vq(struct virtio_device *vdev, | ||
76 | unsigned id, | ||
77 | void (*callback)(struct virtqueue *vq), | ||
78 | const char *name) | ||
79 | { | ||
80 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
81 | struct rproc_vdev *rvdev = rproc->rvdev; | ||
82 | struct rproc_virtio_vq_info *rpvq; | ||
83 | struct virtqueue *vq; | ||
84 | void *addr; | ||
85 | int ret, len; | ||
86 | |||
87 | rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL); | ||
88 | if (!rpvq) | ||
89 | return ERR_PTR(-ENOMEM); | ||
90 | |||
91 | rpvq->rproc = rproc; | ||
92 | rpvq->vq_id = id; | ||
93 | |||
94 | addr = rvdev->vring[id].va; | ||
95 | len = rvdev->vring[id].len; | ||
96 | |||
97 | dev_dbg(rproc->dev, "vring%d: va %p qsz %d\n", id, addr, len); | ||
98 | |||
99 | /* | ||
100 | * Create the new vq, and tell virtio we're not interested in | ||
101 | * the 'weak' smp barriers, since we're talking with a real device. | ||
102 | */ | ||
103 | vq = vring_new_virtqueue(len, AMP_VRING_ALIGN, vdev, false, addr, | ||
104 | rproc_virtio_notify, callback, name); | ||
105 | if (!vq) { | ||
106 | dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name); | ||
107 | ret = -ENOMEM; | ||
108 | goto free_rpvq; | ||
109 | } | ||
110 | |||
111 | rvdev->vq[id] = vq; | ||
112 | vq->priv = rpvq; | ||
113 | |||
114 | return vq; | ||
115 | |||
116 | free_rpvq: | ||
117 | kfree(rpvq); | ||
118 | return ERR_PTR(ret); | ||
119 | } | ||
120 | |||
121 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) | ||
122 | { | ||
123 | struct virtqueue *vq, *n; | ||
124 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
125 | |||
126 | list_for_each_entry_safe(vq, n, &vdev->vqs, list) { | ||
127 | struct rproc_virtio_vq_info *rpvq = vq->priv; | ||
128 | vring_del_virtqueue(vq); | ||
129 | kfree(rpvq); | ||
130 | } | ||
131 | |||
132 | /* power down the remote processor */ | ||
133 | rproc_shutdown(rproc); | ||
134 | } | ||
135 | |||
136 | static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, | ||
137 | struct virtqueue *vqs[], | ||
138 | vq_callback_t *callbacks[], | ||
139 | const char *names[]) | ||
140 | { | ||
141 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
142 | int i, ret; | ||
143 | |||
144 | /* we maintain two virtqueues per remote processor (for RX and TX) */ | ||
145 | if (nvqs != 2) | ||
146 | return -EINVAL; | ||
147 | |||
148 | /* boot the remote processor */ | ||
149 | ret = rproc_boot(rproc); | ||
150 | if (ret) { | ||
151 | dev_err(rproc->dev, "rproc_boot() failed %d\n", ret); | ||
152 | goto error; | ||
153 | } | ||
154 | |||
155 | for (i = 0; i < nvqs; ++i) { | ||
156 | vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]); | ||
157 | if (IS_ERR(vqs[i])) { | ||
158 | ret = PTR_ERR(vqs[i]); | ||
159 | goto error; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | |||
165 | error: | ||
166 | rproc_virtio_del_vqs(vdev); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * We don't support yet real virtio status semantics. | ||
172 | * | ||
173 | * The plan is to provide this via the VIRTIO HDR resource entry | ||
174 | * which is part of the firmware: this way the remote processor | ||
175 | * will be able to access the status values as set by us. | ||
176 | */ | ||
177 | static u8 rproc_virtio_get_status(struct virtio_device *vdev) | ||
178 | { | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) | ||
183 | { | ||
184 | dev_dbg(&vdev->dev, "new status: %d\n", status); | ||
185 | } | ||
186 | |||
187 | static void rproc_virtio_reset(struct virtio_device *vdev) | ||
188 | { | ||
189 | dev_dbg(&vdev->dev, "reset !\n"); | ||
190 | } | ||
191 | |||
192 | /* provide the vdev features as retrieved from the firmware */ | ||
193 | static u32 rproc_virtio_get_features(struct virtio_device *vdev) | ||
194 | { | ||
195 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
196 | |||
197 | /* we only support a single vdev device for now */ | ||
198 | return rproc->rvdev->dfeatures; | ||
199 | } | ||
200 | |||
201 | static void rproc_virtio_finalize_features(struct virtio_device *vdev) | ||
202 | { | ||
203 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
204 | |||
205 | /* Give virtio_ring a chance to accept features */ | ||
206 | vring_transport_features(vdev); | ||
207 | |||
208 | /* | ||
209 | * Remember the finalized features of our vdev, and provide it | ||
210 | * to the remote processor once it is powered on. | ||
211 | * | ||
212 | * Similarly to the status field, we don't expose yet the negotiated | ||
213 | * features to the remote processors at this point. This will be | ||
214 | * fixed as part of a small resource table overhaul and then an | ||
215 | * extension of the virtio resource entries. | ||
216 | */ | ||
217 | rproc->rvdev->gfeatures = vdev->features[0]; | ||
218 | } | ||
219 | |||
220 | static struct virtio_config_ops rproc_virtio_config_ops = { | ||
221 | .get_features = rproc_virtio_get_features, | ||
222 | .finalize_features = rproc_virtio_finalize_features, | ||
223 | .find_vqs = rproc_virtio_find_vqs, | ||
224 | .del_vqs = rproc_virtio_del_vqs, | ||
225 | .reset = rproc_virtio_reset, | ||
226 | .set_status = rproc_virtio_set_status, | ||
227 | .get_status = rproc_virtio_get_status, | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * This function is called whenever vdev is released, and is responsible | ||
232 | * to decrement the remote processor's refcount taken when vdev was | ||
233 | * added. | ||
234 | * | ||
235 | * Never call this function directly; it will be called by the driver | ||
236 | * core when needed. | ||
237 | */ | ||
238 | static void rproc_vdev_release(struct device *dev) | ||
239 | { | ||
240 | struct virtio_device *vdev = dev_to_virtio(dev); | ||
241 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
242 | |||
243 | kref_put(&rproc->refcount, rproc_release); | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * rproc_add_rpmsg_vdev() - create an rpmsg virtio device | ||
248 | * @rproc: the rproc handle | ||
249 | * | ||
250 | * This function is called if virtio rpmsg support was found in the | ||
251 | * firmware of the remote processor. | ||
252 | * | ||
253 | * Today we only support creating a single rpmsg vdev (virtio device), | ||
254 | * but the plan is to remove this limitation. At that point this interface | ||
255 | * will be revised/extended. | ||
256 | */ | ||
257 | int rproc_add_rpmsg_vdev(struct rproc *rproc) | ||
258 | { | ||
259 | struct device *dev = rproc->dev; | ||
260 | struct rproc_vdev *rvdev = rproc->rvdev; | ||
261 | int ret; | ||
262 | |||
263 | rvdev->vdev.id.device = VIRTIO_ID_RPMSG, | ||
264 | rvdev->vdev.config = &rproc_virtio_config_ops, | ||
265 | rvdev->vdev.dev.parent = dev; | ||
266 | rvdev->vdev.dev.release = rproc_vdev_release; | ||
267 | |||
268 | /* | ||
269 | * We're indirectly making a non-temporary copy of the rproc pointer | ||
270 | * here, because drivers probed with this vdev will indirectly | ||
271 | * access the wrapping rproc. | ||
272 | * | ||
273 | * Therefore we must increment the rproc refcount here, and decrement | ||
274 | * it _only_ when the vdev is released. | ||
275 | */ | ||
276 | kref_get(&rproc->refcount); | ||
277 | |||
278 | ret = register_virtio_device(&rvdev->vdev); | ||
279 | if (ret) { | ||
280 | kref_put(&rproc->refcount, rproc_release); | ||
281 | dev_err(dev, "failed to register vdev: %d\n", ret); | ||
282 | } | ||
283 | |||
284 | return ret; | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * rproc_remove_rpmsg_vdev() - remove an rpmsg vdev device | ||
289 | * @rproc: the rproc handle | ||
290 | * | ||
291 | * This function is called whenever @rproc is removed _iff_ an rpmsg | ||
292 | * vdev was created beforehand. | ||
293 | */ | ||
294 | void rproc_remove_rpmsg_vdev(struct rproc *rproc) | ||
295 | { | ||
296 | struct rproc_vdev *rvdev = rproc->rvdev; | ||
297 | |||
298 | unregister_virtio_device(&rvdev->vdev); | ||
299 | } | ||
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig new file mode 100644 index 000000000000..32aead65735a --- /dev/null +++ b/drivers/rpmsg/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | menu "Rpmsg drivers (EXPERIMENTAL)" | ||
2 | |||
3 | # RPMSG always gets selected by whoever wants it | ||
4 | config RPMSG | ||
5 | tristate | ||
6 | select VIRTIO | ||
7 | select VIRTIO_RING | ||
8 | depends on EXPERIMENTAL | ||
9 | |||
10 | endmenu | ||
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile new file mode 100644 index 000000000000..7617fcb8259f --- /dev/null +++ b/drivers/rpmsg/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_RPMSG) += virtio_rpmsg_bus.o | |||
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c new file mode 100644 index 000000000000..8980ac2cc546 --- /dev/null +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -0,0 +1,1026 @@ | |||
1 | /* | ||
2 | * Virtio-based remote processor messaging bus | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/virtio.h> | ||
25 | #include <linux/virtio_ids.h> | ||
26 | #include <linux/virtio_config.h> | ||
27 | #include <linux/scatterlist.h> | ||
28 | #include <linux/dma-mapping.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/idr.h> | ||
31 | #include <linux/jiffies.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/wait.h> | ||
34 | #include <linux/rpmsg.h> | ||
35 | #include <linux/mutex.h> | ||
36 | |||
37 | /** | ||
38 | * struct virtproc_info - virtual remote processor state | ||
39 | * @vdev: the virtio device | ||
40 | * @rvq: rx virtqueue | ||
41 | * @svq: tx virtqueue | ||
42 | * @rbufs: kernel address of rx buffers | ||
43 | * @sbufs: kernel address of tx buffers | ||
44 | * @last_sbuf: index of last tx buffer used | ||
45 | * @bufs_dma: dma base addr of the buffers | ||
46 | * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. | ||
47 | * sending a message might require waking up a dozing remote | ||
48 | * processor, which involves sleeping, hence the mutex. | ||
49 | * @endpoints: idr of local endpoints, allows fast retrieval | ||
50 | * @endpoints_lock: lock of the endpoints set | ||
51 | * @sendq: wait queue of sending contexts waiting for a tx buffers | ||
52 | * @sleepers: number of senders that are waiting for a tx buffer | ||
53 | * @ns_ept: the bus's name service endpoint | ||
54 | * | ||
55 | * This structure stores the rpmsg state of a given virtio remote processor | ||
56 | * device (there might be several virtio proc devices for each physical | ||
57 | * remote processor). | ||
58 | */ | ||
59 | struct virtproc_info { | ||
60 | struct virtio_device *vdev; | ||
61 | struct virtqueue *rvq, *svq; | ||
62 | void *rbufs, *sbufs; | ||
63 | int last_sbuf; | ||
64 | dma_addr_t bufs_dma; | ||
65 | struct mutex tx_lock; | ||
66 | struct idr endpoints; | ||
67 | struct mutex endpoints_lock; | ||
68 | wait_queue_head_t sendq; | ||
69 | atomic_t sleepers; | ||
70 | struct rpmsg_endpoint *ns_ept; | ||
71 | }; | ||
72 | |||
73 | /** | ||
74 | * struct rpmsg_channel_info - internal channel info representation | ||
75 | * @name: name of service | ||
76 | * @src: local address | ||
77 | * @dst: destination address | ||
78 | */ | ||
79 | struct rpmsg_channel_info { | ||
80 | char name[RPMSG_NAME_SIZE]; | ||
81 | u32 src; | ||
82 | u32 dst; | ||
83 | }; | ||
84 | |||
85 | #define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev) | ||
86 | #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) | ||
87 | |||
88 | /* | ||
89 | * We're allocating 512 buffers of 512 bytes for communications, and then | ||
90 | * using the first 256 buffers for RX, and the last 256 buffers for TX. | ||
91 | * | ||
92 | * Each buffer will have 16 bytes for the msg header and 496 bytes for | ||
93 | * the payload. | ||
94 | * | ||
95 | * This will require a total space of 256KB for the buffers. | ||
96 | * | ||
97 | * We might also want to add support for user-provided buffers in time. | ||
98 | * This will allow bigger buffer size flexibility, and can also be used | ||
99 | * to achieve zero-copy messaging. | ||
100 | * | ||
101 | * Note that these numbers are purely a decision of this driver - we | ||
102 | * can change this without changing anything in the firmware of the remote | ||
103 | * processor. | ||
104 | */ | ||
105 | #define RPMSG_NUM_BUFS (512) | ||
106 | #define RPMSG_BUF_SIZE (512) | ||
107 | #define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE) | ||
108 | |||
109 | /* | ||
110 | * Local addresses are dynamically allocated on-demand. | ||
111 | * We do not dynamically assign addresses from the low 1024 range, | ||
112 | * in order to reserve that address range for predefined services. | ||
113 | */ | ||
114 | #define RPMSG_RESERVED_ADDRESSES (1024) | ||
115 | |||
116 | /* Address 53 is reserved for advertising remote services */ | ||
117 | #define RPMSG_NS_ADDR (53) | ||
118 | |||
119 | /* sysfs show configuration fields */ | ||
120 | #define rpmsg_show_attr(field, path, format_string) \ | ||
121 | static ssize_t \ | ||
122 | field##_show(struct device *dev, \ | ||
123 | struct device_attribute *attr, char *buf) \ | ||
124 | { \ | ||
125 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); \ | ||
126 | \ | ||
127 | return sprintf(buf, format_string, rpdev->path); \ | ||
128 | } | ||
129 | |||
130 | /* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */ | ||
131 | rpmsg_show_attr(name, id.name, "%s\n"); | ||
132 | rpmsg_show_attr(src, src, "0x%x\n"); | ||
133 | rpmsg_show_attr(dst, dst, "0x%x\n"); | ||
134 | rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n"); | ||
135 | |||
136 | /* | ||
137 | * Unique (and free running) index for rpmsg devices. | ||
138 | * | ||
139 | * Yeah, we're not recycling those numbers (yet?). will be easy | ||
140 | * to change if/when we want to. | ||
141 | */ | ||
142 | static unsigned int rpmsg_dev_index; | ||
143 | |||
144 | static ssize_t modalias_show(struct device *dev, | ||
145 | struct device_attribute *attr, char *buf) | ||
146 | { | ||
147 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
148 | |||
149 | return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name); | ||
150 | } | ||
151 | |||
152 | static struct device_attribute rpmsg_dev_attrs[] = { | ||
153 | __ATTR_RO(name), | ||
154 | __ATTR_RO(modalias), | ||
155 | __ATTR_RO(dst), | ||
156 | __ATTR_RO(src), | ||
157 | __ATTR_RO(announce), | ||
158 | __ATTR_NULL | ||
159 | }; | ||
160 | |||
161 | /* rpmsg devices and drivers are matched using the service name */ | ||
162 | static inline int rpmsg_id_match(const struct rpmsg_channel *rpdev, | ||
163 | const struct rpmsg_device_id *id) | ||
164 | { | ||
165 | return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0; | ||
166 | } | ||
167 | |||
168 | /* match rpmsg channel and rpmsg driver */ | ||
169 | static int rpmsg_dev_match(struct device *dev, struct device_driver *drv) | ||
170 | { | ||
171 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
172 | struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv); | ||
173 | const struct rpmsg_device_id *ids = rpdrv->id_table; | ||
174 | unsigned int i; | ||
175 | |||
176 | for (i = 0; ids[i].name[0]; i++) | ||
177 | if (rpmsg_id_match(rpdev, &ids[i])) | ||
178 | return 1; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
184 | { | ||
185 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
186 | |||
187 | return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT, | ||
188 | rpdev->id.name); | ||
189 | } | ||
190 | |||
191 | /* for more info, see below documentation of rpmsg_create_ept() */ | ||
192 | static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, | ||
193 | struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb, | ||
194 | void *priv, u32 addr) | ||
195 | { | ||
196 | int err, tmpaddr, request; | ||
197 | struct rpmsg_endpoint *ept; | ||
198 | struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev; | ||
199 | |||
200 | if (!idr_pre_get(&vrp->endpoints, GFP_KERNEL)) | ||
201 | return NULL; | ||
202 | |||
203 | ept = kzalloc(sizeof(*ept), GFP_KERNEL); | ||
204 | if (!ept) { | ||
205 | dev_err(dev, "failed to kzalloc a new ept\n"); | ||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | ept->rpdev = rpdev; | ||
210 | ept->cb = cb; | ||
211 | ept->priv = priv; | ||
212 | |||
213 | /* do we need to allocate a local address ? */ | ||
214 | request = addr == RPMSG_ADDR_ANY ? RPMSG_RESERVED_ADDRESSES : addr; | ||
215 | |||
216 | mutex_lock(&vrp->endpoints_lock); | ||
217 | |||
218 | /* bind the endpoint to an rpmsg address (and allocate one if needed) */ | ||
219 | err = idr_get_new_above(&vrp->endpoints, ept, request, &tmpaddr); | ||
220 | if (err) { | ||
221 | dev_err(dev, "idr_get_new_above failed: %d\n", err); | ||
222 | goto free_ept; | ||
223 | } | ||
224 | |||
225 | /* make sure the user's address request is fulfilled, if relevant */ | ||
226 | if (addr != RPMSG_ADDR_ANY && tmpaddr != addr) { | ||
227 | dev_err(dev, "address 0x%x already in use\n", addr); | ||
228 | goto rem_idr; | ||
229 | } | ||
230 | |||
231 | ept->addr = tmpaddr; | ||
232 | |||
233 | mutex_unlock(&vrp->endpoints_lock); | ||
234 | |||
235 | return ept; | ||
236 | |||
237 | rem_idr: | ||
238 | idr_remove(&vrp->endpoints, request); | ||
239 | free_ept: | ||
240 | mutex_unlock(&vrp->endpoints_lock); | ||
241 | kfree(ept); | ||
242 | return NULL; | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * rpmsg_create_ept() - create a new rpmsg_endpoint | ||
247 | * @rpdev: rpmsg channel device | ||
248 | * @cb: rx callback handler | ||
249 | * @priv: private data for the driver's use | ||
250 | * @addr: local rpmsg address to bind with @cb | ||
251 | * | ||
252 | * Every rpmsg address in the system is bound to an rx callback (so when | ||
253 | * inbound messages arrive, they are dispatched by the rpmsg bus using the | ||
254 | * appropriate callback handler) by means of an rpmsg_endpoint struct. | ||
255 | * | ||
256 | * This function allows drivers to create such an endpoint, and by that, | ||
257 | * bind a callback, and possibly some private data too, to an rpmsg address | ||
258 | * (either one that is known in advance, or one that will be dynamically | ||
259 | * assigned for them). | ||
260 | * | ||
261 | * Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint | ||
262 | * is already created for them when they are probed by the rpmsg bus | ||
263 | * (using the rx callback provided when they registered to the rpmsg bus). | ||
264 | * | ||
265 | * So things should just work for simple drivers: they already have an | ||
266 | * endpoint, their rx callback is bound to their rpmsg address, and when | ||
267 | * relevant inbound messages arrive (i.e. messages which their dst address | ||
268 | * equals to the src address of their rpmsg channel), the driver's handler | ||
269 | * is invoked to process it. | ||
270 | * | ||
271 | * That said, more complicated drivers might do need to allocate | ||
272 | * additional rpmsg addresses, and bind them to different rx callbacks. | ||
273 | * To accomplish that, those drivers need to call this function. | ||
274 | * | ||
275 | * Drivers should provide their @rpdev channel (so the new endpoint would belong | ||
276 | * to the same remote processor their channel belongs to), an rx callback | ||
277 | * function, an optional private data (which is provided back when the | ||
278 | * rx callback is invoked), and an address they want to bind with the | ||
279 | * callback. If @addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will | ||
280 | * dynamically assign them an available rpmsg address (drivers should have | ||
281 | * a very good reason why not to always use RPMSG_ADDR_ANY here). | ||
282 | * | ||
283 | * Returns a pointer to the endpoint on success, or NULL on error. | ||
284 | */ | ||
285 | struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, | ||
286 | rpmsg_rx_cb_t cb, void *priv, u32 addr) | ||
287 | { | ||
288 | return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, addr); | ||
289 | } | ||
290 | EXPORT_SYMBOL(rpmsg_create_ept); | ||
291 | |||
292 | /** | ||
293 | * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint | ||
294 | * @ept: endpoing to destroy | ||
295 | * | ||
296 | * Should be used by drivers to destroy an rpmsg endpoint previously | ||
297 | * created with rpmsg_create_ept(). | ||
298 | */ | ||
299 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) | ||
300 | { | ||
301 | struct virtproc_info *vrp = ept->rpdev->vrp; | ||
302 | |||
303 | mutex_lock(&vrp->endpoints_lock); | ||
304 | idr_remove(&vrp->endpoints, ept->addr); | ||
305 | mutex_unlock(&vrp->endpoints_lock); | ||
306 | |||
307 | kfree(ept); | ||
308 | } | ||
309 | EXPORT_SYMBOL(rpmsg_destroy_ept); | ||
310 | |||
311 | /* | ||
312 | * when an rpmsg driver is probed with a channel, we seamlessly create | ||
313 | * it an endpoint, binding its rx callback to a unique local rpmsg | ||
314 | * address. | ||
315 | * | ||
316 | * if we need to, we also announce about this channel to the remote | ||
317 | * processor (needed in case the driver is exposing an rpmsg service). | ||
318 | */ | ||
319 | static int rpmsg_dev_probe(struct device *dev) | ||
320 | { | ||
321 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
322 | struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); | ||
323 | struct virtproc_info *vrp = rpdev->vrp; | ||
324 | struct rpmsg_endpoint *ept; | ||
325 | int err; | ||
326 | |||
327 | ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, rpdev->src); | ||
328 | if (!ept) { | ||
329 | dev_err(dev, "failed to create endpoint\n"); | ||
330 | err = -ENOMEM; | ||
331 | goto out; | ||
332 | } | ||
333 | |||
334 | rpdev->ept = ept; | ||
335 | rpdev->src = ept->addr; | ||
336 | |||
337 | err = rpdrv->probe(rpdev); | ||
338 | if (err) { | ||
339 | dev_err(dev, "%s: failed: %d\n", __func__, err); | ||
340 | rpmsg_destroy_ept(ept); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | /* need to tell remote processor's name service about this channel ? */ | ||
345 | if (rpdev->announce && | ||
346 | virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { | ||
347 | struct rpmsg_ns_msg nsm; | ||
348 | |||
349 | strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); | ||
350 | nsm.addr = rpdev->src; | ||
351 | nsm.flags = RPMSG_NS_CREATE; | ||
352 | |||
353 | err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); | ||
354 | if (err) | ||
355 | dev_err(dev, "failed to announce service %d\n", err); | ||
356 | } | ||
357 | |||
358 | out: | ||
359 | return err; | ||
360 | } | ||
361 | |||
362 | static int rpmsg_dev_remove(struct device *dev) | ||
363 | { | ||
364 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
365 | struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); | ||
366 | struct virtproc_info *vrp = rpdev->vrp; | ||
367 | int err = 0; | ||
368 | |||
369 | /* tell remote processor's name service we're removing this channel */ | ||
370 | if (rpdev->announce && | ||
371 | virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { | ||
372 | struct rpmsg_ns_msg nsm; | ||
373 | |||
374 | strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); | ||
375 | nsm.addr = rpdev->src; | ||
376 | nsm.flags = RPMSG_NS_DESTROY; | ||
377 | |||
378 | err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); | ||
379 | if (err) | ||
380 | dev_err(dev, "failed to announce service %d\n", err); | ||
381 | } | ||
382 | |||
383 | rpdrv->remove(rpdev); | ||
384 | |||
385 | rpmsg_destroy_ept(rpdev->ept); | ||
386 | |||
387 | return err; | ||
388 | } | ||
389 | |||
390 | static struct bus_type rpmsg_bus = { | ||
391 | .name = "rpmsg", | ||
392 | .match = rpmsg_dev_match, | ||
393 | .dev_attrs = rpmsg_dev_attrs, | ||
394 | .uevent = rpmsg_uevent, | ||
395 | .probe = rpmsg_dev_probe, | ||
396 | .remove = rpmsg_dev_remove, | ||
397 | }; | ||
398 | |||
399 | /** | ||
400 | * register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus | ||
401 | * @rpdrv: pointer to a struct rpmsg_driver | ||
402 | * | ||
403 | * Returns 0 on success, and an appropriate error value on failure. | ||
404 | */ | ||
405 | int register_rpmsg_driver(struct rpmsg_driver *rpdrv) | ||
406 | { | ||
407 | rpdrv->drv.bus = &rpmsg_bus; | ||
408 | return driver_register(&rpdrv->drv); | ||
409 | } | ||
410 | EXPORT_SYMBOL(register_rpmsg_driver); | ||
411 | |||
412 | /** | ||
413 | * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus | ||
414 | * @rpdrv: pointer to a struct rpmsg_driver | ||
415 | * | ||
416 | * Returns 0 on success, and an appropriate error value on failure. | ||
417 | */ | ||
418 | void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv) | ||
419 | { | ||
420 | driver_unregister(&rpdrv->drv); | ||
421 | } | ||
422 | EXPORT_SYMBOL(unregister_rpmsg_driver); | ||
423 | |||
424 | static void rpmsg_release_device(struct device *dev) | ||
425 | { | ||
426 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
427 | |||
428 | kfree(rpdev); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * match an rpmsg channel with a channel info struct. | ||
433 | * this is used to make sure we're not creating rpmsg devices for channels | ||
434 | * that already exist. | ||
435 | */ | ||
436 | static int rpmsg_channel_match(struct device *dev, void *data) | ||
437 | { | ||
438 | struct rpmsg_channel_info *chinfo = data; | ||
439 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
440 | |||
441 | if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src) | ||
442 | return 0; | ||
443 | |||
444 | if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst) | ||
445 | return 0; | ||
446 | |||
447 | if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE)) | ||
448 | return 0; | ||
449 | |||
450 | /* found a match ! */ | ||
451 | return 1; | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * create an rpmsg channel using its name and address info. | ||
456 | * this function will be used to create both static and dynamic | ||
457 | * channels. | ||
458 | */ | ||
459 | static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp, | ||
460 | struct rpmsg_channel_info *chinfo) | ||
461 | { | ||
462 | struct rpmsg_channel *rpdev; | ||
463 | struct device *tmp, *dev = &vrp->vdev->dev; | ||
464 | int ret; | ||
465 | |||
466 | /* make sure a similar channel doesn't already exist */ | ||
467 | tmp = device_find_child(dev, chinfo, rpmsg_channel_match); | ||
468 | if (tmp) { | ||
469 | /* decrement the matched device's refcount back */ | ||
470 | put_device(tmp); | ||
471 | dev_err(dev, "channel %s:%x:%x already exist\n", | ||
472 | chinfo->name, chinfo->src, chinfo->dst); | ||
473 | return NULL; | ||
474 | } | ||
475 | |||
476 | rpdev = kzalloc(sizeof(struct rpmsg_channel), GFP_KERNEL); | ||
477 | if (!rpdev) { | ||
478 | pr_err("kzalloc failed\n"); | ||
479 | return NULL; | ||
480 | } | ||
481 | |||
482 | rpdev->vrp = vrp; | ||
483 | rpdev->src = chinfo->src; | ||
484 | rpdev->dst = chinfo->dst; | ||
485 | |||
486 | /* | ||
487 | * rpmsg server channels has predefined local address (for now), | ||
488 | * and their existence needs to be announced remotely | ||
489 | */ | ||
490 | rpdev->announce = rpdev->src != RPMSG_ADDR_ANY ? true : false; | ||
491 | |||
492 | strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE); | ||
493 | |||
494 | /* very simple device indexing plumbing which is enough for now */ | ||
495 | dev_set_name(&rpdev->dev, "rpmsg%d", rpmsg_dev_index++); | ||
496 | |||
497 | rpdev->dev.parent = &vrp->vdev->dev; | ||
498 | rpdev->dev.bus = &rpmsg_bus; | ||
499 | rpdev->dev.release = rpmsg_release_device; | ||
500 | |||
501 | ret = device_register(&rpdev->dev); | ||
502 | if (ret) { | ||
503 | dev_err(dev, "device_register failed: %d\n", ret); | ||
504 | put_device(&rpdev->dev); | ||
505 | return NULL; | ||
506 | } | ||
507 | |||
508 | return rpdev; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * find an existing channel using its name + address properties, | ||
513 | * and destroy it | ||
514 | */ | ||
515 | static int rpmsg_destroy_channel(struct virtproc_info *vrp, | ||
516 | struct rpmsg_channel_info *chinfo) | ||
517 | { | ||
518 | struct virtio_device *vdev = vrp->vdev; | ||
519 | struct device *dev; | ||
520 | |||
521 | dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match); | ||
522 | if (!dev) | ||
523 | return -EINVAL; | ||
524 | |||
525 | device_unregister(dev); | ||
526 | |||
527 | put_device(dev); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | /* super simple buffer "allocator" that is just enough for now */ | ||
533 | static void *get_a_tx_buf(struct virtproc_info *vrp) | ||
534 | { | ||
535 | unsigned int len; | ||
536 | void *ret; | ||
537 | |||
538 | /* support multiple concurrent senders */ | ||
539 | mutex_lock(&vrp->tx_lock); | ||
540 | |||
541 | /* | ||
542 | * either pick the next unused tx buffer | ||
543 | * (half of our buffers are used for sending messages) | ||
544 | */ | ||
545 | if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2) | ||
546 | ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; | ||
547 | /* or recycle a used one */ | ||
548 | else | ||
549 | ret = virtqueue_get_buf(vrp->svq, &len); | ||
550 | |||
551 | mutex_unlock(&vrp->tx_lock); | ||
552 | |||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed | ||
558 | * @vrp: virtual remote processor state | ||
559 | * | ||
560 | * This function is called before a sender is blocked, waiting for | ||
561 | * a tx buffer to become available. | ||
562 | * | ||
563 | * If we already have blocking senders, this function merely increases | ||
564 | * the "sleepers" reference count, and exits. | ||
565 | * | ||
566 | * Otherwise, if this is the first sender to block, we also enable | ||
567 | * virtio's tx callbacks, so we'd be immediately notified when a tx | ||
568 | * buffer is consumed (we rely on virtio's tx callback in order | ||
569 | * to wake up sleeping senders as soon as a tx buffer is used by the | ||
570 | * remote processor). | ||
571 | */ | ||
572 | static void rpmsg_upref_sleepers(struct virtproc_info *vrp) | ||
573 | { | ||
574 | /* support multiple concurrent senders */ | ||
575 | mutex_lock(&vrp->tx_lock); | ||
576 | |||
577 | /* are we the first sleeping context waiting for tx buffers ? */ | ||
578 | if (atomic_inc_return(&vrp->sleepers) == 1) | ||
579 | /* enable "tx-complete" interrupts before dozing off */ | ||
580 | virtqueue_enable_cb(vrp->svq); | ||
581 | |||
582 | mutex_unlock(&vrp->tx_lock); | ||
583 | } | ||
584 | |||
585 | /** | ||
586 | * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed | ||
587 | * @vrp: virtual remote processor state | ||
588 | * | ||
589 | * This function is called after a sender, that waited for a tx buffer | ||
590 | * to become available, is unblocked. | ||
591 | * | ||
592 | * If we still have blocking senders, this function merely decreases | ||
593 | * the "sleepers" reference count, and exits. | ||
594 | * | ||
595 | * Otherwise, if there are no more blocking senders, we also disable | ||
596 | * virtio's tx callbacks, to avoid the overhead incurred with handling | ||
597 | * those (now redundant) interrupts. | ||
598 | */ | ||
599 | static void rpmsg_downref_sleepers(struct virtproc_info *vrp) | ||
600 | { | ||
601 | /* support multiple concurrent senders */ | ||
602 | mutex_lock(&vrp->tx_lock); | ||
603 | |||
604 | /* are we the last sleeping context waiting for tx buffers ? */ | ||
605 | if (atomic_dec_and_test(&vrp->sleepers)) | ||
606 | /* disable "tx-complete" interrupts */ | ||
607 | virtqueue_disable_cb(vrp->svq); | ||
608 | |||
609 | mutex_unlock(&vrp->tx_lock); | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * rpmsg_send_offchannel_raw() - send a message across to the remote processor | ||
614 | * @rpdev: the rpmsg channel | ||
615 | * @src: source address | ||
616 | * @dst: destination address | ||
617 | * @data: payload of message | ||
618 | * @len: length of payload | ||
619 | * @wait: indicates whether caller should block in case no TX buffers available | ||
620 | * | ||
621 | * This function is the base implementation for all of the rpmsg sending API. | ||
622 | * | ||
623 | * It will send @data of length @len to @dst, and say it's from @src. The | ||
624 | * message will be sent to the remote processor which the @rpdev channel | ||
625 | * belongs to. | ||
626 | * | ||
627 | * The message is sent using one of the TX buffers that are available for | ||
628 | * communication with this remote processor. | ||
629 | * | ||
630 | * If @wait is true, the caller will be blocked until either a TX buffer is | ||
631 | * available, or 15 seconds elapses (we don't want callers to | ||
632 | * sleep indefinitely due to misbehaving remote processors), and in that | ||
633 | * case -ERESTARTSYS is returned. The number '15' itself was picked | ||
634 | * arbitrarily; there's little point in asking drivers to provide a timeout | ||
635 | * value themselves. | ||
636 | * | ||
637 | * Otherwise, if @wait is false, and there are no TX buffers available, | ||
638 | * the function will immediately fail, and -ENOMEM will be returned. | ||
639 | * | ||
640 | * Normally drivers shouldn't use this function directly; instead, drivers | ||
641 | * should use the appropriate rpmsg_{try}send{to, _offchannel} API | ||
642 | * (see include/linux/rpmsg.h). | ||
643 | * | ||
644 | * Returns 0 on success and an appropriate error value on failure. | ||
645 | */ | ||
646 | int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
647 | void *data, int len, bool wait) | ||
648 | { | ||
649 | struct virtproc_info *vrp = rpdev->vrp; | ||
650 | struct device *dev = &rpdev->dev; | ||
651 | struct scatterlist sg; | ||
652 | struct rpmsg_hdr *msg; | ||
653 | int err; | ||
654 | |||
655 | /* bcasting isn't allowed */ | ||
656 | if (src == RPMSG_ADDR_ANY || dst == RPMSG_ADDR_ANY) { | ||
657 | dev_err(dev, "invalid addr (src 0x%x, dst 0x%x)\n", src, dst); | ||
658 | return -EINVAL; | ||
659 | } | ||
660 | |||
661 | /* | ||
662 | * We currently use fixed-sized buffers, and therefore the payload | ||
663 | * length is limited. | ||
664 | * | ||
665 | * One of the possible improvements here is either to support | ||
666 | * user-provided buffers (and then we can also support zero-copy | ||
667 | * messaging), or to improve the buffer allocator, to support | ||
668 | * variable-length buffer sizes. | ||
669 | */ | ||
670 | if (len > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) { | ||
671 | dev_err(dev, "message is too big (%d)\n", len); | ||
672 | return -EMSGSIZE; | ||
673 | } | ||
674 | |||
675 | /* grab a buffer */ | ||
676 | msg = get_a_tx_buf(vrp); | ||
677 | if (!msg && !wait) | ||
678 | return -ENOMEM; | ||
679 | |||
680 | /* no free buffer ? wait for one (but bail after 15 seconds) */ | ||
681 | while (!msg) { | ||
682 | /* enable "tx-complete" interrupts, if not already enabled */ | ||
683 | rpmsg_upref_sleepers(vrp); | ||
684 | |||
685 | /* | ||
686 | * sleep until a free buffer is available or 15 secs elapse. | ||
687 | * the timeout period is not configurable because there's | ||
688 | * little point in asking drivers to specify that. | ||
689 | * if later this happens to be required, it'd be easy to add. | ||
690 | */ | ||
691 | err = wait_event_interruptible_timeout(vrp->sendq, | ||
692 | (msg = get_a_tx_buf(vrp)), | ||
693 | msecs_to_jiffies(15000)); | ||
694 | |||
695 | /* disable "tx-complete" interrupts if we're the last sleeper */ | ||
696 | rpmsg_downref_sleepers(vrp); | ||
697 | |||
698 | /* timeout ? */ | ||
699 | if (!err) { | ||
700 | dev_err(dev, "timeout waiting for a tx buffer\n"); | ||
701 | return -ERESTARTSYS; | ||
702 | } | ||
703 | } | ||
704 | |||
705 | msg->len = len; | ||
706 | msg->flags = 0; | ||
707 | msg->src = src; | ||
708 | msg->dst = dst; | ||
709 | msg->reserved = 0; | ||
710 | memcpy(msg->data, data, len); | ||
711 | |||
712 | dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n", | ||
713 | msg->src, msg->dst, msg->len, | ||
714 | msg->flags, msg->reserved); | ||
715 | print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1, | ||
716 | msg, sizeof(*msg) + msg->len, true); | ||
717 | |||
718 | sg_init_one(&sg, msg, sizeof(*msg) + len); | ||
719 | |||
720 | mutex_lock(&vrp->tx_lock); | ||
721 | |||
722 | /* add message to the remote processor's virtqueue */ | ||
723 | err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL); | ||
724 | if (err < 0) { | ||
725 | /* | ||
726 | * need to reclaim the buffer here, otherwise it's lost | ||
727 | * (memory won't leak, but rpmsg won't use it again for TX). | ||
728 | * this will wait for a buffer management overhaul. | ||
729 | */ | ||
730 | dev_err(dev, "virtqueue_add_buf failed: %d\n", err); | ||
731 | goto out; | ||
732 | } | ||
733 | |||
734 | /* tell the remote processor it has a pending message to read */ | ||
735 | virtqueue_kick(vrp->svq); | ||
736 | |||
737 | err = 0; | ||
738 | out: | ||
739 | mutex_unlock(&vrp->tx_lock); | ||
740 | return err; | ||
741 | } | ||
742 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); | ||
743 | |||
744 | /* called when an rx buffer is used, and it's time to digest a message */ | ||
745 | static void rpmsg_recv_done(struct virtqueue *rvq) | ||
746 | { | ||
747 | struct rpmsg_hdr *msg; | ||
748 | unsigned int len; | ||
749 | struct rpmsg_endpoint *ept; | ||
750 | struct scatterlist sg; | ||
751 | struct virtproc_info *vrp = rvq->vdev->priv; | ||
752 | struct device *dev = &rvq->vdev->dev; | ||
753 | int err; | ||
754 | |||
755 | msg = virtqueue_get_buf(rvq, &len); | ||
756 | if (!msg) { | ||
757 | dev_err(dev, "uhm, incoming signal, but no used buffer ?\n"); | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n", | ||
762 | msg->src, msg->dst, msg->len, | ||
763 | msg->flags, msg->reserved); | ||
764 | print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1, | ||
765 | msg, sizeof(*msg) + msg->len, true); | ||
766 | |||
767 | /* use the dst addr to fetch the callback of the appropriate user */ | ||
768 | mutex_lock(&vrp->endpoints_lock); | ||
769 | ept = idr_find(&vrp->endpoints, msg->dst); | ||
770 | mutex_unlock(&vrp->endpoints_lock); | ||
771 | |||
772 | if (ept && ept->cb) | ||
773 | ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src); | ||
774 | else | ||
775 | dev_warn(dev, "msg received with no recepient\n"); | ||
776 | |||
777 | sg_init_one(&sg, msg, sizeof(*msg) + len); | ||
778 | |||
779 | /* add the buffer back to the remote processor's virtqueue */ | ||
780 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL); | ||
781 | if (err < 0) { | ||
782 | dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); | ||
783 | return; | ||
784 | } | ||
785 | |||
786 | /* tell the remote processor we added another available rx buffer */ | ||
787 | virtqueue_kick(vrp->rvq); | ||
788 | } | ||
789 | |||
790 | /* | ||
791 | * This is invoked whenever the remote processor completed processing | ||
792 | * a TX msg we just sent it, and the buffer is put back to the used ring. | ||
793 | * | ||
794 | * Normally, though, we suppress this "tx complete" interrupt in order to | ||
795 | * avoid the incurred overhead. | ||
796 | */ | ||
797 | static void rpmsg_xmit_done(struct virtqueue *svq) | ||
798 | { | ||
799 | struct virtproc_info *vrp = svq->vdev->priv; | ||
800 | |||
801 | dev_dbg(&svq->vdev->dev, "%s\n", __func__); | ||
802 | |||
803 | /* wake up potential senders that are waiting for a tx buffer */ | ||
804 | wake_up_interruptible(&vrp->sendq); | ||
805 | } | ||
806 | |||
807 | /* invoked when a name service announcement arrives */ | ||
808 | static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len, | ||
809 | void *priv, u32 src) | ||
810 | { | ||
811 | struct rpmsg_ns_msg *msg = data; | ||
812 | struct rpmsg_channel *newch; | ||
813 | struct rpmsg_channel_info chinfo; | ||
814 | struct virtproc_info *vrp = priv; | ||
815 | struct device *dev = &vrp->vdev->dev; | ||
816 | int ret; | ||
817 | |||
818 | print_hex_dump(KERN_DEBUG, "NS announcement: ", | ||
819 | DUMP_PREFIX_NONE, 16, 1, | ||
820 | data, len, true); | ||
821 | |||
822 | if (len != sizeof(*msg)) { | ||
823 | dev_err(dev, "malformed ns msg (%d)\n", len); | ||
824 | return; | ||
825 | } | ||
826 | |||
827 | /* | ||
828 | * the name service ept does _not_ belong to a real rpmsg channel, | ||
829 | * and is handled by the rpmsg bus itself. | ||
830 | * for sanity reasons, make sure a valid rpdev has _not_ sneaked | ||
831 | * in somehow. | ||
832 | */ | ||
833 | if (rpdev) { | ||
834 | dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); | ||
835 | return; | ||
836 | } | ||
837 | |||
838 | /* don't trust the remote processor for null terminating the name */ | ||
839 | msg->name[RPMSG_NAME_SIZE - 1] = '\0'; | ||
840 | |||
841 | dev_info(dev, "%sing channel %s addr 0x%x\n", | ||
842 | msg->flags & RPMSG_NS_DESTROY ? "destroy" : "creat", | ||
843 | msg->name, msg->addr); | ||
844 | |||
845 | strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); | ||
846 | chinfo.src = RPMSG_ADDR_ANY; | ||
847 | chinfo.dst = msg->addr; | ||
848 | |||
849 | if (msg->flags & RPMSG_NS_DESTROY) { | ||
850 | ret = rpmsg_destroy_channel(vrp, &chinfo); | ||
851 | if (ret) | ||
852 | dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); | ||
853 | } else { | ||
854 | newch = rpmsg_create_channel(vrp, &chinfo); | ||
855 | if (!newch) | ||
856 | dev_err(dev, "rpmsg_create_channel failed\n"); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | static int rpmsg_probe(struct virtio_device *vdev) | ||
861 | { | ||
862 | vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; | ||
863 | const char *names[] = { "input", "output" }; | ||
864 | struct virtqueue *vqs[2]; | ||
865 | struct virtproc_info *vrp; | ||
866 | void *bufs_va; | ||
867 | int err = 0, i; | ||
868 | |||
869 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); | ||
870 | if (!vrp) | ||
871 | return -ENOMEM; | ||
872 | |||
873 | vrp->vdev = vdev; | ||
874 | |||
875 | idr_init(&vrp->endpoints); | ||
876 | mutex_init(&vrp->endpoints_lock); | ||
877 | mutex_init(&vrp->tx_lock); | ||
878 | init_waitqueue_head(&vrp->sendq); | ||
879 | |||
880 | /* We expect two virtqueues, rx and tx (and in this order) */ | ||
881 | err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names); | ||
882 | if (err) | ||
883 | goto free_vrp; | ||
884 | |||
885 | vrp->rvq = vqs[0]; | ||
886 | vrp->svq = vqs[1]; | ||
887 | |||
888 | /* allocate coherent memory for the buffers */ | ||
889 | bufs_va = dma_alloc_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, | ||
890 | &vrp->bufs_dma, GFP_KERNEL); | ||
891 | if (!bufs_va) | ||
892 | goto vqs_del; | ||
893 | |||
894 | dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%x\n", bufs_va, | ||
895 | vrp->bufs_dma); | ||
896 | |||
897 | /* half of the buffers is dedicated for RX */ | ||
898 | vrp->rbufs = bufs_va; | ||
899 | |||
900 | /* and half is dedicated for TX */ | ||
901 | vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2; | ||
902 | |||
903 | /* set up the receive buffers */ | ||
904 | for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) { | ||
905 | struct scatterlist sg; | ||
906 | void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; | ||
907 | |||
908 | sg_init_one(&sg, cpu_addr, RPMSG_BUF_SIZE); | ||
909 | |||
910 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr, | ||
911 | GFP_KERNEL); | ||
912 | WARN_ON(err < 0); /* sanity check; this can't really happen */ | ||
913 | } | ||
914 | |||
915 | /* suppress "tx-complete" interrupts */ | ||
916 | virtqueue_disable_cb(vrp->svq); | ||
917 | |||
918 | vdev->priv = vrp; | ||
919 | |||
920 | /* if supported by the remote processor, enable the name service */ | ||
921 | if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { | ||
922 | /* a dedicated endpoint handles the name service msgs */ | ||
923 | vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb, | ||
924 | vrp, RPMSG_NS_ADDR); | ||
925 | if (!vrp->ns_ept) { | ||
926 | dev_err(&vdev->dev, "failed to create the ns ept\n"); | ||
927 | err = -ENOMEM; | ||
928 | goto free_coherent; | ||
929 | } | ||
930 | } | ||
931 | |||
932 | /* tell the remote processor it can start sending messages */ | ||
933 | virtqueue_kick(vrp->rvq); | ||
934 | |||
935 | dev_info(&vdev->dev, "rpmsg host is online\n"); | ||
936 | |||
937 | return 0; | ||
938 | |||
939 | free_coherent: | ||
940 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va, | ||
941 | vrp->bufs_dma); | ||
942 | vqs_del: | ||
943 | vdev->config->del_vqs(vrp->vdev); | ||
944 | free_vrp: | ||
945 | kfree(vrp); | ||
946 | return err; | ||
947 | } | ||
948 | |||
949 | static int rpmsg_remove_device(struct device *dev, void *data) | ||
950 | { | ||
951 | device_unregister(dev); | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static void __devexit rpmsg_remove(struct virtio_device *vdev) | ||
957 | { | ||
958 | struct virtproc_info *vrp = vdev->priv; | ||
959 | int ret; | ||
960 | |||
961 | vdev->config->reset(vdev); | ||
962 | |||
963 | ret = device_for_each_child(&vdev->dev, NULL, rpmsg_remove_device); | ||
964 | if (ret) | ||
965 | dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); | ||
966 | |||
967 | idr_remove_all(&vrp->endpoints); | ||
968 | idr_destroy(&vrp->endpoints); | ||
969 | |||
970 | vdev->config->del_vqs(vrp->vdev); | ||
971 | |||
972 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, | ||
973 | vrp->rbufs, vrp->bufs_dma); | ||
974 | |||
975 | kfree(vrp); | ||
976 | } | ||
977 | |||
978 | static struct virtio_device_id id_table[] = { | ||
979 | { VIRTIO_ID_RPMSG, VIRTIO_DEV_ANY_ID }, | ||
980 | { 0 }, | ||
981 | }; | ||
982 | |||
983 | static unsigned int features[] = { | ||
984 | VIRTIO_RPMSG_F_NS, | ||
985 | }; | ||
986 | |||
987 | static struct virtio_driver virtio_ipc_driver = { | ||
988 | .feature_table = features, | ||
989 | .feature_table_size = ARRAY_SIZE(features), | ||
990 | .driver.name = KBUILD_MODNAME, | ||
991 | .driver.owner = THIS_MODULE, | ||
992 | .id_table = id_table, | ||
993 | .probe = rpmsg_probe, | ||
994 | .remove = __devexit_p(rpmsg_remove), | ||
995 | }; | ||
996 | |||
997 | static int __init rpmsg_init(void) | ||
998 | { | ||
999 | int ret; | ||
1000 | |||
1001 | ret = bus_register(&rpmsg_bus); | ||
1002 | if (ret) { | ||
1003 | pr_err("failed to register rpmsg bus: %d\n", ret); | ||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
1007 | ret = register_virtio_driver(&virtio_ipc_driver); | ||
1008 | if (ret) { | ||
1009 | pr_err("failed to register virtio driver: %d\n", ret); | ||
1010 | bus_unregister(&rpmsg_bus); | ||
1011 | } | ||
1012 | |||
1013 | return ret; | ||
1014 | } | ||
1015 | module_init(rpmsg_init); | ||
1016 | |||
1017 | static void __exit rpmsg_fini(void) | ||
1018 | { | ||
1019 | unregister_virtio_driver(&virtio_ipc_driver); | ||
1020 | bus_unregister(&rpmsg_bus); | ||
1021 | } | ||
1022 | module_exit(rpmsg_fini); | ||
1023 | |||
1024 | MODULE_DEVICE_TABLE(virtio, id_table); | ||
1025 | MODULE_DESCRIPTION("Virtio-based remote processor messaging bus"); | ||
1026 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 83ac0713ed0a..88046b622052 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -414,6 +414,15 @@ struct hv_vmbus_device_id { | |||
414 | __attribute__((aligned(sizeof(kernel_ulong_t)))); | 414 | __attribute__((aligned(sizeof(kernel_ulong_t)))); |
415 | }; | 415 | }; |
416 | 416 | ||
417 | /* rpmsg */ | ||
418 | |||
419 | #define RPMSG_NAME_SIZE 32 | ||
420 | #define RPMSG_DEVICE_MODALIAS_FMT "rpmsg:%s" | ||
421 | |||
422 | struct rpmsg_device_id { | ||
423 | char name[RPMSG_NAME_SIZE]; | ||
424 | }; | ||
425 | |||
417 | /* i2c */ | 426 | /* i2c */ |
418 | 427 | ||
419 | #define I2C_NAME_SIZE 20 | 428 | #define I2C_NAME_SIZE 20 |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h new file mode 100644 index 000000000000..ada4cb063dfe --- /dev/null +++ b/include/linux/remoteproc.h | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Remote Processor Framework | ||
3 | * | ||
4 | * Copyright(c) 2011 Texas Instruments, Inc. | ||
5 | * Copyright(c) 2011 Google, Inc. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * * Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * * Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * * Neither the name Texas Instruments nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef REMOTEPROC_H | ||
36 | #define REMOTEPROC_H | ||
37 | |||
38 | #include <linux/types.h> | ||
39 | #include <linux/kref.h> | ||
40 | #include <linux/klist.h> | ||
41 | #include <linux/mutex.h> | ||
42 | #include <linux/virtio.h> | ||
43 | #include <linux/completion.h> | ||
44 | |||
45 | /* | ||
46 | * The alignment between the consumer and producer parts of the vring. | ||
47 | * Note: this is part of the "wire" protocol. If you change this, you need | ||
48 | * to update your peers too. | ||
49 | */ | ||
50 | #define AMP_VRING_ALIGN (4096) | ||
51 | |||
52 | /** | ||
53 | * struct fw_resource - describes an entry from the resource section | ||
54 | * @type: resource type | ||
55 | * @id: index number of the resource | ||
56 | * @da: device address of the resource | ||
57 | * @pa: physical address of the resource | ||
58 | * @len: size, in bytes, of the resource | ||
59 | * @flags: properties of the resource, e.g. iommu protection required | ||
60 | * @reserved: must be 0 atm | ||
61 | * @name: name of resource | ||
62 | * | ||
63 | * The remote processor firmware should contain a "resource table": | ||
64 | * array of 'struct fw_resource' entries. | ||
65 | * | ||
66 | * Some resources entries are mere announcements, where the host is informed | ||
67 | * of specific remoteproc configuration. Other entries require the host to | ||
68 | * do something (e.g. reserve a requested resource) and possibly also reply | ||
69 | * by overwriting a member inside 'struct fw_resource' with info about the | ||
70 | * allocated resource. | ||
71 | * | ||
72 | * Different resource entries use different members of this struct, | ||
73 | * with different meanings. This is pretty limiting and error-prone, | ||
74 | * so the plan is to move to variable-length TLV-based resource entries, | ||
75 | * where each resource type will have its own structure. | ||
76 | */ | ||
77 | struct fw_resource { | ||
78 | u32 type; | ||
79 | u32 id; | ||
80 | u64 da; | ||
81 | u64 pa; | ||
82 | u32 len; | ||
83 | u32 flags; | ||
84 | u8 reserved[16]; | ||
85 | u8 name[48]; | ||
86 | } __packed; | ||
87 | |||
88 | /** | ||
89 | * enum fw_resource_type - types of resource entries | ||
90 | * | ||
91 | * @RSC_CARVEOUT: request for allocation of a physically contiguous | ||
92 | * memory region. | ||
93 | * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. | ||
94 | * @RSC_TRACE: announces the availability of a trace buffer into which | ||
95 | * the remote processor will be writing logs. In this case, | ||
96 | * 'da' indicates the device address where logs are written to, | ||
97 | * and 'len' is the size of the trace buffer. | ||
98 | * @RSC_VRING: request for allocation of a virtio vring (address should | ||
99 | * be indicated in 'da', and 'len' should contain the number | ||
100 | * of buffers supported by the vring). | ||
101 | * @RSC_VIRTIO_DEV: this entry declares about support for a virtio device, | ||
102 | * and serves as the virtio header. 'da' holds the | ||
103 | * the virtio device features, 'pa' holds the virtio guest | ||
104 | * features, 'len' holds the virtio status, and 'flags' holds | ||
105 | * the virtio id (currently only VIRTIO_ID_RPMSG is supported). | ||
106 | * @RSC_LAST: just keep this one at the end | ||
107 | * | ||
108 | * Most of the resource entries share the basic idea of address/length | ||
109 | * negotiation with the host: the firmware usually asks (on behalf of the | ||
110 | * remote processor that will soon be booted with it) for memory | ||
111 | * of size 'len' bytes, and the host needs to allocate it and provide | ||
112 | * the device/physical address (when relevant) in 'da'/'pa' respectively. | ||
113 | * | ||
114 | * If the firmware is compiled with hard coded device addresses, and | ||
115 | * can't handle dynamically allocated 'da' values, then the 'da' field | ||
116 | * will contain the expected device addresses (today we actually only support | ||
117 | * this scheme, as there aren't yet any use cases for dynamically allocated | ||
118 | * device addresses). | ||
119 | * | ||
120 | * Please note that these values are used as indices to the rproc_handle_rsc | ||
121 | * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to | ||
122 | * check the validity of an index before the lookup table is accessed, so | ||
123 | * please update it as needed. | ||
124 | */ | ||
125 | enum fw_resource_type { | ||
126 | RSC_CARVEOUT = 0, | ||
127 | RSC_DEVMEM = 1, | ||
128 | RSC_TRACE = 2, | ||
129 | RSC_VRING = 3, | ||
130 | RSC_VIRTIO_DEV = 4, | ||
131 | RSC_LAST = 5, | ||
132 | }; | ||
133 | |||
134 | /** | ||
135 | * struct rproc_mem_entry - memory entry descriptor | ||
136 | * @va: virtual address | ||
137 | * @dma: dma address | ||
138 | * @len: length, in bytes | ||
139 | * @da: device address | ||
140 | * @priv: associated data | ||
141 | * @node: list node | ||
142 | */ | ||
143 | struct rproc_mem_entry { | ||
144 | void *va; | ||
145 | dma_addr_t dma; | ||
146 | int len; | ||
147 | u64 da; | ||
148 | void *priv; | ||
149 | struct list_head node; | ||
150 | }; | ||
151 | |||
152 | struct rproc; | ||
153 | |||
154 | /** | ||
155 | * struct rproc_ops - platform-specific device handlers | ||
156 | * @start: power on the device and boot it | ||
157 | * @stop: power off the device | ||
158 | * @kick: kick a virtqueue (virtqueue id given as a parameter) | ||
159 | */ | ||
160 | struct rproc_ops { | ||
161 | int (*start)(struct rproc *rproc); | ||
162 | int (*stop)(struct rproc *rproc); | ||
163 | void (*kick)(struct rproc *rproc, int vqid); | ||
164 | }; | ||
165 | |||
166 | /** | ||
167 | * enum rproc_state - remote processor states | ||
168 | * @RPROC_OFFLINE: device is powered off | ||
169 | * @RPROC_SUSPENDED: device is suspended; needs to be woken up to receive | ||
170 | * a message. | ||
171 | * @RPROC_RUNNING: device is up and running | ||
172 | * @RPROC_CRASHED: device has crashed; need to start recovery | ||
173 | * @RPROC_LAST: just keep this one at the end | ||
174 | * | ||
175 | * Please note that the values of these states are used as indices | ||
176 | * to rproc_state_string, a state-to-name lookup table, | ||
177 | * so please keep the two synchronized. @RPROC_LAST is used to check | ||
178 | * the validity of an index before the lookup table is accessed, so | ||
179 | * please update it as needed too. | ||
180 | */ | ||
181 | enum rproc_state { | ||
182 | RPROC_OFFLINE = 0, | ||
183 | RPROC_SUSPENDED = 1, | ||
184 | RPROC_RUNNING = 2, | ||
185 | RPROC_CRASHED = 3, | ||
186 | RPROC_LAST = 4, | ||
187 | }; | ||
188 | |||
189 | /** | ||
190 | * struct rproc - represents a physical remote processor device | ||
191 | * @node: klist node of this rproc object | ||
192 | * @domain: iommu domain | ||
193 | * @name: human readable name of the rproc | ||
194 | * @firmware: name of firmware file to be loaded | ||
195 | * @priv: private data which belongs to the platform-specific rproc module | ||
196 | * @ops: platform-specific start/stop rproc handlers | ||
197 | * @dev: underlying device | ||
198 | * @refcount: refcount of users that have a valid pointer to this rproc | ||
199 | * @power: refcount of users who need this rproc powered up | ||
200 | * @state: state of the device | ||
201 | * @lock: lock which protects concurrent manipulations of the rproc | ||
202 | * @dbg_dir: debugfs directory of this rproc device | ||
203 | * @traces: list of trace buffers | ||
204 | * @num_traces: number of trace buffers | ||
205 | * @carveouts: list of physically contiguous memory allocations | ||
206 | * @mappings: list of iommu mappings we initiated, needed on shutdown | ||
207 | * @firmware_loading_complete: marks e/o asynchronous firmware loading | ||
208 | * @bootaddr: address of first instruction to boot rproc with (optional) | ||
209 | * @rvdev: virtio device (we only support a single rpmsg virtio device for now) | ||
210 | */ | ||
211 | struct rproc { | ||
212 | struct klist_node node; | ||
213 | struct iommu_domain *domain; | ||
214 | const char *name; | ||
215 | const char *firmware; | ||
216 | void *priv; | ||
217 | const struct rproc_ops *ops; | ||
218 | struct device *dev; | ||
219 | struct kref refcount; | ||
220 | atomic_t power; | ||
221 | unsigned int state; | ||
222 | struct mutex lock; | ||
223 | struct dentry *dbg_dir; | ||
224 | struct list_head traces; | ||
225 | int num_traces; | ||
226 | struct list_head carveouts; | ||
227 | struct list_head mappings; | ||
228 | struct completion firmware_loading_complete; | ||
229 | u64 bootaddr; | ||
230 | struct rproc_vdev *rvdev; | ||
231 | }; | ||
232 | |||
233 | /** | ||
234 | * struct rproc_vdev - remoteproc state for a supported virtio device | ||
235 | * @rproc: the rproc handle | ||
236 | * @vdev: the virio device | ||
237 | * @vq: the virtqueues for this vdev | ||
238 | * @vring: the vrings for this vdev | ||
239 | * @dfeatures: virtio device features | ||
240 | * @gfeatures: virtio guest features | ||
241 | */ | ||
242 | struct rproc_vdev { | ||
243 | struct rproc *rproc; | ||
244 | struct virtio_device vdev; | ||
245 | struct virtqueue *vq[2]; | ||
246 | struct rproc_mem_entry vring[2]; | ||
247 | unsigned long dfeatures; | ||
248 | unsigned long gfeatures; | ||
249 | }; | ||
250 | |||
251 | struct rproc *rproc_get_by_name(const char *name); | ||
252 | void rproc_put(struct rproc *rproc); | ||
253 | |||
254 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
255 | const struct rproc_ops *ops, | ||
256 | const char *firmware, int len); | ||
257 | void rproc_free(struct rproc *rproc); | ||
258 | int rproc_register(struct rproc *rproc); | ||
259 | int rproc_unregister(struct rproc *rproc); | ||
260 | |||
261 | int rproc_boot(struct rproc *rproc); | ||
262 | void rproc_shutdown(struct rproc *rproc); | ||
263 | |||
264 | static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) | ||
265 | { | ||
266 | struct rproc_vdev *rvdev = container_of(vdev, struct rproc_vdev, vdev); | ||
267 | |||
268 | return rvdev->rproc; | ||
269 | } | ||
270 | |||
271 | #endif /* REMOTEPROC_H */ | ||
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h new file mode 100644 index 000000000000..a8e50e44203c --- /dev/null +++ b/include/linux/rpmsg.h | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * Remote processor messaging | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * * Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * * Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * * Neither the name Texas Instruments nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _LINUX_RPMSG_H | ||
36 | #define _LINUX_RPMSG_H | ||
37 | |||
38 | #include <linux/types.h> | ||
39 | #include <linux/device.h> | ||
40 | #include <linux/mod_devicetable.h> | ||
41 | |||
42 | /* The feature bitmap for virtio rpmsg */ | ||
43 | #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */ | ||
44 | |||
45 | /** | ||
46 | * struct rpmsg_hdr - common header for all rpmsg messages | ||
47 | * @src: source address | ||
48 | * @dst: destination address | ||
49 | * @reserved: reserved for future use | ||
50 | * @len: length of payload (in bytes) | ||
51 | * @flags: message flags | ||
52 | * @data: @len bytes of message payload data | ||
53 | * | ||
54 | * Every message sent(/received) on the rpmsg bus begins with this header. | ||
55 | */ | ||
56 | struct rpmsg_hdr { | ||
57 | u32 src; | ||
58 | u32 dst; | ||
59 | u32 reserved; | ||
60 | u16 len; | ||
61 | u16 flags; | ||
62 | u8 data[0]; | ||
63 | } __packed; | ||
64 | |||
65 | /** | ||
66 | * struct rpmsg_ns_msg - dynamic name service announcement message | ||
67 | * @name: name of remote service that is published | ||
68 | * @addr: address of remote service that is published | ||
69 | * @flags: indicates whether service is created or destroyed | ||
70 | * | ||
71 | * This message is sent across to publish a new service, or announce | ||
72 | * about its removal. When we receive these messages, an appropriate | ||
73 | * rpmsg channel (i.e device) is created/destroyed. In turn, the ->probe() | ||
74 | * or ->remove() handler of the appropriate rpmsg driver will be invoked | ||
75 | * (if/as-soon-as one is registered). | ||
76 | */ | ||
77 | struct rpmsg_ns_msg { | ||
78 | char name[RPMSG_NAME_SIZE]; | ||
79 | u32 addr; | ||
80 | u32 flags; | ||
81 | } __packed; | ||
82 | |||
83 | /** | ||
84 | * enum rpmsg_ns_flags - dynamic name service announcement flags | ||
85 | * | ||
86 | * @RPMSG_NS_CREATE: a new remote service was just created | ||
87 | * @RPMSG_NS_DESTROY: a known remote service was just destroyed | ||
88 | */ | ||
89 | enum rpmsg_ns_flags { | ||
90 | RPMSG_NS_CREATE = 0, | ||
91 | RPMSG_NS_DESTROY = 1, | ||
92 | }; | ||
93 | |||
94 | #define RPMSG_ADDR_ANY 0xFFFFFFFF | ||
95 | |||
96 | struct virtproc_info; | ||
97 | |||
98 | /** | ||
99 | * rpmsg_channel - devices that belong to the rpmsg bus are called channels | ||
100 | * @vrp: the remote processor this channel belongs to | ||
101 | * @dev: the device struct | ||
102 | * @id: device id (used to match between rpmsg drivers and devices) | ||
103 | * @src: local address | ||
104 | * @dst: destination address | ||
105 | * @ept: the rpmsg endpoint of this channel | ||
106 | * @announce: if set, rpmsg will announce the creation/removal of this channel | ||
107 | */ | ||
108 | struct rpmsg_channel { | ||
109 | struct virtproc_info *vrp; | ||
110 | struct device dev; | ||
111 | struct rpmsg_device_id id; | ||
112 | u32 src; | ||
113 | u32 dst; | ||
114 | struct rpmsg_endpoint *ept; | ||
115 | bool announce; | ||
116 | }; | ||
117 | |||
118 | typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, u32); | ||
119 | |||
120 | /** | ||
121 | * struct rpmsg_endpoint - binds a local rpmsg address to its user | ||
122 | * @rpdev: rpmsg channel device | ||
123 | * @cb: rx callback handler | ||
124 | * @addr: local rpmsg address | ||
125 | * @priv: private data for the driver's use | ||
126 | * | ||
127 | * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as | ||
128 | * it binds an rpmsg address with an rx callback handler. | ||
129 | * | ||
130 | * Simple rpmsg drivers shouldn't use this struct directly, because | ||
131 | * things just work: every rpmsg driver provides an rx callback upon | ||
132 | * registering to the bus, and that callback is then bound to its rpmsg | ||
133 | * address when the driver is probed. When relevant inbound messages arrive | ||
134 | * (i.e. messages which their dst address equals to the src address of | ||
135 | * the rpmsg channel), the driver's handler is invoked to process it. | ||
136 | * | ||
137 | * More complicated drivers though, that do need to allocate additional rpmsg | ||
138 | * addresses, and bind them to different rx callbacks, must explicitly | ||
139 | * create additional endpoints by themselves (see rpmsg_create_ept()). | ||
140 | */ | ||
141 | struct rpmsg_endpoint { | ||
142 | struct rpmsg_channel *rpdev; | ||
143 | rpmsg_rx_cb_t cb; | ||
144 | u32 addr; | ||
145 | void *priv; | ||
146 | }; | ||
147 | |||
148 | /** | ||
149 | * struct rpmsg_driver - rpmsg driver struct | ||
150 | * @drv: underlying device driver | ||
151 | * @id_table: rpmsg ids serviced by this driver | ||
152 | * @probe: invoked when a matching rpmsg channel (i.e. device) is found | ||
153 | * @remove: invoked when the rpmsg channel is removed | ||
154 | * @callback: invoked when an inbound message is received on the channel | ||
155 | */ | ||
156 | struct rpmsg_driver { | ||
157 | struct device_driver drv; | ||
158 | const struct rpmsg_device_id *id_table; | ||
159 | int (*probe)(struct rpmsg_channel *dev); | ||
160 | void (*remove)(struct rpmsg_channel *dev); | ||
161 | void (*callback)(struct rpmsg_channel *, void *, int, void *, u32); | ||
162 | }; | ||
163 | |||
164 | int register_rpmsg_device(struct rpmsg_channel *dev); | ||
165 | void unregister_rpmsg_device(struct rpmsg_channel *dev); | ||
166 | int register_rpmsg_driver(struct rpmsg_driver *drv); | ||
167 | void unregister_rpmsg_driver(struct rpmsg_driver *drv); | ||
168 | void rpmsg_destroy_ept(struct rpmsg_endpoint *); | ||
169 | struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *, | ||
170 | rpmsg_rx_cb_t cb, void *priv, u32 addr); | ||
171 | int | ||
172 | rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); | ||
173 | |||
174 | /** | ||
175 | * rpmsg_send() - send a message across to the remote processor | ||
176 | * @rpdev: the rpmsg channel | ||
177 | * @data: payload of message | ||
178 | * @len: length of payload | ||
179 | * | ||
180 | * This function sends @data of length @len on the @rpdev channel. | ||
181 | * The message will be sent to the remote processor which the @rpdev | ||
182 | * channel belongs to, using @rpdev's source and destination addresses. | ||
183 | * In case there are no TX buffers available, the function will block until | ||
184 | * one becomes available, or a timeout of 15 seconds elapses. When the latter | ||
185 | * happens, -ERESTARTSYS is returned. | ||
186 | * | ||
187 | * Can only be called from process context (for now). | ||
188 | * | ||
189 | * Returns 0 on success and an appropriate error value on failure. | ||
190 | */ | ||
191 | static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) | ||
192 | { | ||
193 | u32 src = rpdev->src, dst = rpdev->dst; | ||
194 | |||
195 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * rpmsg_sendto() - send a message across to the remote processor, specify dst | ||
200 | * @rpdev: the rpmsg channel | ||
201 | * @data: payload of message | ||
202 | * @len: length of payload | ||
203 | * @dst: destination address | ||
204 | * | ||
205 | * This function sends @data of length @len to the remote @dst address. | ||
206 | * The message will be sent to the remote processor which the @rpdev | ||
207 | * channel belongs to, using @rpdev's source address. | ||
208 | * In case there are no TX buffers available, the function will block until | ||
209 | * one becomes available, or a timeout of 15 seconds elapses. When the latter | ||
210 | * happens, -ERESTARTSYS is returned. | ||
211 | * | ||
212 | * Can only be called from process context (for now). | ||
213 | * | ||
214 | * Returns 0 on success and an appropriate error value on failure. | ||
215 | */ | ||
216 | static inline | ||
217 | int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) | ||
218 | { | ||
219 | u32 src = rpdev->src; | ||
220 | |||
221 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * rpmsg_send_offchannel() - send a message using explicit src/dst addresses | ||
226 | * @rpdev: the rpmsg channel | ||
227 | * @src: source address | ||
228 | * @dst: destination address | ||
229 | * @data: payload of message | ||
230 | * @len: length of payload | ||
231 | * | ||
232 | * This function sends @data of length @len to the remote @dst address, | ||
233 | * and uses @src as the source address. | ||
234 | * The message will be sent to the remote processor which the @rpdev | ||
235 | * channel belongs to. | ||
236 | * In case there are no TX buffers available, the function will block until | ||
237 | * one becomes available, or a timeout of 15 seconds elapses. When the latter | ||
238 | * happens, -ERESTARTSYS is returned. | ||
239 | * | ||
240 | * Can only be called from process context (for now). | ||
241 | * | ||
242 | * Returns 0 on success and an appropriate error value on failure. | ||
243 | */ | ||
244 | static inline | ||
245 | int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
246 | void *data, int len) | ||
247 | { | ||
248 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * rpmsg_send() - send a message across to the remote processor | ||
253 | * @rpdev: the rpmsg channel | ||
254 | * @data: payload of message | ||
255 | * @len: length of payload | ||
256 | * | ||
257 | * This function sends @data of length @len on the @rpdev channel. | ||
258 | * The message will be sent to the remote processor which the @rpdev | ||
259 | * channel belongs to, using @rpdev's source and destination addresses. | ||
260 | * In case there are no TX buffers available, the function will immediately | ||
261 | * return -ENOMEM without waiting until one becomes available. | ||
262 | * | ||
263 | * Can only be called from process context (for now). | ||
264 | * | ||
265 | * Returns 0 on success and an appropriate error value on failure. | ||
266 | */ | ||
267 | static inline | ||
268 | int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) | ||
269 | { | ||
270 | u32 src = rpdev->src, dst = rpdev->dst; | ||
271 | |||
272 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * rpmsg_sendto() - send a message across to the remote processor, specify dst | ||
277 | * @rpdev: the rpmsg channel | ||
278 | * @data: payload of message | ||
279 | * @len: length of payload | ||
280 | * @dst: destination address | ||
281 | * | ||
282 | * This function sends @data of length @len to the remote @dst address. | ||
283 | * The message will be sent to the remote processor which the @rpdev | ||
284 | * channel belongs to, using @rpdev's source address. | ||
285 | * In case there are no TX buffers available, the function will immediately | ||
286 | * return -ENOMEM without waiting until one becomes available. | ||
287 | * | ||
288 | * Can only be called from process context (for now). | ||
289 | * | ||
290 | * Returns 0 on success and an appropriate error value on failure. | ||
291 | */ | ||
292 | static inline | ||
293 | int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) | ||
294 | { | ||
295 | u32 src = rpdev->src; | ||
296 | |||
297 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * rpmsg_send_offchannel() - send a message using explicit src/dst addresses | ||
302 | * @rpdev: the rpmsg channel | ||
303 | * @src: source address | ||
304 | * @dst: destination address | ||
305 | * @data: payload of message | ||
306 | * @len: length of payload | ||
307 | * | ||
308 | * This function sends @data of length @len to the remote @dst address, | ||
309 | * and uses @src as the source address. | ||
310 | * The message will be sent to the remote processor which the @rpdev | ||
311 | * channel belongs to. | ||
312 | * In case there are no TX buffers available, the function will immediately | ||
313 | * return -ENOMEM without waiting until one becomes available. | ||
314 | * | ||
315 | * Can only be called from process context (for now). | ||
316 | * | ||
317 | * Returns 0 on success and an appropriate error value on failure. | ||
318 | */ | ||
319 | static inline | ||
320 | int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
321 | void *data, int len) | ||
322 | { | ||
323 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | ||
324 | } | ||
325 | |||
326 | #endif /* _LINUX_RPMSG_H */ | ||
diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h index 85bb0bb66ffc..b37c5212265e 100644 --- a/include/linux/virtio_ids.h +++ b/include/linux/virtio_ids.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #define VIRTIO_ID_CONSOLE 3 /* virtio console */ | 34 | #define VIRTIO_ID_CONSOLE 3 /* virtio console */ |
35 | #define VIRTIO_ID_RNG 4 /* virtio ring */ | 35 | #define VIRTIO_ID_RNG 4 /* virtio ring */ |
36 | #define VIRTIO_ID_BALLOON 5 /* virtio balloon */ | 36 | #define VIRTIO_ID_BALLOON 5 /* virtio balloon */ |
37 | #define VIRTIO_ID_RPMSG 7 /* virtio remote processor messaging */ | ||
37 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ | 38 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ |
38 | 39 | ||
39 | #endif /* _LINUX_VIRTIO_IDS_H */ | 40 | #endif /* _LINUX_VIRTIO_IDS_H */ |
diff --git a/samples/Kconfig b/samples/Kconfig index 41063e7592d2..7b6792a18c05 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
@@ -61,4 +61,12 @@ config SAMPLE_KDB | |||
61 | Build an example of how to dynamically add the hello | 61 | Build an example of how to dynamically add the hello |
62 | command to the kdb shell. | 62 | command to the kdb shell. |
63 | 63 | ||
64 | config SAMPLE_RPMSG_CLIENT | ||
65 | tristate "Build rpmsg client sample -- loadable modules only" | ||
66 | depends on RPMSG && m | ||
67 | help | ||
68 | Build an rpmsg client sample driver, which demonstrates how | ||
69 | to communicate with an AMP-configured remote processor over | ||
70 | the rpmsg bus. | ||
71 | |||
64 | endif # SAMPLES | 72 | endif # SAMPLES |
diff --git a/samples/Makefile b/samples/Makefile index 6280817c2b7e..2f75851ec629 100644 --- a/samples/Makefile +++ b/samples/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # Makefile for Linux samples code | 1 | # Makefile for Linux samples code |
2 | 2 | ||
3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ | 3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ |
4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ | 4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ |
diff --git a/samples/rpmsg/Makefile b/samples/rpmsg/Makefile new file mode 100644 index 000000000000..2d4973c69663 --- /dev/null +++ b/samples/rpmsg/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_SAMPLE_RPMSG_CLIENT) += rpmsg_client_sample.o | |||
diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c new file mode 100644 index 000000000000..23ea9f2ae11d --- /dev/null +++ b/samples/rpmsg/rpmsg_client_sample.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Remote processor messaging - sample client driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2011 Google, Inc. | ||
6 | * | ||
7 | * Ohad Ben-Cohen <ohad@wizery.com> | ||
8 | * Brian Swetland <swetland@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/rpmsg.h> | ||
23 | |||
24 | #define MSG "hello world!" | ||
25 | #define MSG_LIMIT 100 | ||
26 | |||
27 | static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, | ||
28 | void *priv, u32 src) | ||
29 | { | ||
30 | int ret; | ||
31 | static int rx_count; | ||
32 | |||
33 | dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src); | ||
34 | |||
35 | print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, | ||
36 | data, len, true); | ||
37 | |||
38 | /* samples should not live forever */ | ||
39 | if (rx_count >= MSG_LIMIT) { | ||
40 | dev_info(&rpdev->dev, "goodbye!\n"); | ||
41 | return; | ||
42 | } | ||
43 | |||
44 | /* send a new message now */ | ||
45 | ret = rpmsg_send(rpdev, MSG, strlen(MSG)); | ||
46 | if (ret) | ||
47 | dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); | ||
48 | } | ||
49 | |||
50 | static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) | ||
51 | { | ||
52 | int ret; | ||
53 | |||
54 | dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", | ||
55 | rpdev->src, rpdev->dst); | ||
56 | |||
57 | /* send a message to our remote processor */ | ||
58 | ret = rpmsg_send(rpdev, MSG, strlen(MSG)); | ||
59 | if (ret) { | ||
60 | dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev) | ||
68 | { | ||
69 | dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n"); | ||
70 | } | ||
71 | |||
72 | static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = { | ||
73 | { .name = "rpmsg-client-sample" }, | ||
74 | { }, | ||
75 | }; | ||
76 | MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table); | ||
77 | |||
78 | static struct rpmsg_driver rpmsg_sample_client = { | ||
79 | .drv.name = KBUILD_MODNAME, | ||
80 | .drv.owner = THIS_MODULE, | ||
81 | .id_table = rpmsg_driver_sample_id_table, | ||
82 | .probe = rpmsg_sample_probe, | ||
83 | .callback = rpmsg_sample_cb, | ||
84 | .remove = __devexit_p(rpmsg_sample_remove), | ||
85 | }; | ||
86 | |||
87 | static int __init rpmsg_client_sample_init(void) | ||
88 | { | ||
89 | return register_rpmsg_driver(&rpmsg_sample_client); | ||
90 | } | ||
91 | module_init(rpmsg_client_sample_init); | ||
92 | |||
93 | static void __exit rpmsg_client_sample_fini(void) | ||
94 | { | ||
95 | unregister_rpmsg_driver(&rpmsg_sample_client); | ||
96 | } | ||
97 | module_exit(rpmsg_client_sample_fini); | ||
98 | |||
99 | MODULE_DESCRIPTION("Remote processor messaging sample client driver"); | ||
100 | MODULE_LICENSE("GPL v2"); | ||