diff options
26 files changed, 5182 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..70a048cd3fa3 --- /dev/null +++ b/Documentation/remoteproc.txt | |||
@@ -0,0 +1,322 @@ | |||
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 | Registration of other types of virtio devices is now also possible. Firmwares | ||
24 | just need to publish what kind of virtio devices do they support, and then | ||
25 | remoteproc will add those devices. This makes it possible to reuse the | ||
26 | existing virtio drivers with remote processor backends at a minimal development | ||
27 | cost. | ||
28 | |||
29 | 2. User API | ||
30 | |||
31 | int rproc_boot(struct rproc *rproc) | ||
32 | - Boot a remote processor (i.e. load its firmware, power it on, ...). | ||
33 | If the remote processor is already powered on, this function immediately | ||
34 | returns (successfully). | ||
35 | Returns 0 on success, and an appropriate error value otherwise. | ||
36 | Note: to use this function you should already have a valid rproc | ||
37 | handle. There are several ways to achieve that cleanly (devres, pdata, | ||
38 | the way remoteproc_rpmsg.c does this, or, if this becomes prevalent, we | ||
39 | might also consider using dev_archdata for this). See also | ||
40 | rproc_get_by_name() below. | ||
41 | |||
42 | void rproc_shutdown(struct rproc *rproc) | ||
43 | - Power off a remote processor (previously booted with rproc_boot()). | ||
44 | In case @rproc is still being used by an additional user(s), then | ||
45 | this function will just decrement the power refcount and exit, | ||
46 | without really powering off the device. | ||
47 | Every call to rproc_boot() must (eventually) be accompanied by a call | ||
48 | to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug. | ||
49 | Notes: | ||
50 | - we're not decrementing the rproc's refcount, only the power refcount. | ||
51 | which means that the @rproc handle stays valid even after | ||
52 | rproc_shutdown() returns, and users can still use it with a subsequent | ||
53 | rproc_boot(), if needed. | ||
54 | - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly | ||
55 | because rproc_shutdown() _does not_ decrement the refcount of @rproc. | ||
56 | To decrement the refcount of @rproc, use rproc_put() (but _only_ if | ||
57 | you acquired @rproc using rproc_get_by_name()). | ||
58 | |||
59 | struct rproc *rproc_get_by_name(const char *name) | ||
60 | - Find an rproc handle using the remote processor's name, and then | ||
61 | boot it. If it's already powered on, then just immediately return | ||
62 | (successfully). Returns the rproc handle on success, and NULL on failure. | ||
63 | This function increments the remote processor's refcount, so always | ||
64 | use rproc_put() to decrement it back once rproc isn't needed anymore. | ||
65 | Note: currently rproc_get_by_name() and rproc_put() are not used anymore | ||
66 | by the rpmsg bus and its drivers. We need to scrutinize the use cases | ||
67 | that still need them, and see if we can migrate them to use the non | ||
68 | name-based boot/shutdown interface. | ||
69 | |||
70 | void rproc_put(struct rproc *rproc) | ||
71 | - Decrement @rproc's power refcount and shut it down if it reaches zero | ||
72 | (essentially by just calling rproc_shutdown), and then decrement @rproc's | ||
73 | validity refcount too. | ||
74 | After this function returns, @rproc may _not_ be used anymore, and its | ||
75 | handle should be considered invalid. | ||
76 | This function should be called _iff_ the @rproc handle was grabbed by | ||
77 | calling rproc_get_by_name(). | ||
78 | |||
79 | 3. Typical usage | ||
80 | |||
81 | #include <linux/remoteproc.h> | ||
82 | |||
83 | /* in case we were given a valid 'rproc' handle */ | ||
84 | int dummy_rproc_example(struct rproc *my_rproc) | ||
85 | { | ||
86 | int ret; | ||
87 | |||
88 | /* let's power on and boot our remote processor */ | ||
89 | ret = rproc_boot(my_rproc); | ||
90 | if (ret) { | ||
91 | /* | ||
92 | * something went wrong. handle it and leave. | ||
93 | */ | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * our remote processor is now powered on... give it some work | ||
98 | */ | ||
99 | |||
100 | /* let's shut it down now */ | ||
101 | rproc_shutdown(my_rproc); | ||
102 | } | ||
103 | |||
104 | 4. API for implementors | ||
105 | |||
106 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
107 | const struct rproc_ops *ops, | ||
108 | const char *firmware, int len) | ||
109 | - Allocate a new remote processor handle, but don't register | ||
110 | it yet. Required parameters are the underlying device, the | ||
111 | name of this remote processor, platform-specific ops handlers, | ||
112 | the name of the firmware to boot this rproc with, and the | ||
113 | length of private data needed by the allocating rproc driver (in bytes). | ||
114 | |||
115 | This function should be used by rproc implementations during | ||
116 | initialization of the remote processor. | ||
117 | After creating an rproc handle using this function, and when ready, | ||
118 | implementations should then call rproc_register() to complete | ||
119 | the registration of the remote processor. | ||
120 | On success, the new rproc is returned, and on failure, NULL. | ||
121 | |||
122 | Note: _never_ directly deallocate @rproc, even if it was not registered | ||
123 | yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free(). | ||
124 | |||
125 | void rproc_free(struct rproc *rproc) | ||
126 | - Free an rproc handle that was allocated by rproc_alloc. | ||
127 | This function should _only_ be used if @rproc was only allocated, | ||
128 | but not registered yet. | ||
129 | If @rproc was already successfully registered (by calling | ||
130 | rproc_register()), then use rproc_unregister() instead. | ||
131 | |||
132 | int rproc_register(struct rproc *rproc) | ||
133 | - Register @rproc with the remoteproc framework, after it has been | ||
134 | allocated with rproc_alloc(). | ||
135 | This is called by the platform-specific rproc implementation, whenever | ||
136 | a new remote processor device is probed. | ||
137 | Returns 0 on success and an appropriate error code otherwise. | ||
138 | Note: this function initiates an asynchronous firmware loading | ||
139 | context, which will look for virtio devices supported by the rproc's | ||
140 | firmware. | ||
141 | If found, those virtio devices will be created and added, so as a result | ||
142 | of registering this remote processor, additional virtio drivers might get | ||
143 | probed. | ||
144 | |||
145 | int rproc_unregister(struct rproc *rproc) | ||
146 | - Unregister a remote processor, and decrement its refcount. | ||
147 | If its refcount drops to zero, then @rproc will be freed. If not, | ||
148 | it will be freed later once the last reference is dropped. | ||
149 | |||
150 | This function should be called when the platform specific rproc | ||
151 | implementation decides to remove the rproc device. it should | ||
152 | _only_ be called if a previous invocation of rproc_register() | ||
153 | has completed successfully. | ||
154 | |||
155 | After rproc_unregister() returns, @rproc is _not_ valid anymore and | ||
156 | it shouldn't be used. More specifically, don't call rproc_free() | ||
157 | or try to directly free @rproc after rproc_unregister() returns; | ||
158 | none of these are needed, and calling them is a bug. | ||
159 | |||
160 | Returns 0 on success and -EINVAL if @rproc isn't valid. | ||
161 | |||
162 | 5. Implementation callbacks | ||
163 | |||
164 | These callbacks should be provided by platform-specific remoteproc | ||
165 | drivers: | ||
166 | |||
167 | /** | ||
168 | * struct rproc_ops - platform-specific device handlers | ||
169 | * @start: power on the device and boot it | ||
170 | * @stop: power off the device | ||
171 | * @kick: kick a virtqueue (virtqueue id given as a parameter) | ||
172 | */ | ||
173 | struct rproc_ops { | ||
174 | int (*start)(struct rproc *rproc); | ||
175 | int (*stop)(struct rproc *rproc); | ||
176 | void (*kick)(struct rproc *rproc, int vqid); | ||
177 | }; | ||
178 | |||
179 | Every remoteproc implementation should at least provide the ->start and ->stop | ||
180 | handlers. If rpmsg/virtio functionality is also desired, then the ->kick handler | ||
181 | should be provided as well. | ||
182 | |||
183 | The ->start() handler takes an rproc handle and should then power on the | ||
184 | device and boot it (use rproc->priv to access platform-specific private data). | ||
185 | The boot address, in case needed, can be found in rproc->bootaddr (remoteproc | ||
186 | core puts there the ELF entry point). | ||
187 | On success, 0 should be returned, and on failure, an appropriate error code. | ||
188 | |||
189 | The ->stop() handler takes an rproc handle and powers the device down. | ||
190 | On success, 0 is returned, and on failure, an appropriate error code. | ||
191 | |||
192 | The ->kick() handler takes an rproc handle, and an index of a virtqueue | ||
193 | where new message was placed in. Implementations should interrupt the remote | ||
194 | processor and let it know it has pending messages. Notifying remote processors | ||
195 | the exact virtqueue index to look in is optional: it is easy (and not | ||
196 | too expensive) to go through the existing virtqueues and look for new buffers | ||
197 | in the used rings. | ||
198 | |||
199 | 6. Binary Firmware Structure | ||
200 | |||
201 | At this point remoteproc only supports ELF32 firmware binaries. However, | ||
202 | it is quite expected that other platforms/devices which we'd want to | ||
203 | support with this framework will be based on different binary formats. | ||
204 | |||
205 | When those use cases show up, we will have to decouple the binary format | ||
206 | from the framework core, so we can support several binary formats without | ||
207 | duplicating common code. | ||
208 | |||
209 | When the firmware is parsed, its various segments are loaded to memory | ||
210 | according to the specified device address (might be a physical address | ||
211 | if the remote processor is accessing memory directly). | ||
212 | |||
213 | In addition to the standard ELF segments, most remote processors would | ||
214 | also include a special section which we call "the resource table". | ||
215 | |||
216 | The resource table contains system resources that the remote processor | ||
217 | requires before it should be powered on, such as allocation of physically | ||
218 | contiguous memory, or iommu mapping of certain on-chip peripherals. | ||
219 | Remotecore will only power up the device after all the resource table's | ||
220 | requirement are met. | ||
221 | |||
222 | In addition to system resources, the resource table may also contain | ||
223 | resource entries that publish the existence of supported features | ||
224 | or configurations by the remote processor, such as trace buffers and | ||
225 | supported virtio devices (and their configurations). | ||
226 | |||
227 | The resource table begins with this header: | ||
228 | |||
229 | /** | ||
230 | * struct resource_table - firmware resource table header | ||
231 | * @ver: version number | ||
232 | * @num: number of resource entries | ||
233 | * @reserved: reserved (must be zero) | ||
234 | * @offset: array of offsets pointing at the various resource entries | ||
235 | * | ||
236 | * The header of the resource table, as expressed by this structure, | ||
237 | * contains a version number (should we need to change this format in the | ||
238 | * future), the number of available resource entries, and their offsets | ||
239 | * in the table. | ||
240 | */ | ||
241 | struct resource_table { | ||
242 | u32 ver; | ||
243 | u32 num; | ||
244 | u32 reserved[2]; | ||
245 | u32 offset[0]; | ||
246 | } __packed; | ||
247 | |||
248 | Immediately following this header are the resource entries themselves, | ||
249 | each of which begins with the following resource entry header: | ||
250 | |||
251 | /** | ||
252 | * struct fw_rsc_hdr - firmware resource entry header | ||
253 | * @type: resource type | ||
254 | * @data: resource data | ||
255 | * | ||
256 | * Every resource entry begins with a 'struct fw_rsc_hdr' header providing | ||
257 | * its @type. The content of the entry itself will immediately follow | ||
258 | * this header, and it should be parsed according to the resource type. | ||
259 | */ | ||
260 | struct fw_rsc_hdr { | ||
261 | u32 type; | ||
262 | u8 data[0]; | ||
263 | } __packed; | ||
264 | |||
265 | Some resources entries are mere announcements, where the host is informed | ||
266 | of specific remoteproc configuration. Other entries require the host to | ||
267 | do something (e.g. allocate a system resource). Sometimes a negotiation | ||
268 | is expected, where the firmware requests a resource, and once allocated, | ||
269 | the host should provide back its details (e.g. address of an allocated | ||
270 | memory region). | ||
271 | |||
272 | Here are the various resource types that are currently supported: | ||
273 | |||
274 | /** | ||
275 | * enum fw_resource_type - types of resource entries | ||
276 | * | ||
277 | * @RSC_CARVEOUT: request for allocation of a physically contiguous | ||
278 | * memory region. | ||
279 | * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. | ||
280 | * @RSC_TRACE: announces the availability of a trace buffer into which | ||
281 | * the remote processor will be writing logs. | ||
282 | * @RSC_VDEV: declare support for a virtio device, and serve as its | ||
283 | * virtio header. | ||
284 | * @RSC_LAST: just keep this one at the end | ||
285 | * | ||
286 | * Please note that these values are used as indices to the rproc_handle_rsc | ||
287 | * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to | ||
288 | * check the validity of an index before the lookup table is accessed, so | ||
289 | * please update it as needed. | ||
290 | */ | ||
291 | enum fw_resource_type { | ||
292 | RSC_CARVEOUT = 0, | ||
293 | RSC_DEVMEM = 1, | ||
294 | RSC_TRACE = 2, | ||
295 | RSC_VDEV = 3, | ||
296 | RSC_LAST = 4, | ||
297 | }; | ||
298 | |||
299 | For more details regarding a specific resource type, please see its | ||
300 | dedicated structure in include/linux/remoteproc.h. | ||
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_PLATFORM | ||
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_VDEV resource entry | ||
310 | should specify the virtio device id (as in virtio_ids.h), virtio features, | ||
311 | virtio config space, vrings information, etc. | ||
312 | |||
313 | When a new remote processor is registered, the remoteproc framework | ||
314 | will look for its resource table and will register the virtio devices | ||
315 | it supports. A firmware may support any number of virtio devices, and | ||
316 | of any type (a single remote processor can also easily support several | ||
317 | rpmsg virtio devices this way, if desired). | ||
318 | |||
319 | Of course, RSC_VDEV resource entries are only good enough for static | ||
320 | allocation of virtio devices. Dynamic allocations will also be made possible | ||
321 | using the rpmsg bus (similar to how we already do dynamic allocations of | ||
322 | 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 0755fe6c4e3b..3d11fa581bb7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5634,6 +5634,13 @@ S: Supported | |||
5634 | F: drivers/base/regmap/ | 5634 | F: drivers/base/regmap/ |
5635 | F: include/linux/regmap.h | 5635 | F: include/linux/regmap.h |
5636 | 5636 | ||
5637 | REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM | ||
5638 | M: Ohad Ben-Cohen <ohad@wizery.com> | ||
5639 | S: Maintained | ||
5640 | F: drivers/remoteproc/ | ||
5641 | F: Documentation/remoteproc.txt | ||
5642 | F: include/linux/remoteproc.txt | ||
5643 | |||
5637 | RFKILL | 5644 | RFKILL |
5638 | M: Johannes Berg <johannes@sipsolutions.net> | 5645 | M: Johannes Berg <johannes@sipsolutions.net> |
5639 | L: linux-wireless@vger.kernel.org | 5646 | 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 decf8e420856..6f0459cb745b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -130,6 +130,10 @@ source "drivers/clocksource/Kconfig" | |||
130 | 130 | ||
131 | source "drivers/iommu/Kconfig" | 131 | source "drivers/iommu/Kconfig" |
132 | 132 | ||
133 | source "drivers/remoteproc/Kconfig" | ||
134 | |||
135 | source "drivers/rpmsg/Kconfig" | ||
136 | |||
133 | source "drivers/virt/Kconfig" | 137 | source "drivers/virt/Kconfig" |
134 | 138 | ||
135 | source "drivers/devfreq/Kconfig" | 139 | source "drivers/devfreq/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index 932e8bf20356..262b19d6b627 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -125,6 +125,8 @@ obj-y += clk/ | |||
125 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ | 125 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ |
126 | obj-$(CONFIG_NFC) += nfc/ | 126 | obj-$(CONFIG_NFC) += nfc/ |
127 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | 127 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ |
128 | obj-$(CONFIG_REMOTEPROC) += remoteproc/ | ||
129 | obj-$(CONFIG_RPMSG) += rpmsg/ | ||
128 | 130 | ||
129 | # Virtualization drivers | 131 | # Virtualization drivers |
130 | obj-$(CONFIG_VIRT_DRIVERS) += virt/ | 132 | obj-$(CONFIG_VIRT_DRIVERS) += virt/ |
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig new file mode 100644 index 000000000000..24d880e78ec6 --- /dev/null +++ b/drivers/remoteproc/Kconfig | |||
@@ -0,0 +1,28 @@ | |||
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 | depends on OMAP_IOMMU | ||
12 | select REMOTEPROC | ||
13 | select OMAP_MBOX_FWK | ||
14 | select RPMSG | ||
15 | help | ||
16 | Say y here to support OMAP's remote processors (dual M3 | ||
17 | and DSP on OMAP4) via the remote processor framework. | ||
18 | |||
19 | Currently only supported on OMAP4. | ||
20 | |||
21 | Usually you want to say y here, in order to enable multimedia | ||
22 | use-cases to run on your platform (multimedia codecs are | ||
23 | offloaded to remote DSP processors using this framework). | ||
24 | |||
25 | It's safe to say n here if you're not interested in multimedia | ||
26 | offloading or just want a bare minimum kernel. | ||
27 | |||
28 | endmenu | ||
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile new file mode 100644 index 000000000000..5445d9b23294 --- /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_virtio.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..69425c4e86f3 --- /dev/null +++ b/drivers/remoteproc/omap_remoteproc.c | |||
@@ -0,0 +1,229 @@ | |||
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 | /* msg contains the index of the triggered vring */ | ||
84 | if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE) | ||
85 | dev_dbg(dev, "no message was found in vqid %d\n", msg); | ||
86 | } | ||
87 | |||
88 | return NOTIFY_DONE; | ||
89 | } | ||
90 | |||
91 | /* kick a virtqueue */ | ||
92 | static void omap_rproc_kick(struct rproc *rproc, int vqid) | ||
93 | { | ||
94 | struct omap_rproc *oproc = rproc->priv; | ||
95 | int ret; | ||
96 | |||
97 | /* send the index of the triggered virtqueue in the mailbox payload */ | ||
98 | ret = omap_mbox_msg_send(oproc->mbox, vqid); | ||
99 | if (ret) | ||
100 | dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * Power up the remote processor. | ||
105 | * | ||
106 | * This function will be invoked only after the firmware for this rproc | ||
107 | * was loaded, parsed successfully, and all of its resource requirements | ||
108 | * were met. | ||
109 | */ | ||
110 | static int omap_rproc_start(struct rproc *rproc) | ||
111 | { | ||
112 | struct omap_rproc *oproc = rproc->priv; | ||
113 | struct platform_device *pdev = to_platform_device(rproc->dev); | ||
114 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
115 | int ret; | ||
116 | |||
117 | oproc->nb.notifier_call = omap_rproc_mbox_callback; | ||
118 | |||
119 | /* every omap rproc is assigned a mailbox instance for messaging */ | ||
120 | oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb); | ||
121 | if (IS_ERR(oproc->mbox)) { | ||
122 | ret = PTR_ERR(oproc->mbox); | ||
123 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Ping the remote processor. this is only for sanity-sake; | ||
129 | * there is no functional effect whatsoever. | ||
130 | * | ||
131 | * Note that the reply will _not_ arrive immediately: this message | ||
132 | * will wait in the mailbox fifo until the remote processor is booted. | ||
133 | */ | ||
134 | ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST); | ||
135 | if (ret) { | ||
136 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | ||
137 | goto put_mbox; | ||
138 | } | ||
139 | |||
140 | ret = pdata->device_enable(pdev); | ||
141 | if (ret) { | ||
142 | dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret); | ||
143 | goto put_mbox; | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | |||
148 | put_mbox: | ||
149 | omap_mbox_put(oproc->mbox, &oproc->nb); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | /* power off the remote processor */ | ||
154 | static int omap_rproc_stop(struct rproc *rproc) | ||
155 | { | ||
156 | struct platform_device *pdev = to_platform_device(rproc->dev); | ||
157 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
158 | struct omap_rproc *oproc = rproc->priv; | ||
159 | int ret; | ||
160 | |||
161 | ret = pdata->device_shutdown(pdev); | ||
162 | if (ret) | ||
163 | return ret; | ||
164 | |||
165 | omap_mbox_put(oproc->mbox, &oproc->nb); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct rproc_ops omap_rproc_ops = { | ||
171 | .start = omap_rproc_start, | ||
172 | .stop = omap_rproc_stop, | ||
173 | .kick = omap_rproc_kick, | ||
174 | }; | ||
175 | |||
176 | static int __devinit omap_rproc_probe(struct platform_device *pdev) | ||
177 | { | ||
178 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | ||
179 | struct omap_rproc *oproc; | ||
180 | struct rproc *rproc; | ||
181 | int ret; | ||
182 | |||
183 | ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | ||
184 | if (ret) { | ||
185 | dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops, | ||
190 | pdata->firmware, sizeof(*oproc)); | ||
191 | if (!rproc) | ||
192 | return -ENOMEM; | ||
193 | |||
194 | oproc = rproc->priv; | ||
195 | oproc->rproc = rproc; | ||
196 | |||
197 | platform_set_drvdata(pdev, rproc); | ||
198 | |||
199 | ret = rproc_register(rproc); | ||
200 | if (ret) | ||
201 | goto free_rproc; | ||
202 | |||
203 | return 0; | ||
204 | |||
205 | free_rproc: | ||
206 | rproc_free(rproc); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | static int __devexit omap_rproc_remove(struct platform_device *pdev) | ||
211 | { | ||
212 | struct rproc *rproc = platform_get_drvdata(pdev); | ||
213 | |||
214 | return rproc_unregister(rproc); | ||
215 | } | ||
216 | |||
217 | static struct platform_driver omap_rproc_driver = { | ||
218 | .probe = omap_rproc_probe, | ||
219 | .remove = __devexit_p(omap_rproc_remove), | ||
220 | .driver = { | ||
221 | .name = "omap-rproc", | ||
222 | .owner = THIS_MODULE, | ||
223 | }, | ||
224 | }; | ||
225 | |||
226 | module_platform_driver(omap_rproc_driver); | ||
227 | |||
228 | MODULE_LICENSE("GPL v2"); | ||
229 | 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..ee15c68fb519 --- /dev/null +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -0,0 +1,1586 @@ | |||
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() at this point. | ||
56 | * 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 resource_table *table, int len); | ||
67 | typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail); | ||
68 | |||
69 | /* | ||
70 | * This is the IOMMU fault handler we register with the IOMMU API | ||
71 | * (when relevant; not all remote processors access memory through | ||
72 | * an IOMMU). | ||
73 | * | ||
74 | * IOMMU core will invoke this handler whenever the remote processor | ||
75 | * will try to access an unmapped device address. | ||
76 | * | ||
77 | * Currently this is mostly a stub, but it will be later used to trigger | ||
78 | * the recovery of the remote processor. | ||
79 | */ | ||
80 | static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, | ||
81 | unsigned long iova, int flags) | ||
82 | { | ||
83 | dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags); | ||
84 | |||
85 | /* | ||
86 | * Let the iommu core know we're not really handling this fault; | ||
87 | * we just plan to use this as a recovery trigger. | ||
88 | */ | ||
89 | return -ENOSYS; | ||
90 | } | ||
91 | |||
92 | static int rproc_enable_iommu(struct rproc *rproc) | ||
93 | { | ||
94 | struct iommu_domain *domain; | ||
95 | struct device *dev = rproc->dev; | ||
96 | int ret; | ||
97 | |||
98 | /* | ||
99 | * We currently use iommu_present() to decide if an IOMMU | ||
100 | * setup is needed. | ||
101 | * | ||
102 | * This works for simple cases, but will easily fail with | ||
103 | * platforms that do have an IOMMU, but not for this specific | ||
104 | * rproc. | ||
105 | * | ||
106 | * This will be easily solved by introducing hw capabilities | ||
107 | * that will be set by the remoteproc driver. | ||
108 | */ | ||
109 | if (!iommu_present(dev->bus)) { | ||
110 | dev_dbg(dev, "iommu not found\n"); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | domain = iommu_domain_alloc(dev->bus); | ||
115 | if (!domain) { | ||
116 | dev_err(dev, "can't alloc iommu domain\n"); | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | |||
120 | iommu_set_fault_handler(domain, rproc_iommu_fault); | ||
121 | |||
122 | ret = iommu_attach_device(domain, dev); | ||
123 | if (ret) { | ||
124 | dev_err(dev, "can't attach iommu device: %d\n", ret); | ||
125 | goto free_domain; | ||
126 | } | ||
127 | |||
128 | rproc->domain = domain; | ||
129 | |||
130 | return 0; | ||
131 | |||
132 | free_domain: | ||
133 | iommu_domain_free(domain); | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static void rproc_disable_iommu(struct rproc *rproc) | ||
138 | { | ||
139 | struct iommu_domain *domain = rproc->domain; | ||
140 | struct device *dev = rproc->dev; | ||
141 | |||
142 | if (!domain) | ||
143 | return; | ||
144 | |||
145 | iommu_detach_device(domain, dev); | ||
146 | iommu_domain_free(domain); | ||
147 | |||
148 | return; | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * Some remote processors will ask us to allocate them physically contiguous | ||
153 | * memory regions (which we call "carveouts"), and map them to specific | ||
154 | * device addresses (which are hardcoded in the firmware). | ||
155 | * | ||
156 | * They may then ask us to copy objects into specific device addresses (e.g. | ||
157 | * code/data sections) or expose us certain symbols in other device address | ||
158 | * (e.g. their trace buffer). | ||
159 | * | ||
160 | * This function is an internal helper with which we can go over the allocated | ||
161 | * carveouts and translate specific device address to kernel virtual addresses | ||
162 | * so we can access the referenced memory. | ||
163 | * | ||
164 | * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too, | ||
165 | * but only on kernel direct mapped RAM memory. Instead, we're just using | ||
166 | * here the output of the DMA API, which should be more correct. | ||
167 | */ | ||
168 | static void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) | ||
169 | { | ||
170 | struct rproc_mem_entry *carveout; | ||
171 | void *ptr = NULL; | ||
172 | |||
173 | list_for_each_entry(carveout, &rproc->carveouts, node) { | ||
174 | int offset = da - carveout->da; | ||
175 | |||
176 | /* try next carveout if da is too small */ | ||
177 | if (offset < 0) | ||
178 | continue; | ||
179 | |||
180 | /* try next carveout if da is too large */ | ||
181 | if (offset + len > carveout->len) | ||
182 | continue; | ||
183 | |||
184 | ptr = carveout->va + offset; | ||
185 | |||
186 | break; | ||
187 | } | ||
188 | |||
189 | return ptr; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * rproc_load_segments() - load firmware segments to memory | ||
194 | * @rproc: remote processor which will be booted using these fw segments | ||
195 | * @elf_data: the content of the ELF firmware image | ||
196 | * @len: firmware size (in bytes) | ||
197 | * | ||
198 | * This function loads the firmware segments to memory, where the remote | ||
199 | * processor expects them. | ||
200 | * | ||
201 | * Some remote processors will expect their code and data to be placed | ||
202 | * in specific device addresses, and can't have them dynamically assigned. | ||
203 | * | ||
204 | * We currently support only those kind of remote processors, and expect | ||
205 | * the program header's paddr member to contain those addresses. We then go | ||
206 | * through the physically contiguous "carveout" memory regions which we | ||
207 | * allocated (and mapped) earlier on behalf of the remote processor, | ||
208 | * and "translate" device address to kernel addresses, so we can copy the | ||
209 | * segments where they are expected. | ||
210 | * | ||
211 | * Currently we only support remote processors that required carveout | ||
212 | * allocations and got them mapped onto their iommus. Some processors | ||
213 | * might be different: they might not have iommus, and would prefer to | ||
214 | * directly allocate memory for every segment/resource. This is not yet | ||
215 | * supported, though. | ||
216 | */ | ||
217 | static int | ||
218 | rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) | ||
219 | { | ||
220 | struct device *dev = rproc->dev; | ||
221 | struct elf32_hdr *ehdr; | ||
222 | struct elf32_phdr *phdr; | ||
223 | int i, ret = 0; | ||
224 | |||
225 | ehdr = (struct elf32_hdr *)elf_data; | ||
226 | phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff); | ||
227 | |||
228 | /* go through the available ELF segments */ | ||
229 | for (i = 0; i < ehdr->e_phnum; i++, phdr++) { | ||
230 | u32 da = phdr->p_paddr; | ||
231 | u32 memsz = phdr->p_memsz; | ||
232 | u32 filesz = phdr->p_filesz; | ||
233 | u32 offset = phdr->p_offset; | ||
234 | void *ptr; | ||
235 | |||
236 | if (phdr->p_type != PT_LOAD) | ||
237 | continue; | ||
238 | |||
239 | dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", | ||
240 | phdr->p_type, da, memsz, filesz); | ||
241 | |||
242 | if (filesz > memsz) { | ||
243 | dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", | ||
244 | filesz, memsz); | ||
245 | ret = -EINVAL; | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | if (offset + filesz > len) { | ||
250 | dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", | ||
251 | offset + filesz, len); | ||
252 | ret = -EINVAL; | ||
253 | break; | ||
254 | } | ||
255 | |||
256 | /* grab the kernel address for this device address */ | ||
257 | ptr = rproc_da_to_va(rproc, da, memsz); | ||
258 | if (!ptr) { | ||
259 | dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz); | ||
260 | ret = -EINVAL; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | /* put the segment where the remote processor expects it */ | ||
265 | if (phdr->p_filesz) | ||
266 | memcpy(ptr, elf_data + phdr->p_offset, filesz); | ||
267 | |||
268 | /* | ||
269 | * Zero out remaining memory for this segment. | ||
270 | * | ||
271 | * This isn't strictly required since dma_alloc_coherent already | ||
272 | * did this for us. albeit harmless, we may consider removing | ||
273 | * this. | ||
274 | */ | ||
275 | if (memsz > filesz) | ||
276 | memset(ptr + filesz, 0, memsz - filesz); | ||
277 | } | ||
278 | |||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static int | ||
283 | __rproc_handle_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) | ||
284 | { | ||
285 | struct rproc *rproc = rvdev->rproc; | ||
286 | struct device *dev = rproc->dev; | ||
287 | struct fw_rsc_vdev_vring *vring = &rsc->vring[i]; | ||
288 | dma_addr_t dma; | ||
289 | void *va; | ||
290 | int ret, size, notifyid; | ||
291 | |||
292 | dev_dbg(dev, "vdev rsc: vring%d: da %x, qsz %d, align %d\n", | ||
293 | i, vring->da, vring->num, vring->align); | ||
294 | |||
295 | /* make sure reserved bytes are zeroes */ | ||
296 | if (vring->reserved) { | ||
297 | dev_err(dev, "vring rsc has non zero reserved bytes\n"); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | |||
301 | /* verify queue size and vring alignment are sane */ | ||
302 | if (!vring->num || !vring->align) { | ||
303 | dev_err(dev, "invalid qsz (%d) or alignment (%d)\n", | ||
304 | vring->num, vring->align); | ||
305 | return -EINVAL; | ||
306 | } | ||
307 | |||
308 | /* actual size of vring (in bytes) */ | ||
309 | size = PAGE_ALIGN(vring_size(vring->num, vring->align)); | ||
310 | |||
311 | if (!idr_pre_get(&rproc->notifyids, GFP_KERNEL)) { | ||
312 | dev_err(dev, "idr_pre_get failed\n"); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * Allocate non-cacheable memory for the vring. In the future | ||
318 | * this call will also configure the IOMMU for us | ||
319 | */ | ||
320 | va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL); | ||
321 | if (!va) { | ||
322 | dev_err(dev, "dma_alloc_coherent failed\n"); | ||
323 | return -EINVAL; | ||
324 | } | ||
325 | |||
326 | /* assign an rproc-wide unique index for this vring */ | ||
327 | /* TODO: assign a notifyid for rvdev updates as well */ | ||
328 | ret = idr_get_new(&rproc->notifyids, &rvdev->vring[i], ¬ifyid); | ||
329 | if (ret) { | ||
330 | dev_err(dev, "idr_get_new failed: %d\n", ret); | ||
331 | dma_free_coherent(dev, size, va, dma); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | /* let the rproc know the da and notifyid of this vring */ | ||
336 | /* TODO: expose this to remote processor */ | ||
337 | vring->da = dma; | ||
338 | vring->notifyid = notifyid; | ||
339 | |||
340 | dev_dbg(dev, "vring%d: va %p dma %x size %x idr %d\n", i, va, | ||
341 | dma, size, notifyid); | ||
342 | |||
343 | rvdev->vring[i].len = vring->num; | ||
344 | rvdev->vring[i].align = vring->align; | ||
345 | rvdev->vring[i].va = va; | ||
346 | rvdev->vring[i].dma = dma; | ||
347 | rvdev->vring[i].notifyid = notifyid; | ||
348 | rvdev->vring[i].rvdev = rvdev; | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static void __rproc_free_vrings(struct rproc_vdev *rvdev, int i) | ||
354 | { | ||
355 | struct rproc *rproc = rvdev->rproc; | ||
356 | |||
357 | for (i--; i > 0; i--) { | ||
358 | struct rproc_vring *rvring = &rvdev->vring[i]; | ||
359 | int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align)); | ||
360 | |||
361 | dma_free_coherent(rproc->dev, size, rvring->va, rvring->dma); | ||
362 | idr_remove(&rproc->notifyids, rvring->notifyid); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * rproc_handle_vdev() - handle a vdev fw resource | ||
368 | * @rproc: the remote processor | ||
369 | * @rsc: the vring resource descriptor | ||
370 | * @avail: size of available data (for sanity checking the image) | ||
371 | * | ||
372 | * This resource entry requests the host to statically register a virtio | ||
373 | * device (vdev), and setup everything needed to support it. It contains | ||
374 | * everything needed to make it possible: the virtio device id, virtio | ||
375 | * device features, vrings information, virtio config space, etc... | ||
376 | * | ||
377 | * Before registering the vdev, the vrings are allocated from non-cacheable | ||
378 | * physically contiguous memory. Currently we only support two vrings per | ||
379 | * remote processor (temporary limitation). We might also want to consider | ||
380 | * doing the vring allocation only later when ->find_vqs() is invoked, and | ||
381 | * then release them upon ->del_vqs(). | ||
382 | * | ||
383 | * Note: @da is currently not really handled correctly: we dynamically | ||
384 | * allocate it using the DMA API, ignoring requested hard coded addresses, | ||
385 | * and we don't take care of any required IOMMU programming. This is all | ||
386 | * going to be taken care of when the generic iommu-based DMA API will be | ||
387 | * merged. Meanwhile, statically-addressed iommu-based firmware images should | ||
388 | * use RSC_DEVMEM resource entries to map their required @da to the physical | ||
389 | * address of their base CMA region (ouch, hacky!). | ||
390 | * | ||
391 | * Returns 0 on success, or an appropriate error code otherwise | ||
392 | */ | ||
393 | static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, | ||
394 | int avail) | ||
395 | { | ||
396 | struct device *dev = rproc->dev; | ||
397 | struct rproc_vdev *rvdev; | ||
398 | int i, ret; | ||
399 | |||
400 | /* make sure resource isn't truncated */ | ||
401 | if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring) | ||
402 | + rsc->config_len > avail) { | ||
403 | dev_err(rproc->dev, "vdev rsc is truncated\n"); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | |||
407 | /* make sure reserved bytes are zeroes */ | ||
408 | if (rsc->reserved[0] || rsc->reserved[1]) { | ||
409 | dev_err(dev, "vdev rsc has non zero reserved bytes\n"); | ||
410 | return -EINVAL; | ||
411 | } | ||
412 | |||
413 | dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n", | ||
414 | rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings); | ||
415 | |||
416 | /* we currently support only two vrings per rvdev */ | ||
417 | if (rsc->num_of_vrings > ARRAY_SIZE(rvdev->vring)) { | ||
418 | dev_err(dev, "too many vrings: %d\n", rsc->num_of_vrings); | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL); | ||
423 | if (!rvdev) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | rvdev->rproc = rproc; | ||
427 | |||
428 | /* allocate the vrings */ | ||
429 | for (i = 0; i < rsc->num_of_vrings; i++) { | ||
430 | ret = __rproc_handle_vring(rvdev, rsc, i); | ||
431 | if (ret) | ||
432 | goto free_vrings; | ||
433 | } | ||
434 | |||
435 | /* remember the device features */ | ||
436 | rvdev->dfeatures = rsc->dfeatures; | ||
437 | |||
438 | list_add_tail(&rvdev->node, &rproc->rvdevs); | ||
439 | |||
440 | /* it is now safe to add the virtio device */ | ||
441 | ret = rproc_add_virtio_dev(rvdev, rsc->id); | ||
442 | if (ret) | ||
443 | goto free_vrings; | ||
444 | |||
445 | return 0; | ||
446 | |||
447 | free_vrings: | ||
448 | __rproc_free_vrings(rvdev, i); | ||
449 | kfree(rvdev); | ||
450 | return ret; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * rproc_handle_trace() - handle a shared trace buffer resource | ||
455 | * @rproc: the remote processor | ||
456 | * @rsc: the trace resource descriptor | ||
457 | * @avail: size of available data (for sanity checking the image) | ||
458 | * | ||
459 | * In case the remote processor dumps trace logs into memory, | ||
460 | * export it via debugfs. | ||
461 | * | ||
462 | * Currently, the 'da' member of @rsc should contain the device address | ||
463 | * where the remote processor is dumping the traces. Later we could also | ||
464 | * support dynamically allocating this address using the generic | ||
465 | * DMA API (but currently there isn't a use case for that). | ||
466 | * | ||
467 | * Returns 0 on success, or an appropriate error code otherwise | ||
468 | */ | ||
469 | static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, | ||
470 | int avail) | ||
471 | { | ||
472 | struct rproc_mem_entry *trace; | ||
473 | struct device *dev = rproc->dev; | ||
474 | void *ptr; | ||
475 | char name[15]; | ||
476 | |||
477 | if (sizeof(*rsc) > avail) { | ||
478 | dev_err(rproc->dev, "trace rsc is truncated\n"); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | /* make sure reserved bytes are zeroes */ | ||
483 | if (rsc->reserved) { | ||
484 | dev_err(dev, "trace rsc has non zero reserved bytes\n"); | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
488 | /* what's the kernel address of this resource ? */ | ||
489 | ptr = rproc_da_to_va(rproc, rsc->da, rsc->len); | ||
490 | if (!ptr) { | ||
491 | dev_err(dev, "erroneous trace resource entry\n"); | ||
492 | return -EINVAL; | ||
493 | } | ||
494 | |||
495 | trace = kzalloc(sizeof(*trace), GFP_KERNEL); | ||
496 | if (!trace) { | ||
497 | dev_err(dev, "kzalloc trace failed\n"); | ||
498 | return -ENOMEM; | ||
499 | } | ||
500 | |||
501 | /* set the trace buffer dma properties */ | ||
502 | trace->len = rsc->len; | ||
503 | trace->va = ptr; | ||
504 | |||
505 | /* make sure snprintf always null terminates, even if truncating */ | ||
506 | snprintf(name, sizeof(name), "trace%d", rproc->num_traces); | ||
507 | |||
508 | /* create the debugfs entry */ | ||
509 | trace->priv = rproc_create_trace_file(name, rproc, trace); | ||
510 | if (!trace->priv) { | ||
511 | trace->va = NULL; | ||
512 | kfree(trace); | ||
513 | return -EINVAL; | ||
514 | } | ||
515 | |||
516 | list_add_tail(&trace->node, &rproc->traces); | ||
517 | |||
518 | rproc->num_traces++; | ||
519 | |||
520 | dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr, | ||
521 | rsc->da, rsc->len); | ||
522 | |||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /** | ||
527 | * rproc_handle_devmem() - handle devmem resource entry | ||
528 | * @rproc: remote processor handle | ||
529 | * @rsc: the devmem resource entry | ||
530 | * @avail: size of available data (for sanity checking the image) | ||
531 | * | ||
532 | * Remote processors commonly need to access certain on-chip peripherals. | ||
533 | * | ||
534 | * Some of these remote processors access memory via an iommu device, | ||
535 | * and might require us to configure their iommu before they can access | ||
536 | * the on-chip peripherals they need. | ||
537 | * | ||
538 | * This resource entry is a request to map such a peripheral device. | ||
539 | * | ||
540 | * These devmem entries will contain the physical address of the device in | ||
541 | * the 'pa' member. If a specific device address is expected, then 'da' will | ||
542 | * contain it (currently this is the only use case supported). 'len' will | ||
543 | * contain the size of the physical region we need to map. | ||
544 | * | ||
545 | * Currently we just "trust" those devmem entries to contain valid physical | ||
546 | * addresses, but this is going to change: we want the implementations to | ||
547 | * tell us ranges of physical addresses the firmware is allowed to request, | ||
548 | * and not allow firmwares to request access to physical addresses that | ||
549 | * are outside those ranges. | ||
550 | */ | ||
551 | static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc, | ||
552 | int avail) | ||
553 | { | ||
554 | struct rproc_mem_entry *mapping; | ||
555 | int ret; | ||
556 | |||
557 | /* no point in handling this resource without a valid iommu domain */ | ||
558 | if (!rproc->domain) | ||
559 | return -EINVAL; | ||
560 | |||
561 | if (sizeof(*rsc) > avail) { | ||
562 | dev_err(rproc->dev, "devmem rsc is truncated\n"); | ||
563 | return -EINVAL; | ||
564 | } | ||
565 | |||
566 | /* make sure reserved bytes are zeroes */ | ||
567 | if (rsc->reserved) { | ||
568 | dev_err(rproc->dev, "devmem rsc has non zero reserved bytes\n"); | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); | ||
573 | if (!mapping) { | ||
574 | dev_err(rproc->dev, "kzalloc mapping failed\n"); | ||
575 | return -ENOMEM; | ||
576 | } | ||
577 | |||
578 | ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags); | ||
579 | if (ret) { | ||
580 | dev_err(rproc->dev, "failed to map devmem: %d\n", ret); | ||
581 | goto out; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * We'll need this info later when we'll want to unmap everything | ||
586 | * (e.g. on shutdown). | ||
587 | * | ||
588 | * We can't trust the remote processor not to change the resource | ||
589 | * table, so we must maintain this info independently. | ||
590 | */ | ||
591 | mapping->da = rsc->da; | ||
592 | mapping->len = rsc->len; | ||
593 | list_add_tail(&mapping->node, &rproc->mappings); | ||
594 | |||
595 | dev_dbg(rproc->dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n", | ||
596 | rsc->pa, rsc->da, rsc->len); | ||
597 | |||
598 | return 0; | ||
599 | |||
600 | out: | ||
601 | kfree(mapping); | ||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | /** | ||
606 | * rproc_handle_carveout() - handle phys contig memory allocation requests | ||
607 | * @rproc: rproc handle | ||
608 | * @rsc: the resource entry | ||
609 | * @avail: size of available data (for image validation) | ||
610 | * | ||
611 | * This function will handle firmware requests for allocation of physically | ||
612 | * contiguous memory regions. | ||
613 | * | ||
614 | * These request entries should come first in the firmware's resource table, | ||
615 | * as other firmware entries might request placing other data objects inside | ||
616 | * these memory regions (e.g. data/code segments, trace resource entries, ...). | ||
617 | * | ||
618 | * Allocating memory this way helps utilizing the reserved physical memory | ||
619 | * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries | ||
620 | * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB | ||
621 | * pressure is important; it may have a substantial impact on performance. | ||
622 | */ | ||
623 | static int rproc_handle_carveout(struct rproc *rproc, | ||
624 | struct fw_rsc_carveout *rsc, int avail) | ||
625 | { | ||
626 | struct rproc_mem_entry *carveout, *mapping; | ||
627 | struct device *dev = rproc->dev; | ||
628 | dma_addr_t dma; | ||
629 | void *va; | ||
630 | int ret; | ||
631 | |||
632 | if (sizeof(*rsc) > avail) { | ||
633 | dev_err(rproc->dev, "carveout rsc is truncated\n"); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | /* make sure reserved bytes are zeroes */ | ||
638 | if (rsc->reserved) { | ||
639 | dev_err(dev, "carveout rsc has non zero reserved bytes\n"); | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | |||
643 | dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n", | ||
644 | rsc->da, rsc->pa, rsc->len, rsc->flags); | ||
645 | |||
646 | mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); | ||
647 | if (!mapping) { | ||
648 | dev_err(dev, "kzalloc mapping failed\n"); | ||
649 | return -ENOMEM; | ||
650 | } | ||
651 | |||
652 | carveout = kzalloc(sizeof(*carveout), GFP_KERNEL); | ||
653 | if (!carveout) { | ||
654 | dev_err(dev, "kzalloc carveout failed\n"); | ||
655 | ret = -ENOMEM; | ||
656 | goto free_mapping; | ||
657 | } | ||
658 | |||
659 | va = dma_alloc_coherent(dev, rsc->len, &dma, GFP_KERNEL); | ||
660 | if (!va) { | ||
661 | dev_err(dev, "failed to dma alloc carveout: %d\n", rsc->len); | ||
662 | ret = -ENOMEM; | ||
663 | goto free_carv; | ||
664 | } | ||
665 | |||
666 | dev_dbg(dev, "carveout va %p, dma %x, len 0x%x\n", va, dma, rsc->len); | ||
667 | |||
668 | /* | ||
669 | * Ok, this is non-standard. | ||
670 | * | ||
671 | * Sometimes we can't rely on the generic iommu-based DMA API | ||
672 | * to dynamically allocate the device address and then set the IOMMU | ||
673 | * tables accordingly, because some remote processors might | ||
674 | * _require_ us to use hard coded device addresses that their | ||
675 | * firmware was compiled with. | ||
676 | * | ||
677 | * In this case, we must use the IOMMU API directly and map | ||
678 | * the memory to the device address as expected by the remote | ||
679 | * processor. | ||
680 | * | ||
681 | * Obviously such remote processor devices should not be configured | ||
682 | * to use the iommu-based DMA API: we expect 'dma' to contain the | ||
683 | * physical address in this case. | ||
684 | */ | ||
685 | if (rproc->domain) { | ||
686 | ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len, | ||
687 | rsc->flags); | ||
688 | if (ret) { | ||
689 | dev_err(dev, "iommu_map failed: %d\n", ret); | ||
690 | goto dma_free; | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * We'll need this info later when we'll want to unmap | ||
695 | * everything (e.g. on shutdown). | ||
696 | * | ||
697 | * We can't trust the remote processor not to change the | ||
698 | * resource table, so we must maintain this info independently. | ||
699 | */ | ||
700 | mapping->da = rsc->da; | ||
701 | mapping->len = rsc->len; | ||
702 | list_add_tail(&mapping->node, &rproc->mappings); | ||
703 | |||
704 | dev_dbg(dev, "carveout mapped 0x%x to 0x%x\n", rsc->da, dma); | ||
705 | |||
706 | /* | ||
707 | * Some remote processors might need to know the pa | ||
708 | * even though they are behind an IOMMU. E.g., OMAP4's | ||
709 | * remote M3 processor needs this so it can control | ||
710 | * on-chip hardware accelerators that are not behind | ||
711 | * the IOMMU, and therefor must know the pa. | ||
712 | * | ||
713 | * Generally we don't want to expose physical addresses | ||
714 | * if we don't have to (remote processors are generally | ||
715 | * _not_ trusted), so we might want to do this only for | ||
716 | * remote processor that _must_ have this (e.g. OMAP4's | ||
717 | * dual M3 subsystem). | ||
718 | */ | ||
719 | rsc->pa = dma; | ||
720 | } | ||
721 | |||
722 | carveout->va = va; | ||
723 | carveout->len = rsc->len; | ||
724 | carveout->dma = dma; | ||
725 | carveout->da = rsc->da; | ||
726 | |||
727 | list_add_tail(&carveout->node, &rproc->carveouts); | ||
728 | |||
729 | return 0; | ||
730 | |||
731 | dma_free: | ||
732 | dma_free_coherent(dev, rsc->len, va, dma); | ||
733 | free_carv: | ||
734 | kfree(carveout); | ||
735 | free_mapping: | ||
736 | kfree(mapping); | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * A lookup table for resource handlers. The indices are defined in | ||
742 | * enum fw_resource_type. | ||
743 | */ | ||
744 | static rproc_handle_resource_t rproc_handle_rsc[] = { | ||
745 | [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout, | ||
746 | [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem, | ||
747 | [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace, | ||
748 | [RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */ | ||
749 | }; | ||
750 | |||
751 | /* handle firmware resource entries before booting the remote processor */ | ||
752 | static int | ||
753 | rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len) | ||
754 | { | ||
755 | struct device *dev = rproc->dev; | ||
756 | rproc_handle_resource_t handler; | ||
757 | int ret = 0, i; | ||
758 | |||
759 | for (i = 0; i < table->num; i++) { | ||
760 | int offset = table->offset[i]; | ||
761 | struct fw_rsc_hdr *hdr = (void *)table + offset; | ||
762 | int avail = len - offset - sizeof(*hdr); | ||
763 | void *rsc = (void *)hdr + sizeof(*hdr); | ||
764 | |||
765 | /* make sure table isn't truncated */ | ||
766 | if (avail < 0) { | ||
767 | dev_err(dev, "rsc table is truncated\n"); | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | |||
771 | dev_dbg(dev, "rsc: type %d\n", hdr->type); | ||
772 | |||
773 | if (hdr->type >= RSC_LAST) { | ||
774 | dev_warn(dev, "unsupported resource %d\n", hdr->type); | ||
775 | continue; | ||
776 | } | ||
777 | |||
778 | handler = rproc_handle_rsc[hdr->type]; | ||
779 | if (!handler) | ||
780 | continue; | ||
781 | |||
782 | ret = handler(rproc, rsc, avail); | ||
783 | if (ret) | ||
784 | break; | ||
785 | } | ||
786 | |||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | /* handle firmware resource entries while registering the remote processor */ | ||
791 | static int | ||
792 | rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int len) | ||
793 | { | ||
794 | struct device *dev = rproc->dev; | ||
795 | int ret = 0, i; | ||
796 | |||
797 | for (i = 0; i < table->num; i++) { | ||
798 | int offset = table->offset[i]; | ||
799 | struct fw_rsc_hdr *hdr = (void *)table + offset; | ||
800 | int avail = len - offset - sizeof(*hdr); | ||
801 | struct fw_rsc_vdev *vrsc; | ||
802 | |||
803 | /* make sure table isn't truncated */ | ||
804 | if (avail < 0) { | ||
805 | dev_err(dev, "rsc table is truncated\n"); | ||
806 | return -EINVAL; | ||
807 | } | ||
808 | |||
809 | dev_dbg(dev, "%s: rsc type %d\n", __func__, hdr->type); | ||
810 | |||
811 | if (hdr->type != RSC_VDEV) | ||
812 | continue; | ||
813 | |||
814 | vrsc = (struct fw_rsc_vdev *)hdr->data; | ||
815 | |||
816 | ret = rproc_handle_vdev(rproc, vrsc, avail); | ||
817 | if (ret) | ||
818 | break; | ||
819 | } | ||
820 | |||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | /** | ||
825 | * rproc_find_rsc_table() - find the resource table | ||
826 | * @rproc: the rproc handle | ||
827 | * @elf_data: the content of the ELF firmware image | ||
828 | * @len: firmware size (in bytes) | ||
829 | * @tablesz: place holder for providing back the table size | ||
830 | * | ||
831 | * This function finds the resource table inside the remote processor's | ||
832 | * firmware. It is used both upon the registration of @rproc (in order | ||
833 | * to look for and register the supported virito devices), and when the | ||
834 | * @rproc is booted. | ||
835 | * | ||
836 | * Returns the pointer to the resource table if it is found, and write its | ||
837 | * size into @tablesz. If a valid table isn't found, NULL is returned | ||
838 | * (and @tablesz isn't set). | ||
839 | */ | ||
840 | static struct resource_table * | ||
841 | rproc_find_rsc_table(struct rproc *rproc, const u8 *elf_data, size_t len, | ||
842 | int *tablesz) | ||
843 | { | ||
844 | struct elf32_hdr *ehdr; | ||
845 | struct elf32_shdr *shdr; | ||
846 | const char *name_table; | ||
847 | struct device *dev = rproc->dev; | ||
848 | struct resource_table *table = NULL; | ||
849 | int i; | ||
850 | |||
851 | ehdr = (struct elf32_hdr *)elf_data; | ||
852 | shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); | ||
853 | name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset; | ||
854 | |||
855 | /* look for the resource table and handle it */ | ||
856 | for (i = 0; i < ehdr->e_shnum; i++, shdr++) { | ||
857 | int size = shdr->sh_size; | ||
858 | int offset = shdr->sh_offset; | ||
859 | |||
860 | if (strcmp(name_table + shdr->sh_name, ".resource_table")) | ||
861 | continue; | ||
862 | |||
863 | table = (struct resource_table *)(elf_data + offset); | ||
864 | |||
865 | /* make sure we have the entire table */ | ||
866 | if (offset + size > len) { | ||
867 | dev_err(dev, "resource table truncated\n"); | ||
868 | return NULL; | ||
869 | } | ||
870 | |||
871 | /* make sure table has at least the header */ | ||
872 | if (sizeof(struct resource_table) > size) { | ||
873 | dev_err(dev, "header-less resource table\n"); | ||
874 | return NULL; | ||
875 | } | ||
876 | |||
877 | /* we don't support any version beyond the first */ | ||
878 | if (table->ver != 1) { | ||
879 | dev_err(dev, "unsupported fw ver: %d\n", table->ver); | ||
880 | return NULL; | ||
881 | } | ||
882 | |||
883 | /* make sure reserved bytes are zeroes */ | ||
884 | if (table->reserved[0] || table->reserved[1]) { | ||
885 | dev_err(dev, "non zero reserved bytes\n"); | ||
886 | return NULL; | ||
887 | } | ||
888 | |||
889 | /* make sure the offsets array isn't truncated */ | ||
890 | if (table->num * sizeof(table->offset[0]) + | ||
891 | sizeof(struct resource_table) > size) { | ||
892 | dev_err(dev, "resource table incomplete\n"); | ||
893 | return NULL; | ||
894 | } | ||
895 | |||
896 | *tablesz = shdr->sh_size; | ||
897 | break; | ||
898 | } | ||
899 | |||
900 | return table; | ||
901 | } | ||
902 | |||
903 | /** | ||
904 | * rproc_resource_cleanup() - clean up and free all acquired resources | ||
905 | * @rproc: rproc handle | ||
906 | * | ||
907 | * This function will free all resources acquired for @rproc, and it | ||
908 | * is called whenever @rproc either shuts down or fails to boot. | ||
909 | */ | ||
910 | static void rproc_resource_cleanup(struct rproc *rproc) | ||
911 | { | ||
912 | struct rproc_mem_entry *entry, *tmp; | ||
913 | struct device *dev = rproc->dev; | ||
914 | |||
915 | /* clean up debugfs trace entries */ | ||
916 | list_for_each_entry_safe(entry, tmp, &rproc->traces, node) { | ||
917 | rproc_remove_trace_file(entry->priv); | ||
918 | rproc->num_traces--; | ||
919 | list_del(&entry->node); | ||
920 | kfree(entry); | ||
921 | } | ||
922 | |||
923 | /* clean up carveout allocations */ | ||
924 | list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) { | ||
925 | dma_free_coherent(dev, entry->len, entry->va, entry->dma); | ||
926 | list_del(&entry->node); | ||
927 | kfree(entry); | ||
928 | } | ||
929 | |||
930 | /* clean up iommu mapping entries */ | ||
931 | list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) { | ||
932 | size_t unmapped; | ||
933 | |||
934 | unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); | ||
935 | if (unmapped != entry->len) { | ||
936 | /* nothing much to do besides complaining */ | ||
937 | dev_err(dev, "failed to unmap %u/%u\n", entry->len, | ||
938 | unmapped); | ||
939 | } | ||
940 | |||
941 | list_del(&entry->node); | ||
942 | kfree(entry); | ||
943 | } | ||
944 | } | ||
945 | |||
946 | /* make sure this fw image is sane */ | ||
947 | static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw) | ||
948 | { | ||
949 | const char *name = rproc->firmware; | ||
950 | struct device *dev = rproc->dev; | ||
951 | struct elf32_hdr *ehdr; | ||
952 | char class; | ||
953 | |||
954 | if (!fw) { | ||
955 | dev_err(dev, "failed to load %s\n", name); | ||
956 | return -EINVAL; | ||
957 | } | ||
958 | |||
959 | if (fw->size < sizeof(struct elf32_hdr)) { | ||
960 | dev_err(dev, "Image is too small\n"); | ||
961 | return -EINVAL; | ||
962 | } | ||
963 | |||
964 | ehdr = (struct elf32_hdr *)fw->data; | ||
965 | |||
966 | /* We only support ELF32 at this point */ | ||
967 | class = ehdr->e_ident[EI_CLASS]; | ||
968 | if (class != ELFCLASS32) { | ||
969 | dev_err(dev, "Unsupported class: %d\n", class); | ||
970 | return -EINVAL; | ||
971 | } | ||
972 | |||
973 | /* We assume the firmware has the same endianess as the host */ | ||
974 | # ifdef __LITTLE_ENDIAN | ||
975 | if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) { | ||
976 | # else /* BIG ENDIAN */ | ||
977 | if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) { | ||
978 | # endif | ||
979 | dev_err(dev, "Unsupported firmware endianess\n"); | ||
980 | return -EINVAL; | ||
981 | } | ||
982 | |||
983 | if (fw->size < ehdr->e_shoff + sizeof(struct elf32_shdr)) { | ||
984 | dev_err(dev, "Image is too small\n"); | ||
985 | return -EINVAL; | ||
986 | } | ||
987 | |||
988 | if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { | ||
989 | dev_err(dev, "Image is corrupted (bad magic)\n"); | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | |||
993 | if (ehdr->e_phnum == 0) { | ||
994 | dev_err(dev, "No loadable segments\n"); | ||
995 | return -EINVAL; | ||
996 | } | ||
997 | |||
998 | if (ehdr->e_phoff > fw->size) { | ||
999 | dev_err(dev, "Firmware size is too small\n"); | ||
1000 | return -EINVAL; | ||
1001 | } | ||
1002 | |||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | /* | ||
1007 | * take a firmware and boot a remote processor with it. | ||
1008 | */ | ||
1009 | static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) | ||
1010 | { | ||
1011 | struct device *dev = rproc->dev; | ||
1012 | const char *name = rproc->firmware; | ||
1013 | struct elf32_hdr *ehdr; | ||
1014 | struct resource_table *table; | ||
1015 | int ret, tablesz; | ||
1016 | |||
1017 | ret = rproc_fw_sanity_check(rproc, fw); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | |||
1021 | ehdr = (struct elf32_hdr *)fw->data; | ||
1022 | |||
1023 | dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); | ||
1024 | |||
1025 | /* | ||
1026 | * if enabling an IOMMU isn't relevant for this rproc, this is | ||
1027 | * just a nop | ||
1028 | */ | ||
1029 | ret = rproc_enable_iommu(rproc); | ||
1030 | if (ret) { | ||
1031 | dev_err(dev, "can't enable iommu: %d\n", ret); | ||
1032 | return ret; | ||
1033 | } | ||
1034 | |||
1035 | /* | ||
1036 | * The ELF entry point is the rproc's boot addr (though this is not | ||
1037 | * a configurable property of all remote processors: some will always | ||
1038 | * boot at a specific hardcoded address). | ||
1039 | */ | ||
1040 | rproc->bootaddr = ehdr->e_entry; | ||
1041 | |||
1042 | /* look for the resource table */ | ||
1043 | table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); | ||
1044 | if (!table) | ||
1045 | goto clean_up; | ||
1046 | |||
1047 | /* handle fw resources which are required to boot rproc */ | ||
1048 | ret = rproc_handle_boot_rsc(rproc, table, tablesz); | ||
1049 | if (ret) { | ||
1050 | dev_err(dev, "Failed to process resources: %d\n", ret); | ||
1051 | goto clean_up; | ||
1052 | } | ||
1053 | |||
1054 | /* load the ELF segments to memory */ | ||
1055 | ret = rproc_load_segments(rproc, fw->data, fw->size); | ||
1056 | if (ret) { | ||
1057 | dev_err(dev, "Failed to load program segments: %d\n", ret); | ||
1058 | goto clean_up; | ||
1059 | } | ||
1060 | |||
1061 | /* power up the remote processor */ | ||
1062 | ret = rproc->ops->start(rproc); | ||
1063 | if (ret) { | ||
1064 | dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret); | ||
1065 | goto clean_up; | ||
1066 | } | ||
1067 | |||
1068 | rproc->state = RPROC_RUNNING; | ||
1069 | |||
1070 | dev_info(dev, "remote processor %s is now up\n", rproc->name); | ||
1071 | |||
1072 | return 0; | ||
1073 | |||
1074 | clean_up: | ||
1075 | rproc_resource_cleanup(rproc); | ||
1076 | rproc_disable_iommu(rproc); | ||
1077 | return ret; | ||
1078 | } | ||
1079 | |||
1080 | /* | ||
1081 | * take a firmware and look for virtio devices to register. | ||
1082 | * | ||
1083 | * Note: this function is called asynchronously upon registration of the | ||
1084 | * remote processor (so we must wait until it completes before we try | ||
1085 | * to unregister the device. one other option is just to use kref here, | ||
1086 | * that might be cleaner). | ||
1087 | */ | ||
1088 | static void rproc_fw_config_virtio(const struct firmware *fw, void *context) | ||
1089 | { | ||
1090 | struct rproc *rproc = context; | ||
1091 | struct resource_table *table; | ||
1092 | int ret, tablesz; | ||
1093 | |||
1094 | if (rproc_fw_sanity_check(rproc, fw) < 0) | ||
1095 | goto out; | ||
1096 | |||
1097 | /* look for the resource table */ | ||
1098 | table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); | ||
1099 | if (!table) | ||
1100 | goto out; | ||
1101 | |||
1102 | /* look for virtio devices and register them */ | ||
1103 | ret = rproc_handle_virtio_rsc(rproc, table, tablesz); | ||
1104 | if (ret) | ||
1105 | goto out; | ||
1106 | |||
1107 | out: | ||
1108 | if (fw) | ||
1109 | release_firmware(fw); | ||
1110 | /* allow rproc_unregister() contexts, if any, to proceed */ | ||
1111 | complete_all(&rproc->firmware_loading_complete); | ||
1112 | } | ||
1113 | |||
1114 | /** | ||
1115 | * rproc_boot() - boot a remote processor | ||
1116 | * @rproc: handle of a remote processor | ||
1117 | * | ||
1118 | * Boot a remote processor (i.e. load its firmware, power it on, ...). | ||
1119 | * | ||
1120 | * If the remote processor is already powered on, this function immediately | ||
1121 | * returns (successfully). | ||
1122 | * | ||
1123 | * Returns 0 on success, and an appropriate error value otherwise. | ||
1124 | */ | ||
1125 | int rproc_boot(struct rproc *rproc) | ||
1126 | { | ||
1127 | const struct firmware *firmware_p; | ||
1128 | struct device *dev; | ||
1129 | int ret; | ||
1130 | |||
1131 | if (!rproc) { | ||
1132 | pr_err("invalid rproc handle\n"); | ||
1133 | return -EINVAL; | ||
1134 | } | ||
1135 | |||
1136 | dev = rproc->dev; | ||
1137 | |||
1138 | ret = mutex_lock_interruptible(&rproc->lock); | ||
1139 | if (ret) { | ||
1140 | dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); | ||
1141 | return ret; | ||
1142 | } | ||
1143 | |||
1144 | /* loading a firmware is required */ | ||
1145 | if (!rproc->firmware) { | ||
1146 | dev_err(dev, "%s: no firmware to load\n", __func__); | ||
1147 | ret = -EINVAL; | ||
1148 | goto unlock_mutex; | ||
1149 | } | ||
1150 | |||
1151 | /* prevent underlying implementation from being removed */ | ||
1152 | if (!try_module_get(dev->driver->owner)) { | ||
1153 | dev_err(dev, "%s: can't get owner\n", __func__); | ||
1154 | ret = -EINVAL; | ||
1155 | goto unlock_mutex; | ||
1156 | } | ||
1157 | |||
1158 | /* skip the boot process if rproc is already powered up */ | ||
1159 | if (atomic_inc_return(&rproc->power) > 1) { | ||
1160 | ret = 0; | ||
1161 | goto unlock_mutex; | ||
1162 | } | ||
1163 | |||
1164 | dev_info(dev, "powering up %s\n", rproc->name); | ||
1165 | |||
1166 | /* load firmware */ | ||
1167 | ret = request_firmware(&firmware_p, rproc->firmware, dev); | ||
1168 | if (ret < 0) { | ||
1169 | dev_err(dev, "request_firmware failed: %d\n", ret); | ||
1170 | goto downref_rproc; | ||
1171 | } | ||
1172 | |||
1173 | ret = rproc_fw_boot(rproc, firmware_p); | ||
1174 | |||
1175 | release_firmware(firmware_p); | ||
1176 | |||
1177 | downref_rproc: | ||
1178 | if (ret) { | ||
1179 | module_put(dev->driver->owner); | ||
1180 | atomic_dec(&rproc->power); | ||
1181 | } | ||
1182 | unlock_mutex: | ||
1183 | mutex_unlock(&rproc->lock); | ||
1184 | return ret; | ||
1185 | } | ||
1186 | EXPORT_SYMBOL(rproc_boot); | ||
1187 | |||
1188 | /** | ||
1189 | * rproc_shutdown() - power off the remote processor | ||
1190 | * @rproc: the remote processor | ||
1191 | * | ||
1192 | * Power off a remote processor (previously booted with rproc_boot()). | ||
1193 | * | ||
1194 | * In case @rproc is still being used by an additional user(s), then | ||
1195 | * this function will just decrement the power refcount and exit, | ||
1196 | * without really powering off the device. | ||
1197 | * | ||
1198 | * Every call to rproc_boot() must (eventually) be accompanied by a call | ||
1199 | * to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug. | ||
1200 | * | ||
1201 | * Notes: | ||
1202 | * - we're not decrementing the rproc's refcount, only the power refcount. | ||
1203 | * which means that the @rproc handle stays valid even after rproc_shutdown() | ||
1204 | * returns, and users can still use it with a subsequent rproc_boot(), if | ||
1205 | * needed. | ||
1206 | * - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly | ||
1207 | * because rproc_shutdown() _does not_ decrement the refcount of @rproc. | ||
1208 | * To decrement the refcount of @rproc, use rproc_put() (but _only_ if | ||
1209 | * you acquired @rproc using rproc_get_by_name()). | ||
1210 | */ | ||
1211 | void rproc_shutdown(struct rproc *rproc) | ||
1212 | { | ||
1213 | struct device *dev = rproc->dev; | ||
1214 | int ret; | ||
1215 | |||
1216 | ret = mutex_lock_interruptible(&rproc->lock); | ||
1217 | if (ret) { | ||
1218 | dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); | ||
1219 | return; | ||
1220 | } | ||
1221 | |||
1222 | /* if the remote proc is still needed, bail out */ | ||
1223 | if (!atomic_dec_and_test(&rproc->power)) | ||
1224 | goto out; | ||
1225 | |||
1226 | /* power off the remote processor */ | ||
1227 | ret = rproc->ops->stop(rproc); | ||
1228 | if (ret) { | ||
1229 | atomic_inc(&rproc->power); | ||
1230 | dev_err(dev, "can't stop rproc: %d\n", ret); | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | /* clean up all acquired resources */ | ||
1235 | rproc_resource_cleanup(rproc); | ||
1236 | |||
1237 | rproc_disable_iommu(rproc); | ||
1238 | |||
1239 | rproc->state = RPROC_OFFLINE; | ||
1240 | |||
1241 | dev_info(dev, "stopped remote processor %s\n", rproc->name); | ||
1242 | |||
1243 | out: | ||
1244 | mutex_unlock(&rproc->lock); | ||
1245 | if (!ret) | ||
1246 | module_put(dev->driver->owner); | ||
1247 | } | ||
1248 | EXPORT_SYMBOL(rproc_shutdown); | ||
1249 | |||
1250 | /** | ||
1251 | * rproc_release() - completely deletes the existence of a remote processor | ||
1252 | * @kref: the rproc's kref | ||
1253 | * | ||
1254 | * This function should _never_ be called directly. | ||
1255 | * | ||
1256 | * The only reasonable location to use it is as an argument when kref_put'ing | ||
1257 | * @rproc's refcount. | ||
1258 | * | ||
1259 | * This way it will be called when no one holds a valid pointer to this @rproc | ||
1260 | * anymore (and obviously after it is removed from the rprocs klist). | ||
1261 | * | ||
1262 | * Note: this function is not static because rproc_vdev_release() needs it when | ||
1263 | * it decrements @rproc's refcount. | ||
1264 | */ | ||
1265 | void rproc_release(struct kref *kref) | ||
1266 | { | ||
1267 | struct rproc *rproc = container_of(kref, struct rproc, refcount); | ||
1268 | struct rproc_vdev *rvdev, *rvtmp; | ||
1269 | |||
1270 | dev_info(rproc->dev, "removing %s\n", rproc->name); | ||
1271 | |||
1272 | rproc_delete_debug_dir(rproc); | ||
1273 | |||
1274 | /* clean up remote vdev entries */ | ||
1275 | list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) { | ||
1276 | __rproc_free_vrings(rvdev, RVDEV_NUM_VRINGS); | ||
1277 | list_del(&rvdev->node); | ||
1278 | } | ||
1279 | |||
1280 | /* | ||
1281 | * At this point no one holds a reference to rproc anymore, | ||
1282 | * so we can directly unroll rproc_alloc() | ||
1283 | */ | ||
1284 | rproc_free(rproc); | ||
1285 | } | ||
1286 | |||
1287 | /* will be called when an rproc is added to the rprocs klist */ | ||
1288 | static void klist_rproc_get(struct klist_node *n) | ||
1289 | { | ||
1290 | struct rproc *rproc = container_of(n, struct rproc, node); | ||
1291 | |||
1292 | kref_get(&rproc->refcount); | ||
1293 | } | ||
1294 | |||
1295 | /* will be called when an rproc is removed from the rprocs klist */ | ||
1296 | static void klist_rproc_put(struct klist_node *n) | ||
1297 | { | ||
1298 | struct rproc *rproc = container_of(n, struct rproc, node); | ||
1299 | |||
1300 | kref_put(&rproc->refcount, rproc_release); | ||
1301 | } | ||
1302 | |||
1303 | static struct rproc *next_rproc(struct klist_iter *i) | ||
1304 | { | ||
1305 | struct klist_node *n; | ||
1306 | |||
1307 | n = klist_next(i); | ||
1308 | if (!n) | ||
1309 | return NULL; | ||
1310 | |||
1311 | return container_of(n, struct rproc, node); | ||
1312 | } | ||
1313 | |||
1314 | /** | ||
1315 | * rproc_get_by_name() - find a remote processor by name and boot it | ||
1316 | * @name: name of the remote processor | ||
1317 | * | ||
1318 | * Finds an rproc handle using the remote processor's name, and then | ||
1319 | * boot it. If it's already powered on, then just immediately return | ||
1320 | * (successfully). | ||
1321 | * | ||
1322 | * Returns the rproc handle on success, and NULL on failure. | ||
1323 | * | ||
1324 | * This function increments the remote processor's refcount, so always | ||
1325 | * use rproc_put() to decrement it back once rproc isn't needed anymore. | ||
1326 | * | ||
1327 | * Note: currently this function (and its counterpart rproc_put()) are not | ||
1328 | * being used. We need to scrutinize the use cases | ||
1329 | * that still need them, and see if we can migrate them to use the non | ||
1330 | * name-based boot/shutdown interface. | ||
1331 | */ | ||
1332 | struct rproc *rproc_get_by_name(const char *name) | ||
1333 | { | ||
1334 | struct rproc *rproc; | ||
1335 | struct klist_iter i; | ||
1336 | int ret; | ||
1337 | |||
1338 | /* find the remote processor, and upref its refcount */ | ||
1339 | klist_iter_init(&rprocs, &i); | ||
1340 | while ((rproc = next_rproc(&i)) != NULL) | ||
1341 | if (!strcmp(rproc->name, name)) { | ||
1342 | kref_get(&rproc->refcount); | ||
1343 | break; | ||
1344 | } | ||
1345 | klist_iter_exit(&i); | ||
1346 | |||
1347 | /* can't find this rproc ? */ | ||
1348 | if (!rproc) { | ||
1349 | pr_err("can't find remote processor %s\n", name); | ||
1350 | return NULL; | ||
1351 | } | ||
1352 | |||
1353 | ret = rproc_boot(rproc); | ||
1354 | if (ret < 0) { | ||
1355 | kref_put(&rproc->refcount, rproc_release); | ||
1356 | return NULL; | ||
1357 | } | ||
1358 | |||
1359 | return rproc; | ||
1360 | } | ||
1361 | EXPORT_SYMBOL(rproc_get_by_name); | ||
1362 | |||
1363 | /** | ||
1364 | * rproc_put() - decrement the refcount of a remote processor, and shut it down | ||
1365 | * @rproc: the remote processor | ||
1366 | * | ||
1367 | * This function tries to shutdown @rproc, and it then decrements its | ||
1368 | * refcount. | ||
1369 | * | ||
1370 | * After this function returns, @rproc may _not_ be used anymore, and its | ||
1371 | * handle should be considered invalid. | ||
1372 | * | ||
1373 | * This function should be called _iff_ the @rproc handle was grabbed by | ||
1374 | * calling rproc_get_by_name(). | ||
1375 | */ | ||
1376 | void rproc_put(struct rproc *rproc) | ||
1377 | { | ||
1378 | /* try to power off the remote processor */ | ||
1379 | rproc_shutdown(rproc); | ||
1380 | |||
1381 | /* downref rproc's refcount */ | ||
1382 | kref_put(&rproc->refcount, rproc_release); | ||
1383 | } | ||
1384 | EXPORT_SYMBOL(rproc_put); | ||
1385 | |||
1386 | /** | ||
1387 | * rproc_register() - register a remote processor | ||
1388 | * @rproc: the remote processor handle to register | ||
1389 | * | ||
1390 | * Registers @rproc with the remoteproc framework, after it has been | ||
1391 | * allocated with rproc_alloc(). | ||
1392 | * | ||
1393 | * This is called by the platform-specific rproc implementation, whenever | ||
1394 | * a new remote processor device is probed. | ||
1395 | * | ||
1396 | * Returns 0 on success and an appropriate error code otherwise. | ||
1397 | * | ||
1398 | * Note: this function initiates an asynchronous firmware loading | ||
1399 | * context, which will look for virtio devices supported by the rproc's | ||
1400 | * firmware. | ||
1401 | * | ||
1402 | * If found, those virtio devices will be created and added, so as a result | ||
1403 | * of registering this remote processor, additional virtio drivers might be | ||
1404 | * probed. | ||
1405 | */ | ||
1406 | int rproc_register(struct rproc *rproc) | ||
1407 | { | ||
1408 | struct device *dev = rproc->dev; | ||
1409 | int ret = 0; | ||
1410 | |||
1411 | /* expose to rproc_get_by_name users */ | ||
1412 | klist_add_tail(&rproc->node, &rprocs); | ||
1413 | |||
1414 | dev_info(rproc->dev, "%s is available\n", rproc->name); | ||
1415 | |||
1416 | dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n"); | ||
1417 | dev_info(dev, "THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.\n"); | ||
1418 | |||
1419 | /* create debugfs entries */ | ||
1420 | rproc_create_debug_dir(rproc); | ||
1421 | |||
1422 | /* rproc_unregister() calls must wait until async loader completes */ | ||
1423 | init_completion(&rproc->firmware_loading_complete); | ||
1424 | |||
1425 | /* | ||
1426 | * We must retrieve early virtio configuration info from | ||
1427 | * the firmware (e.g. whether to register a virtio device, | ||
1428 | * what virtio features does it support, ...). | ||
1429 | * | ||
1430 | * We're initiating an asynchronous firmware loading, so we can | ||
1431 | * be built-in kernel code, without hanging the boot process. | ||
1432 | */ | ||
1433 | ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
1434 | rproc->firmware, dev, GFP_KERNEL, | ||
1435 | rproc, rproc_fw_config_virtio); | ||
1436 | if (ret < 0) { | ||
1437 | dev_err(dev, "request_firmware_nowait failed: %d\n", ret); | ||
1438 | complete_all(&rproc->firmware_loading_complete); | ||
1439 | klist_remove(&rproc->node); | ||
1440 | } | ||
1441 | |||
1442 | return ret; | ||
1443 | } | ||
1444 | EXPORT_SYMBOL(rproc_register); | ||
1445 | |||
1446 | /** | ||
1447 | * rproc_alloc() - allocate a remote processor handle | ||
1448 | * @dev: the underlying device | ||
1449 | * @name: name of this remote processor | ||
1450 | * @ops: platform-specific handlers (mainly start/stop) | ||
1451 | * @firmware: name of firmware file to load | ||
1452 | * @len: length of private data needed by the rproc driver (in bytes) | ||
1453 | * | ||
1454 | * Allocates a new remote processor handle, but does not register | ||
1455 | * it yet. | ||
1456 | * | ||
1457 | * This function should be used by rproc implementations during initialization | ||
1458 | * of the remote processor. | ||
1459 | * | ||
1460 | * After creating an rproc handle using this function, and when ready, | ||
1461 | * implementations should then call rproc_register() to complete | ||
1462 | * the registration of the remote processor. | ||
1463 | * | ||
1464 | * On success the new rproc is returned, and on failure, NULL. | ||
1465 | * | ||
1466 | * Note: _never_ directly deallocate @rproc, even if it was not registered | ||
1467 | * yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free(). | ||
1468 | */ | ||
1469 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
1470 | const struct rproc_ops *ops, | ||
1471 | const char *firmware, int len) | ||
1472 | { | ||
1473 | struct rproc *rproc; | ||
1474 | |||
1475 | if (!dev || !name || !ops) | ||
1476 | return NULL; | ||
1477 | |||
1478 | rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL); | ||
1479 | if (!rproc) { | ||
1480 | dev_err(dev, "%s: kzalloc failed\n", __func__); | ||
1481 | return NULL; | ||
1482 | } | ||
1483 | |||
1484 | rproc->dev = dev; | ||
1485 | rproc->name = name; | ||
1486 | rproc->ops = ops; | ||
1487 | rproc->firmware = firmware; | ||
1488 | rproc->priv = &rproc[1]; | ||
1489 | |||
1490 | atomic_set(&rproc->power, 0); | ||
1491 | |||
1492 | kref_init(&rproc->refcount); | ||
1493 | |||
1494 | mutex_init(&rproc->lock); | ||
1495 | |||
1496 | idr_init(&rproc->notifyids); | ||
1497 | |||
1498 | INIT_LIST_HEAD(&rproc->carveouts); | ||
1499 | INIT_LIST_HEAD(&rproc->mappings); | ||
1500 | INIT_LIST_HEAD(&rproc->traces); | ||
1501 | INIT_LIST_HEAD(&rproc->rvdevs); | ||
1502 | |||
1503 | rproc->state = RPROC_OFFLINE; | ||
1504 | |||
1505 | return rproc; | ||
1506 | } | ||
1507 | EXPORT_SYMBOL(rproc_alloc); | ||
1508 | |||
1509 | /** | ||
1510 | * rproc_free() - free an rproc handle that was allocated by rproc_alloc | ||
1511 | * @rproc: the remote processor handle | ||
1512 | * | ||
1513 | * This function should _only_ be used if @rproc was only allocated, | ||
1514 | * but not registered yet. | ||
1515 | * | ||
1516 | * If @rproc was already successfully registered (by calling rproc_register()), | ||
1517 | * then use rproc_unregister() instead. | ||
1518 | */ | ||
1519 | void rproc_free(struct rproc *rproc) | ||
1520 | { | ||
1521 | idr_remove_all(&rproc->notifyids); | ||
1522 | idr_destroy(&rproc->notifyids); | ||
1523 | |||
1524 | kfree(rproc); | ||
1525 | } | ||
1526 | EXPORT_SYMBOL(rproc_free); | ||
1527 | |||
1528 | /** | ||
1529 | * rproc_unregister() - unregister a remote processor | ||
1530 | * @rproc: rproc handle to unregister | ||
1531 | * | ||
1532 | * Unregisters a remote processor, and decrements its refcount. | ||
1533 | * If its refcount drops to zero, then @rproc will be freed. If not, | ||
1534 | * it will be freed later once the last reference is dropped. | ||
1535 | * | ||
1536 | * This function should be called when the platform specific rproc | ||
1537 | * implementation decides to remove the rproc device. it should | ||
1538 | * _only_ be called if a previous invocation of rproc_register() | ||
1539 | * has completed successfully. | ||
1540 | * | ||
1541 | * After rproc_unregister() returns, @rproc is _not_ valid anymore and | ||
1542 | * it shouldn't be used. More specifically, don't call rproc_free() | ||
1543 | * or try to directly free @rproc after rproc_unregister() returns; | ||
1544 | * none of these are needed, and calling them is a bug. | ||
1545 | * | ||
1546 | * Returns 0 on success and -EINVAL if @rproc isn't valid. | ||
1547 | */ | ||
1548 | int rproc_unregister(struct rproc *rproc) | ||
1549 | { | ||
1550 | struct rproc_vdev *rvdev; | ||
1551 | |||
1552 | if (!rproc) | ||
1553 | return -EINVAL; | ||
1554 | |||
1555 | /* if rproc is just being registered, wait */ | ||
1556 | wait_for_completion(&rproc->firmware_loading_complete); | ||
1557 | |||
1558 | /* clean up remote vdev entries */ | ||
1559 | list_for_each_entry(rvdev, &rproc->rvdevs, node) | ||
1560 | rproc_remove_virtio_dev(rvdev); | ||
1561 | |||
1562 | /* the rproc is downref'ed as soon as it's removed from the klist */ | ||
1563 | klist_del(&rproc->node); | ||
1564 | |||
1565 | /* the rproc will only be released after its refcount drops to zero */ | ||
1566 | kref_put(&rproc->refcount, rproc_release); | ||
1567 | |||
1568 | return 0; | ||
1569 | } | ||
1570 | EXPORT_SYMBOL(rproc_unregister); | ||
1571 | |||
1572 | static int __init remoteproc_init(void) | ||
1573 | { | ||
1574 | rproc_init_debugfs(); | ||
1575 | return 0; | ||
1576 | } | ||
1577 | module_init(remoteproc_init); | ||
1578 | |||
1579 | static void __exit remoteproc_exit(void) | ||
1580 | { | ||
1581 | rproc_exit_debugfs(); | ||
1582 | } | ||
1583 | module_exit(remoteproc_exit); | ||
1584 | |||
1585 | MODULE_LICENSE("GPL v2"); | ||
1586 | 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..9f336d6bdef3 --- /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_virtio.c */ | ||
32 | int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id); | ||
33 | void rproc_remove_virtio_dev(struct rproc_vdev *rvdev); | ||
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_virtio.c b/drivers/remoteproc/remoteproc_virtio.c new file mode 100644 index 000000000000..ecf612130750 --- /dev/null +++ b/drivers/remoteproc/remoteproc_virtio.c | |||
@@ -0,0 +1,289 @@ | |||
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/virtio.h> | ||
23 | #include <linux/virtio_config.h> | ||
24 | #include <linux/virtio_ids.h> | ||
25 | #include <linux/virtio_ring.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/kref.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #include "remoteproc_internal.h" | ||
31 | |||
32 | /* kick the remote processor, and let it know which virtqueue to poke at */ | ||
33 | static void rproc_virtio_notify(struct virtqueue *vq) | ||
34 | { | ||
35 | struct rproc_vring *rvring = vq->priv; | ||
36 | struct rproc *rproc = rvring->rvdev->rproc; | ||
37 | int notifyid = rvring->notifyid; | ||
38 | |||
39 | dev_dbg(rproc->dev, "kicking vq index: %d\n", notifyid); | ||
40 | |||
41 | rproc->ops->kick(rproc, notifyid); | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted | ||
46 | * @rproc: handle to the remote processor | ||
47 | * @notifyid: index of the signalled virtqueue (unique per this @rproc) | ||
48 | * | ||
49 | * This function should be called by the platform-specific rproc driver, | ||
50 | * when the remote processor signals that a specific virtqueue has pending | ||
51 | * messages available. | ||
52 | * | ||
53 | * Returns IRQ_NONE if no message was found in the @notifyid virtqueue, | ||
54 | * and otherwise returns IRQ_HANDLED. | ||
55 | */ | ||
56 | irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid) | ||
57 | { | ||
58 | struct rproc_vring *rvring; | ||
59 | |||
60 | dev_dbg(rproc->dev, "vq index %d is interrupted\n", notifyid); | ||
61 | |||
62 | rvring = idr_find(&rproc->notifyids, notifyid); | ||
63 | if (!rvring || !rvring->vq) | ||
64 | return IRQ_NONE; | ||
65 | |||
66 | return vring_interrupt(0, rvring->vq); | ||
67 | } | ||
68 | EXPORT_SYMBOL(rproc_vq_interrupt); | ||
69 | |||
70 | static struct virtqueue *rp_find_vq(struct virtio_device *vdev, | ||
71 | unsigned id, | ||
72 | void (*callback)(struct virtqueue *vq), | ||
73 | const char *name) | ||
74 | { | ||
75 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
76 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
77 | struct rproc_vring *rvring; | ||
78 | struct virtqueue *vq; | ||
79 | void *addr; | ||
80 | int len, size; | ||
81 | |||
82 | /* we're temporarily limited to two virtqueues per rvdev */ | ||
83 | if (id >= ARRAY_SIZE(rvdev->vring)) | ||
84 | return ERR_PTR(-EINVAL); | ||
85 | |||
86 | rvring = &rvdev->vring[id]; | ||
87 | |||
88 | addr = rvring->va; | ||
89 | len = rvring->len; | ||
90 | |||
91 | /* zero vring */ | ||
92 | size = vring_size(len, rvring->align); | ||
93 | memset(addr, 0, size); | ||
94 | |||
95 | dev_dbg(rproc->dev, "vring%d: va %p qsz %d notifyid %d\n", | ||
96 | id, addr, len, rvring->notifyid); | ||
97 | |||
98 | /* | ||
99 | * Create the new vq, and tell virtio we're not interested in | ||
100 | * the 'weak' smp barriers, since we're talking with a real device. | ||
101 | */ | ||
102 | vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr, | ||
103 | rproc_virtio_notify, callback, name); | ||
104 | if (!vq) { | ||
105 | dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name); | ||
106 | return ERR_PTR(-ENOMEM); | ||
107 | } | ||
108 | |||
109 | rvring->vq = vq; | ||
110 | vq->priv = rvring; | ||
111 | |||
112 | return vq; | ||
113 | } | ||
114 | |||
115 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) | ||
116 | { | ||
117 | struct virtqueue *vq, *n; | ||
118 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
119 | struct rproc_vring *rvring; | ||
120 | |||
121 | /* power down the remote processor before deleting vqs */ | ||
122 | rproc_shutdown(rproc); | ||
123 | |||
124 | list_for_each_entry_safe(vq, n, &vdev->vqs, list) { | ||
125 | rvring = vq->priv; | ||
126 | rvring->vq = NULL; | ||
127 | vring_del_virtqueue(vq); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, | ||
132 | struct virtqueue *vqs[], | ||
133 | vq_callback_t *callbacks[], | ||
134 | const char *names[]) | ||
135 | { | ||
136 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
137 | int i, ret; | ||
138 | |||
139 | for (i = 0; i < nvqs; ++i) { | ||
140 | vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]); | ||
141 | if (IS_ERR(vqs[i])) { | ||
142 | ret = PTR_ERR(vqs[i]); | ||
143 | goto error; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | /* now that the vqs are all set, boot the remote processor */ | ||
148 | ret = rproc_boot(rproc); | ||
149 | if (ret) { | ||
150 | dev_err(rproc->dev, "rproc_boot() failed %d\n", ret); | ||
151 | goto error; | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | |||
156 | error: | ||
157 | rproc_virtio_del_vqs(vdev); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * We don't support yet real virtio status semantics. | ||
163 | * | ||
164 | * The plan is to provide this via the VDEV resource entry | ||
165 | * which is part of the firmware: this way the remote processor | ||
166 | * will be able to access the status values as set by us. | ||
167 | */ | ||
168 | static u8 rproc_virtio_get_status(struct virtio_device *vdev) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) | ||
174 | { | ||
175 | dev_dbg(&vdev->dev, "status: %d\n", status); | ||
176 | } | ||
177 | |||
178 | static void rproc_virtio_reset(struct virtio_device *vdev) | ||
179 | { | ||
180 | dev_dbg(&vdev->dev, "reset !\n"); | ||
181 | } | ||
182 | |||
183 | /* provide the vdev features as retrieved from the firmware */ | ||
184 | static u32 rproc_virtio_get_features(struct virtio_device *vdev) | ||
185 | { | ||
186 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
187 | |||
188 | return rvdev->dfeatures; | ||
189 | } | ||
190 | |||
191 | static void rproc_virtio_finalize_features(struct virtio_device *vdev) | ||
192 | { | ||
193 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
194 | |||
195 | /* Give virtio_ring a chance to accept features */ | ||
196 | vring_transport_features(vdev); | ||
197 | |||
198 | /* | ||
199 | * Remember the finalized features of our vdev, and provide it | ||
200 | * to the remote processor once it is powered on. | ||
201 | * | ||
202 | * Similarly to the status field, we don't expose yet the negotiated | ||
203 | * features to the remote processors at this point. This will be | ||
204 | * fixed as part of a small resource table overhaul and then an | ||
205 | * extension of the virtio resource entries. | ||
206 | */ | ||
207 | rvdev->gfeatures = vdev->features[0]; | ||
208 | } | ||
209 | |||
210 | static struct virtio_config_ops rproc_virtio_config_ops = { | ||
211 | .get_features = rproc_virtio_get_features, | ||
212 | .finalize_features = rproc_virtio_finalize_features, | ||
213 | .find_vqs = rproc_virtio_find_vqs, | ||
214 | .del_vqs = rproc_virtio_del_vqs, | ||
215 | .reset = rproc_virtio_reset, | ||
216 | .set_status = rproc_virtio_set_status, | ||
217 | .get_status = rproc_virtio_get_status, | ||
218 | }; | ||
219 | |||
220 | /* | ||
221 | * This function is called whenever vdev is released, and is responsible | ||
222 | * to decrement the remote processor's refcount taken when vdev was | ||
223 | * added. | ||
224 | * | ||
225 | * Never call this function directly; it will be called by the driver | ||
226 | * core when needed. | ||
227 | */ | ||
228 | static void rproc_vdev_release(struct device *dev) | ||
229 | { | ||
230 | struct virtio_device *vdev = dev_to_virtio(dev); | ||
231 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
232 | |||
233 | kref_put(&rproc->refcount, rproc_release); | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * rproc_add_virtio_dev() - register an rproc-induced virtio device | ||
238 | * @rvdev: the remote vdev | ||
239 | * | ||
240 | * This function registers a virtio device. This vdev's partent is | ||
241 | * the rproc device. | ||
242 | * | ||
243 | * Returns 0 on success or an appropriate error value otherwise. | ||
244 | */ | ||
245 | int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id) | ||
246 | { | ||
247 | struct rproc *rproc = rvdev->rproc; | ||
248 | struct device *dev = rproc->dev; | ||
249 | struct virtio_device *vdev = &rvdev->vdev; | ||
250 | int ret; | ||
251 | |||
252 | vdev->id.device = id, | ||
253 | vdev->config = &rproc_virtio_config_ops, | ||
254 | vdev->dev.parent = dev; | ||
255 | vdev->dev.release = rproc_vdev_release; | ||
256 | |||
257 | /* | ||
258 | * We're indirectly making a non-temporary copy of the rproc pointer | ||
259 | * here, because drivers probed with this vdev will indirectly | ||
260 | * access the wrapping rproc. | ||
261 | * | ||
262 | * Therefore we must increment the rproc refcount here, and decrement | ||
263 | * it _only_ when the vdev is released. | ||
264 | */ | ||
265 | kref_get(&rproc->refcount); | ||
266 | |||
267 | ret = register_virtio_device(vdev); | ||
268 | if (ret) { | ||
269 | kref_put(&rproc->refcount, rproc_release); | ||
270 | dev_err(dev, "failed to register vdev: %d\n", ret); | ||
271 | goto out; | ||
272 | } | ||
273 | |||
274 | dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id); | ||
275 | |||
276 | out: | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * rproc_remove_virtio_dev() - remove an rproc-induced virtio device | ||
282 | * @rvdev: the remote vdev | ||
283 | * | ||
284 | * This function unregisters an existing virtio device. | ||
285 | */ | ||
286 | void rproc_remove_virtio_dev(struct rproc_vdev *rvdev) | ||
287 | { | ||
288 | unregister_virtio_device(&rvdev->vdev); | ||
289 | } | ||
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..75506ec2840e --- /dev/null +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -0,0 +1,1054 @@ | |||
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 | * @vrp: virtproc which owns this ept | ||
295 | * @ept: endpoing to destroy | ||
296 | * | ||
297 | * An internal function which destroy an ept without assuming it is | ||
298 | * bound to an rpmsg channel. This is needed for handling the internal | ||
299 | * name service endpoint, which isn't bound to an rpmsg channel. | ||
300 | * See also __rpmsg_create_ept(). | ||
301 | */ | ||
302 | static void | ||
303 | __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) | ||
304 | { | ||
305 | mutex_lock(&vrp->endpoints_lock); | ||
306 | idr_remove(&vrp->endpoints, ept->addr); | ||
307 | mutex_unlock(&vrp->endpoints_lock); | ||
308 | |||
309 | kfree(ept); | ||
310 | } | ||
311 | |||
312 | /** | ||
313 | * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint | ||
314 | * @ept: endpoing to destroy | ||
315 | * | ||
316 | * Should be used by drivers to destroy an rpmsg endpoint previously | ||
317 | * created with rpmsg_create_ept(). | ||
318 | */ | ||
319 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) | ||
320 | { | ||
321 | __rpmsg_destroy_ept(ept->rpdev->vrp, ept); | ||
322 | } | ||
323 | EXPORT_SYMBOL(rpmsg_destroy_ept); | ||
324 | |||
325 | /* | ||
326 | * when an rpmsg driver is probed with a channel, we seamlessly create | ||
327 | * it an endpoint, binding its rx callback to a unique local rpmsg | ||
328 | * address. | ||
329 | * | ||
330 | * if we need to, we also announce about this channel to the remote | ||
331 | * processor (needed in case the driver is exposing an rpmsg service). | ||
332 | */ | ||
333 | static int rpmsg_dev_probe(struct device *dev) | ||
334 | { | ||
335 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
336 | struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); | ||
337 | struct virtproc_info *vrp = rpdev->vrp; | ||
338 | struct rpmsg_endpoint *ept; | ||
339 | int err; | ||
340 | |||
341 | ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, rpdev->src); | ||
342 | if (!ept) { | ||
343 | dev_err(dev, "failed to create endpoint\n"); | ||
344 | err = -ENOMEM; | ||
345 | goto out; | ||
346 | } | ||
347 | |||
348 | rpdev->ept = ept; | ||
349 | rpdev->src = ept->addr; | ||
350 | |||
351 | err = rpdrv->probe(rpdev); | ||
352 | if (err) { | ||
353 | dev_err(dev, "%s: failed: %d\n", __func__, err); | ||
354 | rpmsg_destroy_ept(ept); | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | /* need to tell remote processor's name service about this channel ? */ | ||
359 | if (rpdev->announce && | ||
360 | virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { | ||
361 | struct rpmsg_ns_msg nsm; | ||
362 | |||
363 | strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); | ||
364 | nsm.addr = rpdev->src; | ||
365 | nsm.flags = RPMSG_NS_CREATE; | ||
366 | |||
367 | err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); | ||
368 | if (err) | ||
369 | dev_err(dev, "failed to announce service %d\n", err); | ||
370 | } | ||
371 | |||
372 | out: | ||
373 | return err; | ||
374 | } | ||
375 | |||
376 | static int rpmsg_dev_remove(struct device *dev) | ||
377 | { | ||
378 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
379 | struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); | ||
380 | struct virtproc_info *vrp = rpdev->vrp; | ||
381 | int err = 0; | ||
382 | |||
383 | /* tell remote processor's name service we're removing this channel */ | ||
384 | if (rpdev->announce && | ||
385 | virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { | ||
386 | struct rpmsg_ns_msg nsm; | ||
387 | |||
388 | strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); | ||
389 | nsm.addr = rpdev->src; | ||
390 | nsm.flags = RPMSG_NS_DESTROY; | ||
391 | |||
392 | err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); | ||
393 | if (err) | ||
394 | dev_err(dev, "failed to announce service %d\n", err); | ||
395 | } | ||
396 | |||
397 | rpdrv->remove(rpdev); | ||
398 | |||
399 | rpmsg_destroy_ept(rpdev->ept); | ||
400 | |||
401 | return err; | ||
402 | } | ||
403 | |||
404 | static struct bus_type rpmsg_bus = { | ||
405 | .name = "rpmsg", | ||
406 | .match = rpmsg_dev_match, | ||
407 | .dev_attrs = rpmsg_dev_attrs, | ||
408 | .uevent = rpmsg_uevent, | ||
409 | .probe = rpmsg_dev_probe, | ||
410 | .remove = rpmsg_dev_remove, | ||
411 | }; | ||
412 | |||
413 | /** | ||
414 | * register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus | ||
415 | * @rpdrv: pointer to a struct rpmsg_driver | ||
416 | * | ||
417 | * Returns 0 on success, and an appropriate error value on failure. | ||
418 | */ | ||
419 | int register_rpmsg_driver(struct rpmsg_driver *rpdrv) | ||
420 | { | ||
421 | rpdrv->drv.bus = &rpmsg_bus; | ||
422 | return driver_register(&rpdrv->drv); | ||
423 | } | ||
424 | EXPORT_SYMBOL(register_rpmsg_driver); | ||
425 | |||
426 | /** | ||
427 | * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus | ||
428 | * @rpdrv: pointer to a struct rpmsg_driver | ||
429 | * | ||
430 | * Returns 0 on success, and an appropriate error value on failure. | ||
431 | */ | ||
432 | void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv) | ||
433 | { | ||
434 | driver_unregister(&rpdrv->drv); | ||
435 | } | ||
436 | EXPORT_SYMBOL(unregister_rpmsg_driver); | ||
437 | |||
438 | static void rpmsg_release_device(struct device *dev) | ||
439 | { | ||
440 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
441 | |||
442 | kfree(rpdev); | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * match an rpmsg channel with a channel info struct. | ||
447 | * this is used to make sure we're not creating rpmsg devices for channels | ||
448 | * that already exist. | ||
449 | */ | ||
450 | static int rpmsg_channel_match(struct device *dev, void *data) | ||
451 | { | ||
452 | struct rpmsg_channel_info *chinfo = data; | ||
453 | struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); | ||
454 | |||
455 | if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src) | ||
456 | return 0; | ||
457 | |||
458 | if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst) | ||
459 | return 0; | ||
460 | |||
461 | if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE)) | ||
462 | return 0; | ||
463 | |||
464 | /* found a match ! */ | ||
465 | return 1; | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * create an rpmsg channel using its name and address info. | ||
470 | * this function will be used to create both static and dynamic | ||
471 | * channels. | ||
472 | */ | ||
473 | static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp, | ||
474 | struct rpmsg_channel_info *chinfo) | ||
475 | { | ||
476 | struct rpmsg_channel *rpdev; | ||
477 | struct device *tmp, *dev = &vrp->vdev->dev; | ||
478 | int ret; | ||
479 | |||
480 | /* make sure a similar channel doesn't already exist */ | ||
481 | tmp = device_find_child(dev, chinfo, rpmsg_channel_match); | ||
482 | if (tmp) { | ||
483 | /* decrement the matched device's refcount back */ | ||
484 | put_device(tmp); | ||
485 | dev_err(dev, "channel %s:%x:%x already exist\n", | ||
486 | chinfo->name, chinfo->src, chinfo->dst); | ||
487 | return NULL; | ||
488 | } | ||
489 | |||
490 | rpdev = kzalloc(sizeof(struct rpmsg_channel), GFP_KERNEL); | ||
491 | if (!rpdev) { | ||
492 | pr_err("kzalloc failed\n"); | ||
493 | return NULL; | ||
494 | } | ||
495 | |||
496 | rpdev->vrp = vrp; | ||
497 | rpdev->src = chinfo->src; | ||
498 | rpdev->dst = chinfo->dst; | ||
499 | |||
500 | /* | ||
501 | * rpmsg server channels has predefined local address (for now), | ||
502 | * and their existence needs to be announced remotely | ||
503 | */ | ||
504 | rpdev->announce = rpdev->src != RPMSG_ADDR_ANY ? true : false; | ||
505 | |||
506 | strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE); | ||
507 | |||
508 | /* very simple device indexing plumbing which is enough for now */ | ||
509 | dev_set_name(&rpdev->dev, "rpmsg%d", rpmsg_dev_index++); | ||
510 | |||
511 | rpdev->dev.parent = &vrp->vdev->dev; | ||
512 | rpdev->dev.bus = &rpmsg_bus; | ||
513 | rpdev->dev.release = rpmsg_release_device; | ||
514 | |||
515 | ret = device_register(&rpdev->dev); | ||
516 | if (ret) { | ||
517 | dev_err(dev, "device_register failed: %d\n", ret); | ||
518 | put_device(&rpdev->dev); | ||
519 | return NULL; | ||
520 | } | ||
521 | |||
522 | return rpdev; | ||
523 | } | ||
524 | |||
525 | /* | ||
526 | * find an existing channel using its name + address properties, | ||
527 | * and destroy it | ||
528 | */ | ||
529 | static int rpmsg_destroy_channel(struct virtproc_info *vrp, | ||
530 | struct rpmsg_channel_info *chinfo) | ||
531 | { | ||
532 | struct virtio_device *vdev = vrp->vdev; | ||
533 | struct device *dev; | ||
534 | |||
535 | dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match); | ||
536 | if (!dev) | ||
537 | return -EINVAL; | ||
538 | |||
539 | device_unregister(dev); | ||
540 | |||
541 | put_device(dev); | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | /* super simple buffer "allocator" that is just enough for now */ | ||
547 | static void *get_a_tx_buf(struct virtproc_info *vrp) | ||
548 | { | ||
549 | unsigned int len; | ||
550 | void *ret; | ||
551 | |||
552 | /* support multiple concurrent senders */ | ||
553 | mutex_lock(&vrp->tx_lock); | ||
554 | |||
555 | /* | ||
556 | * either pick the next unused tx buffer | ||
557 | * (half of our buffers are used for sending messages) | ||
558 | */ | ||
559 | if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2) | ||
560 | ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; | ||
561 | /* or recycle a used one */ | ||
562 | else | ||
563 | ret = virtqueue_get_buf(vrp->svq, &len); | ||
564 | |||
565 | mutex_unlock(&vrp->tx_lock); | ||
566 | |||
567 | return ret; | ||
568 | } | ||
569 | |||
570 | /** | ||
571 | * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed | ||
572 | * @vrp: virtual remote processor state | ||
573 | * | ||
574 | * This function is called before a sender is blocked, waiting for | ||
575 | * a tx buffer to become available. | ||
576 | * | ||
577 | * If we already have blocking senders, this function merely increases | ||
578 | * the "sleepers" reference count, and exits. | ||
579 | * | ||
580 | * Otherwise, if this is the first sender to block, we also enable | ||
581 | * virtio's tx callbacks, so we'd be immediately notified when a tx | ||
582 | * buffer is consumed (we rely on virtio's tx callback in order | ||
583 | * to wake up sleeping senders as soon as a tx buffer is used by the | ||
584 | * remote processor). | ||
585 | */ | ||
586 | static void rpmsg_upref_sleepers(struct virtproc_info *vrp) | ||
587 | { | ||
588 | /* support multiple concurrent senders */ | ||
589 | mutex_lock(&vrp->tx_lock); | ||
590 | |||
591 | /* are we the first sleeping context waiting for tx buffers ? */ | ||
592 | if (atomic_inc_return(&vrp->sleepers) == 1) | ||
593 | /* enable "tx-complete" interrupts before dozing off */ | ||
594 | virtqueue_enable_cb(vrp->svq); | ||
595 | |||
596 | mutex_unlock(&vrp->tx_lock); | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed | ||
601 | * @vrp: virtual remote processor state | ||
602 | * | ||
603 | * This function is called after a sender, that waited for a tx buffer | ||
604 | * to become available, is unblocked. | ||
605 | * | ||
606 | * If we still have blocking senders, this function merely decreases | ||
607 | * the "sleepers" reference count, and exits. | ||
608 | * | ||
609 | * Otherwise, if there are no more blocking senders, we also disable | ||
610 | * virtio's tx callbacks, to avoid the overhead incurred with handling | ||
611 | * those (now redundant) interrupts. | ||
612 | */ | ||
613 | static void rpmsg_downref_sleepers(struct virtproc_info *vrp) | ||
614 | { | ||
615 | /* support multiple concurrent senders */ | ||
616 | mutex_lock(&vrp->tx_lock); | ||
617 | |||
618 | /* are we the last sleeping context waiting for tx buffers ? */ | ||
619 | if (atomic_dec_and_test(&vrp->sleepers)) | ||
620 | /* disable "tx-complete" interrupts */ | ||
621 | virtqueue_disable_cb(vrp->svq); | ||
622 | |||
623 | mutex_unlock(&vrp->tx_lock); | ||
624 | } | ||
625 | |||
626 | /** | ||
627 | * rpmsg_send_offchannel_raw() - send a message across to the remote processor | ||
628 | * @rpdev: the rpmsg channel | ||
629 | * @src: source address | ||
630 | * @dst: destination address | ||
631 | * @data: payload of message | ||
632 | * @len: length of payload | ||
633 | * @wait: indicates whether caller should block in case no TX buffers available | ||
634 | * | ||
635 | * This function is the base implementation for all of the rpmsg sending API. | ||
636 | * | ||
637 | * It will send @data of length @len to @dst, and say it's from @src. The | ||
638 | * message will be sent to the remote processor which the @rpdev channel | ||
639 | * belongs to. | ||
640 | * | ||
641 | * The message is sent using one of the TX buffers that are available for | ||
642 | * communication with this remote processor. | ||
643 | * | ||
644 | * If @wait is true, the caller will be blocked until either a TX buffer is | ||
645 | * available, or 15 seconds elapses (we don't want callers to | ||
646 | * sleep indefinitely due to misbehaving remote processors), and in that | ||
647 | * case -ERESTARTSYS is returned. The number '15' itself was picked | ||
648 | * arbitrarily; there's little point in asking drivers to provide a timeout | ||
649 | * value themselves. | ||
650 | * | ||
651 | * Otherwise, if @wait is false, and there are no TX buffers available, | ||
652 | * the function will immediately fail, and -ENOMEM will be returned. | ||
653 | * | ||
654 | * Normally drivers shouldn't use this function directly; instead, drivers | ||
655 | * should use the appropriate rpmsg_{try}send{to, _offchannel} API | ||
656 | * (see include/linux/rpmsg.h). | ||
657 | * | ||
658 | * Returns 0 on success and an appropriate error value on failure. | ||
659 | */ | ||
660 | int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, | ||
661 | void *data, int len, bool wait) | ||
662 | { | ||
663 | struct virtproc_info *vrp = rpdev->vrp; | ||
664 | struct device *dev = &rpdev->dev; | ||
665 | struct scatterlist sg; | ||
666 | struct rpmsg_hdr *msg; | ||
667 | int err; | ||
668 | |||
669 | /* bcasting isn't allowed */ | ||
670 | if (src == RPMSG_ADDR_ANY || dst == RPMSG_ADDR_ANY) { | ||
671 | dev_err(dev, "invalid addr (src 0x%x, dst 0x%x)\n", src, dst); | ||
672 | return -EINVAL; | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | * We currently use fixed-sized buffers, and therefore the payload | ||
677 | * length is limited. | ||
678 | * | ||
679 | * One of the possible improvements here is either to support | ||
680 | * user-provided buffers (and then we can also support zero-copy | ||
681 | * messaging), or to improve the buffer allocator, to support | ||
682 | * variable-length buffer sizes. | ||
683 | */ | ||
684 | if (len > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) { | ||
685 | dev_err(dev, "message is too big (%d)\n", len); | ||
686 | return -EMSGSIZE; | ||
687 | } | ||
688 | |||
689 | /* grab a buffer */ | ||
690 | msg = get_a_tx_buf(vrp); | ||
691 | if (!msg && !wait) | ||
692 | return -ENOMEM; | ||
693 | |||
694 | /* no free buffer ? wait for one (but bail after 15 seconds) */ | ||
695 | while (!msg) { | ||
696 | /* enable "tx-complete" interrupts, if not already enabled */ | ||
697 | rpmsg_upref_sleepers(vrp); | ||
698 | |||
699 | /* | ||
700 | * sleep until a free buffer is available or 15 secs elapse. | ||
701 | * the timeout period is not configurable because there's | ||
702 | * little point in asking drivers to specify that. | ||
703 | * if later this happens to be required, it'd be easy to add. | ||
704 | */ | ||
705 | err = wait_event_interruptible_timeout(vrp->sendq, | ||
706 | (msg = get_a_tx_buf(vrp)), | ||
707 | msecs_to_jiffies(15000)); | ||
708 | |||
709 | /* disable "tx-complete" interrupts if we're the last sleeper */ | ||
710 | rpmsg_downref_sleepers(vrp); | ||
711 | |||
712 | /* timeout ? */ | ||
713 | if (!err) { | ||
714 | dev_err(dev, "timeout waiting for a tx buffer\n"); | ||
715 | return -ERESTARTSYS; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | msg->len = len; | ||
720 | msg->flags = 0; | ||
721 | msg->src = src; | ||
722 | msg->dst = dst; | ||
723 | msg->reserved = 0; | ||
724 | memcpy(msg->data, data, len); | ||
725 | |||
726 | dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n", | ||
727 | msg->src, msg->dst, msg->len, | ||
728 | msg->flags, msg->reserved); | ||
729 | print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1, | ||
730 | msg, sizeof(*msg) + msg->len, true); | ||
731 | |||
732 | sg_init_one(&sg, msg, sizeof(*msg) + len); | ||
733 | |||
734 | mutex_lock(&vrp->tx_lock); | ||
735 | |||
736 | /* add message to the remote processor's virtqueue */ | ||
737 | err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL); | ||
738 | if (err < 0) { | ||
739 | /* | ||
740 | * need to reclaim the buffer here, otherwise it's lost | ||
741 | * (memory won't leak, but rpmsg won't use it again for TX). | ||
742 | * this will wait for a buffer management overhaul. | ||
743 | */ | ||
744 | dev_err(dev, "virtqueue_add_buf failed: %d\n", err); | ||
745 | goto out; | ||
746 | } | ||
747 | |||
748 | /* tell the remote processor it has a pending message to read */ | ||
749 | virtqueue_kick(vrp->svq); | ||
750 | |||
751 | err = 0; | ||
752 | out: | ||
753 | mutex_unlock(&vrp->tx_lock); | ||
754 | return err; | ||
755 | } | ||
756 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); | ||
757 | |||
758 | /* called when an rx buffer is used, and it's time to digest a message */ | ||
759 | static void rpmsg_recv_done(struct virtqueue *rvq) | ||
760 | { | ||
761 | struct rpmsg_hdr *msg; | ||
762 | unsigned int len; | ||
763 | struct rpmsg_endpoint *ept; | ||
764 | struct scatterlist sg; | ||
765 | struct virtproc_info *vrp = rvq->vdev->priv; | ||
766 | struct device *dev = &rvq->vdev->dev; | ||
767 | int err; | ||
768 | |||
769 | msg = virtqueue_get_buf(rvq, &len); | ||
770 | if (!msg) { | ||
771 | dev_err(dev, "uhm, incoming signal, but no used buffer ?\n"); | ||
772 | return; | ||
773 | } | ||
774 | |||
775 | dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n", | ||
776 | msg->src, msg->dst, msg->len, | ||
777 | msg->flags, msg->reserved); | ||
778 | print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1, | ||
779 | msg, sizeof(*msg) + msg->len, true); | ||
780 | |||
781 | /* | ||
782 | * We currently use fixed-sized buffers, so trivially sanitize | ||
783 | * the reported payload length. | ||
784 | */ | ||
785 | if (len > RPMSG_BUF_SIZE || | ||
786 | msg->len > (len - sizeof(struct rpmsg_hdr))) { | ||
787 | dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len); | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | /* use the dst addr to fetch the callback of the appropriate user */ | ||
792 | mutex_lock(&vrp->endpoints_lock); | ||
793 | ept = idr_find(&vrp->endpoints, msg->dst); | ||
794 | mutex_unlock(&vrp->endpoints_lock); | ||
795 | |||
796 | if (ept && ept->cb) | ||
797 | ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src); | ||
798 | else | ||
799 | dev_warn(dev, "msg received with no recepient\n"); | ||
800 | |||
801 | /* publish the real size of the buffer */ | ||
802 | sg_init_one(&sg, msg, RPMSG_BUF_SIZE); | ||
803 | |||
804 | /* add the buffer back to the remote processor's virtqueue */ | ||
805 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL); | ||
806 | if (err < 0) { | ||
807 | dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); | ||
808 | return; | ||
809 | } | ||
810 | |||
811 | /* tell the remote processor we added another available rx buffer */ | ||
812 | virtqueue_kick(vrp->rvq); | ||
813 | } | ||
814 | |||
815 | /* | ||
816 | * This is invoked whenever the remote processor completed processing | ||
817 | * a TX msg we just sent it, and the buffer is put back to the used ring. | ||
818 | * | ||
819 | * Normally, though, we suppress this "tx complete" interrupt in order to | ||
820 | * avoid the incurred overhead. | ||
821 | */ | ||
822 | static void rpmsg_xmit_done(struct virtqueue *svq) | ||
823 | { | ||
824 | struct virtproc_info *vrp = svq->vdev->priv; | ||
825 | |||
826 | dev_dbg(&svq->vdev->dev, "%s\n", __func__); | ||
827 | |||
828 | /* wake up potential senders that are waiting for a tx buffer */ | ||
829 | wake_up_interruptible(&vrp->sendq); | ||
830 | } | ||
831 | |||
832 | /* invoked when a name service announcement arrives */ | ||
833 | static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len, | ||
834 | void *priv, u32 src) | ||
835 | { | ||
836 | struct rpmsg_ns_msg *msg = data; | ||
837 | struct rpmsg_channel *newch; | ||
838 | struct rpmsg_channel_info chinfo; | ||
839 | struct virtproc_info *vrp = priv; | ||
840 | struct device *dev = &vrp->vdev->dev; | ||
841 | int ret; | ||
842 | |||
843 | print_hex_dump(KERN_DEBUG, "NS announcement: ", | ||
844 | DUMP_PREFIX_NONE, 16, 1, | ||
845 | data, len, true); | ||
846 | |||
847 | if (len != sizeof(*msg)) { | ||
848 | dev_err(dev, "malformed ns msg (%d)\n", len); | ||
849 | return; | ||
850 | } | ||
851 | |||
852 | /* | ||
853 | * the name service ept does _not_ belong to a real rpmsg channel, | ||
854 | * and is handled by the rpmsg bus itself. | ||
855 | * for sanity reasons, make sure a valid rpdev has _not_ sneaked | ||
856 | * in somehow. | ||
857 | */ | ||
858 | if (rpdev) { | ||
859 | dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); | ||
860 | return; | ||
861 | } | ||
862 | |||
863 | /* don't trust the remote processor for null terminating the name */ | ||
864 | msg->name[RPMSG_NAME_SIZE - 1] = '\0'; | ||
865 | |||
866 | dev_info(dev, "%sing channel %s addr 0x%x\n", | ||
867 | msg->flags & RPMSG_NS_DESTROY ? "destroy" : "creat", | ||
868 | msg->name, msg->addr); | ||
869 | |||
870 | strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); | ||
871 | chinfo.src = RPMSG_ADDR_ANY; | ||
872 | chinfo.dst = msg->addr; | ||
873 | |||
874 | if (msg->flags & RPMSG_NS_DESTROY) { | ||
875 | ret = rpmsg_destroy_channel(vrp, &chinfo); | ||
876 | if (ret) | ||
877 | dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); | ||
878 | } else { | ||
879 | newch = rpmsg_create_channel(vrp, &chinfo); | ||
880 | if (!newch) | ||
881 | dev_err(dev, "rpmsg_create_channel failed\n"); | ||
882 | } | ||
883 | } | ||
884 | |||
885 | static int rpmsg_probe(struct virtio_device *vdev) | ||
886 | { | ||
887 | vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; | ||
888 | const char *names[] = { "input", "output" }; | ||
889 | struct virtqueue *vqs[2]; | ||
890 | struct virtproc_info *vrp; | ||
891 | void *bufs_va; | ||
892 | int err = 0, i; | ||
893 | |||
894 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); | ||
895 | if (!vrp) | ||
896 | return -ENOMEM; | ||
897 | |||
898 | vrp->vdev = vdev; | ||
899 | |||
900 | idr_init(&vrp->endpoints); | ||
901 | mutex_init(&vrp->endpoints_lock); | ||
902 | mutex_init(&vrp->tx_lock); | ||
903 | init_waitqueue_head(&vrp->sendq); | ||
904 | |||
905 | /* We expect two virtqueues, rx and tx (and in this order) */ | ||
906 | err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names); | ||
907 | if (err) | ||
908 | goto free_vrp; | ||
909 | |||
910 | vrp->rvq = vqs[0]; | ||
911 | vrp->svq = vqs[1]; | ||
912 | |||
913 | /* allocate coherent memory for the buffers */ | ||
914 | bufs_va = dma_alloc_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, | ||
915 | &vrp->bufs_dma, GFP_KERNEL); | ||
916 | if (!bufs_va) | ||
917 | goto vqs_del; | ||
918 | |||
919 | dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%llx\n", bufs_va, | ||
920 | (unsigned long long)vrp->bufs_dma); | ||
921 | |||
922 | /* half of the buffers is dedicated for RX */ | ||
923 | vrp->rbufs = bufs_va; | ||
924 | |||
925 | /* and half is dedicated for TX */ | ||
926 | vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2; | ||
927 | |||
928 | /* set up the receive buffers */ | ||
929 | for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) { | ||
930 | struct scatterlist sg; | ||
931 | void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; | ||
932 | |||
933 | sg_init_one(&sg, cpu_addr, RPMSG_BUF_SIZE); | ||
934 | |||
935 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr, | ||
936 | GFP_KERNEL); | ||
937 | WARN_ON(err < 0); /* sanity check; this can't really happen */ | ||
938 | } | ||
939 | |||
940 | /* suppress "tx-complete" interrupts */ | ||
941 | virtqueue_disable_cb(vrp->svq); | ||
942 | |||
943 | vdev->priv = vrp; | ||
944 | |||
945 | /* if supported by the remote processor, enable the name service */ | ||
946 | if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { | ||
947 | /* a dedicated endpoint handles the name service msgs */ | ||
948 | vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb, | ||
949 | vrp, RPMSG_NS_ADDR); | ||
950 | if (!vrp->ns_ept) { | ||
951 | dev_err(&vdev->dev, "failed to create the ns ept\n"); | ||
952 | err = -ENOMEM; | ||
953 | goto free_coherent; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | /* tell the remote processor it can start sending messages */ | ||
958 | virtqueue_kick(vrp->rvq); | ||
959 | |||
960 | dev_info(&vdev->dev, "rpmsg host is online\n"); | ||
961 | |||
962 | return 0; | ||
963 | |||
964 | free_coherent: | ||
965 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va, | ||
966 | vrp->bufs_dma); | ||
967 | vqs_del: | ||
968 | vdev->config->del_vqs(vrp->vdev); | ||
969 | free_vrp: | ||
970 | kfree(vrp); | ||
971 | return err; | ||
972 | } | ||
973 | |||
974 | static int rpmsg_remove_device(struct device *dev, void *data) | ||
975 | { | ||
976 | device_unregister(dev); | ||
977 | |||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | static void __devexit rpmsg_remove(struct virtio_device *vdev) | ||
982 | { | ||
983 | struct virtproc_info *vrp = vdev->priv; | ||
984 | int ret; | ||
985 | |||
986 | vdev->config->reset(vdev); | ||
987 | |||
988 | ret = device_for_each_child(&vdev->dev, NULL, rpmsg_remove_device); | ||
989 | if (ret) | ||
990 | dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); | ||
991 | |||
992 | if (vrp->ns_ept) | ||
993 | __rpmsg_destroy_ept(vrp, vrp->ns_ept); | ||
994 | |||
995 | idr_remove_all(&vrp->endpoints); | ||
996 | idr_destroy(&vrp->endpoints); | ||
997 | |||
998 | vdev->config->del_vqs(vrp->vdev); | ||
999 | |||
1000 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, | ||
1001 | vrp->rbufs, vrp->bufs_dma); | ||
1002 | |||
1003 | kfree(vrp); | ||
1004 | } | ||
1005 | |||
1006 | static struct virtio_device_id id_table[] = { | ||
1007 | { VIRTIO_ID_RPMSG, VIRTIO_DEV_ANY_ID }, | ||
1008 | { 0 }, | ||
1009 | }; | ||
1010 | |||
1011 | static unsigned int features[] = { | ||
1012 | VIRTIO_RPMSG_F_NS, | ||
1013 | }; | ||
1014 | |||
1015 | static struct virtio_driver virtio_ipc_driver = { | ||
1016 | .feature_table = features, | ||
1017 | .feature_table_size = ARRAY_SIZE(features), | ||
1018 | .driver.name = KBUILD_MODNAME, | ||
1019 | .driver.owner = THIS_MODULE, | ||
1020 | .id_table = id_table, | ||
1021 | .probe = rpmsg_probe, | ||
1022 | .remove = __devexit_p(rpmsg_remove), | ||
1023 | }; | ||
1024 | |||
1025 | static int __init rpmsg_init(void) | ||
1026 | { | ||
1027 | int ret; | ||
1028 | |||
1029 | ret = bus_register(&rpmsg_bus); | ||
1030 | if (ret) { | ||
1031 | pr_err("failed to register rpmsg bus: %d\n", ret); | ||
1032 | return ret; | ||
1033 | } | ||
1034 | |||
1035 | ret = register_virtio_driver(&virtio_ipc_driver); | ||
1036 | if (ret) { | ||
1037 | pr_err("failed to register virtio driver: %d\n", ret); | ||
1038 | bus_unregister(&rpmsg_bus); | ||
1039 | } | ||
1040 | |||
1041 | return ret; | ||
1042 | } | ||
1043 | module_init(rpmsg_init); | ||
1044 | |||
1045 | static void __exit rpmsg_fini(void) | ||
1046 | { | ||
1047 | unregister_virtio_driver(&virtio_ipc_driver); | ||
1048 | bus_unregister(&rpmsg_bus); | ||
1049 | } | ||
1050 | module_exit(rpmsg_fini); | ||
1051 | |||
1052 | MODULE_DEVICE_TABLE(virtio, id_table); | ||
1053 | MODULE_DESCRIPTION("Virtio-based remote processor messaging bus"); | ||
1054 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index fb69ad191ad7..501da4cb8a6d 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..f1ffabb978d3 --- /dev/null +++ b/include/linux/remoteproc.h | |||
@@ -0,0 +1,478 @@ | |||
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 | #include <linux/idr.h> | ||
45 | |||
46 | /** | ||
47 | * struct resource_table - firmware resource table header | ||
48 | * @ver: version number | ||
49 | * @num: number of resource entries | ||
50 | * @reserved: reserved (must be zero) | ||
51 | * @offset: array of offsets pointing at the various resource entries | ||
52 | * | ||
53 | * A resource table is essentially a list of system resources required | ||
54 | * by the remote processor. It may also include configuration entries. | ||
55 | * If needed, the remote processor firmware should contain this table | ||
56 | * as a dedicated ".resource_table" ELF section. | ||
57 | * | ||
58 | * Some resources entries are mere announcements, where the host is informed | ||
59 | * of specific remoteproc configuration. Other entries require the host to | ||
60 | * do something (e.g. allocate a system resource). Sometimes a negotiation | ||
61 | * is expected, where the firmware requests a resource, and once allocated, | ||
62 | * the host should provide back its details (e.g. address of an allocated | ||
63 | * memory region). | ||
64 | * | ||
65 | * The header of the resource table, as expressed by this structure, | ||
66 | * contains a version number (should we need to change this format in the | ||
67 | * future), the number of available resource entries, and their offsets | ||
68 | * in the table. | ||
69 | * | ||
70 | * Immediately following this header are the resource entries themselves, | ||
71 | * each of which begins with a resource entry header (as described below). | ||
72 | */ | ||
73 | struct resource_table { | ||
74 | u32 ver; | ||
75 | u32 num; | ||
76 | u32 reserved[2]; | ||
77 | u32 offset[0]; | ||
78 | } __packed; | ||
79 | |||
80 | /** | ||
81 | * struct fw_rsc_hdr - firmware resource entry header | ||
82 | * @type: resource type | ||
83 | * @data: resource data | ||
84 | * | ||
85 | * Every resource entry begins with a 'struct fw_rsc_hdr' header providing | ||
86 | * its @type. The content of the entry itself will immediately follow | ||
87 | * this header, and it should be parsed according to the resource type. | ||
88 | */ | ||
89 | struct fw_rsc_hdr { | ||
90 | u32 type; | ||
91 | u8 data[0]; | ||
92 | } __packed; | ||
93 | |||
94 | /** | ||
95 | * enum fw_resource_type - types of resource entries | ||
96 | * | ||
97 | * @RSC_CARVEOUT: request for allocation of a physically contiguous | ||
98 | * memory region. | ||
99 | * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. | ||
100 | * @RSC_TRACE: announces the availability of a trace buffer into which | ||
101 | * the remote processor will be writing logs. | ||
102 | * @RSC_VDEV: declare support for a virtio device, and serve as its | ||
103 | * virtio header. | ||
104 | * @RSC_LAST: just keep this one at the end | ||
105 | * | ||
106 | * For more details regarding a specific resource type, please see its | ||
107 | * dedicated structure below. | ||
108 | * | ||
109 | * Please note that these values are used as indices to the rproc_handle_rsc | ||
110 | * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to | ||
111 | * check the validity of an index before the lookup table is accessed, so | ||
112 | * please update it as needed. | ||
113 | */ | ||
114 | enum fw_resource_type { | ||
115 | RSC_CARVEOUT = 0, | ||
116 | RSC_DEVMEM = 1, | ||
117 | RSC_TRACE = 2, | ||
118 | RSC_VDEV = 3, | ||
119 | RSC_LAST = 4, | ||
120 | }; | ||
121 | |||
122 | #define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF) | ||
123 | |||
124 | /** | ||
125 | * struct fw_rsc_carveout - physically contiguous memory request | ||
126 | * @da: device address | ||
127 | * @pa: physical address | ||
128 | * @len: length (in bytes) | ||
129 | * @flags: iommu protection flags | ||
130 | * @reserved: reserved (must be zero) | ||
131 | * @name: human-readable name of the requested memory region | ||
132 | * | ||
133 | * This resource entry requests the host to allocate a physically contiguous | ||
134 | * memory region. | ||
135 | * | ||
136 | * These request entries should precede other firmware resource entries, | ||
137 | * as other entries might request placing other data objects inside | ||
138 | * these memory regions (e.g. data/code segments, trace resource entries, ...). | ||
139 | * | ||
140 | * Allocating memory this way helps utilizing the reserved physical memory | ||
141 | * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries | ||
142 | * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB | ||
143 | * pressure is important; it may have a substantial impact on performance. | ||
144 | * | ||
145 | * If the firmware is compiled with static addresses, then @da should specify | ||
146 | * the expected device address of this memory region. If @da is set to | ||
147 | * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then | ||
148 | * overwrite @da with the dynamically allocated address. | ||
149 | * | ||
150 | * We will always use @da to negotiate the device addresses, even if it | ||
151 | * isn't using an iommu. In that case, though, it will obviously contain | ||
152 | * physical addresses. | ||
153 | * | ||
154 | * Some remote processors needs to know the allocated physical address | ||
155 | * even if they do use an iommu. This is needed, e.g., if they control | ||
156 | * hardware accelerators which access the physical memory directly (this | ||
157 | * is the case with OMAP4 for instance). In that case, the host will | ||
158 | * overwrite @pa with the dynamically allocated physical address. | ||
159 | * Generally we don't want to expose physical addresses if we don't have to | ||
160 | * (remote processors are generally _not_ trusted), so we might want to | ||
161 | * change this to happen _only_ when explicitly required by the hardware. | ||
162 | * | ||
163 | * @flags is used to provide IOMMU protection flags, and @name should | ||
164 | * (optionally) contain a human readable name of this carveout region | ||
165 | * (mainly for debugging purposes). | ||
166 | */ | ||
167 | struct fw_rsc_carveout { | ||
168 | u32 da; | ||
169 | u32 pa; | ||
170 | u32 len; | ||
171 | u32 flags; | ||
172 | u32 reserved; | ||
173 | u8 name[32]; | ||
174 | } __packed; | ||
175 | |||
176 | /** | ||
177 | * struct fw_rsc_devmem - iommu mapping request | ||
178 | * @da: device address | ||
179 | * @pa: physical address | ||
180 | * @len: length (in bytes) | ||
181 | * @flags: iommu protection flags | ||
182 | * @reserved: reserved (must be zero) | ||
183 | * @name: human-readable name of the requested region to be mapped | ||
184 | * | ||
185 | * This resource entry requests the host to iommu map a physically contiguous | ||
186 | * memory region. This is needed in case the remote processor requires | ||
187 | * access to certain memory-based peripherals; _never_ use it to access | ||
188 | * regular memory. | ||
189 | * | ||
190 | * This is obviously only needed if the remote processor is accessing memory | ||
191 | * via an iommu. | ||
192 | * | ||
193 | * @da should specify the required device address, @pa should specify | ||
194 | * the physical address we want to map, @len should specify the size of | ||
195 | * the mapping and @flags is the IOMMU protection flags. As always, @name may | ||
196 | * (optionally) contain a human readable name of this mapping (mainly for | ||
197 | * debugging purposes). | ||
198 | * | ||
199 | * Note: at this point we just "trust" those devmem entries to contain valid | ||
200 | * physical addresses, but this isn't safe and will be changed: eventually we | ||
201 | * want remoteproc implementations to provide us ranges of physical addresses | ||
202 | * the firmware is allowed to request, and not allow firmwares to request | ||
203 | * access to physical addresses that are outside those ranges. | ||
204 | */ | ||
205 | struct fw_rsc_devmem { | ||
206 | u32 da; | ||
207 | u32 pa; | ||
208 | u32 len; | ||
209 | u32 flags; | ||
210 | u32 reserved; | ||
211 | u8 name[32]; | ||
212 | } __packed; | ||
213 | |||
214 | /** | ||
215 | * struct fw_rsc_trace - trace buffer declaration | ||
216 | * @da: device address | ||
217 | * @len: length (in bytes) | ||
218 | * @reserved: reserved (must be zero) | ||
219 | * @name: human-readable name of the trace buffer | ||
220 | * | ||
221 | * This resource entry provides the host information about a trace buffer | ||
222 | * into which the remote processor will write log messages. | ||
223 | * | ||
224 | * @da specifies the device address of the buffer, @len specifies | ||
225 | * its size, and @name may contain a human readable name of the trace buffer. | ||
226 | * | ||
227 | * After booting the remote processor, the trace buffers are exposed to the | ||
228 | * user via debugfs entries (called trace0, trace1, etc..). | ||
229 | */ | ||
230 | struct fw_rsc_trace { | ||
231 | u32 da; | ||
232 | u32 len; | ||
233 | u32 reserved; | ||
234 | u8 name[32]; | ||
235 | } __packed; | ||
236 | |||
237 | /** | ||
238 | * struct fw_rsc_vdev_vring - vring descriptor entry | ||
239 | * @da: device address | ||
240 | * @align: the alignment between the consumer and producer parts of the vring | ||
241 | * @num: num of buffers supported by this vring (must be power of two) | ||
242 | * @notifyid is a unique rproc-wide notify index for this vring. This notify | ||
243 | * index is used when kicking a remote processor, to let it know that this | ||
244 | * vring is triggered. | ||
245 | * @reserved: reserved (must be zero) | ||
246 | * | ||
247 | * This descriptor is not a resource entry by itself; it is part of the | ||
248 | * vdev resource type (see below). | ||
249 | * | ||
250 | * Note that @da should either contain the device address where | ||
251 | * the remote processor is expecting the vring, or indicate that | ||
252 | * dynamically allocation of the vring's device address is supported. | ||
253 | */ | ||
254 | struct fw_rsc_vdev_vring { | ||
255 | u32 da; | ||
256 | u32 align; | ||
257 | u32 num; | ||
258 | u32 notifyid; | ||
259 | u32 reserved; | ||
260 | } __packed; | ||
261 | |||
262 | /** | ||
263 | * struct fw_rsc_vdev - virtio device header | ||
264 | * @id: virtio device id (as in virtio_ids.h) | ||
265 | * @notifyid is a unique rproc-wide notify index for this vdev. This notify | ||
266 | * index is used when kicking a remote processor, to let it know that the | ||
267 | * status/features of this vdev have changes. | ||
268 | * @dfeatures specifies the virtio device features supported by the firmware | ||
269 | * @gfeatures is a place holder used by the host to write back the | ||
270 | * negotiated features that are supported by both sides. | ||
271 | * @config_len is the size of the virtio config space of this vdev. The config | ||
272 | * space lies in the resource table immediate after this vdev header. | ||
273 | * @status is a place holder where the host will indicate its virtio progress. | ||
274 | * @num_of_vrings indicates how many vrings are described in this vdev header | ||
275 | * @reserved: reserved (must be zero) | ||
276 | * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'. | ||
277 | * | ||
278 | * This resource is a virtio device header: it provides information about | ||
279 | * the vdev, and is then used by the host and its peer remote processors | ||
280 | * to negotiate and share certain virtio properties. | ||
281 | * | ||
282 | * By providing this resource entry, the firmware essentially asks remoteproc | ||
283 | * to statically allocate a vdev upon registration of the rproc (dynamic vdev | ||
284 | * allocation is not yet supported). | ||
285 | * | ||
286 | * Note: unlike virtualization systems, the term 'host' here means | ||
287 | * the Linux side which is running remoteproc to control the remote | ||
288 | * processors. We use the name 'gfeatures' to comply with virtio's terms, | ||
289 | * though there isn't really any virtualized guest OS here: it's the host | ||
290 | * which is responsible for negotiating the final features. | ||
291 | * Yeah, it's a bit confusing. | ||
292 | * | ||
293 | * Note: immediately following this structure is the virtio config space for | ||
294 | * this vdev (which is specific to the vdev; for more info, read the virtio | ||
295 | * spec). the size of the config space is specified by @config_len. | ||
296 | */ | ||
297 | struct fw_rsc_vdev { | ||
298 | u32 id; | ||
299 | u32 notifyid; | ||
300 | u32 dfeatures; | ||
301 | u32 gfeatures; | ||
302 | u32 config_len; | ||
303 | u8 status; | ||
304 | u8 num_of_vrings; | ||
305 | u8 reserved[2]; | ||
306 | struct fw_rsc_vdev_vring vring[0]; | ||
307 | } __packed; | ||
308 | |||
309 | /** | ||
310 | * struct rproc_mem_entry - memory entry descriptor | ||
311 | * @va: virtual address | ||
312 | * @dma: dma address | ||
313 | * @len: length, in bytes | ||
314 | * @da: device address | ||
315 | * @priv: associated data | ||
316 | * @node: list node | ||
317 | */ | ||
318 | struct rproc_mem_entry { | ||
319 | void *va; | ||
320 | dma_addr_t dma; | ||
321 | int len; | ||
322 | u32 da; | ||
323 | void *priv; | ||
324 | struct list_head node; | ||
325 | }; | ||
326 | |||
327 | struct rproc; | ||
328 | |||
329 | /** | ||
330 | * struct rproc_ops - platform-specific device handlers | ||
331 | * @start: power on the device and boot it | ||
332 | * @stop: power off the device | ||
333 | * @kick: kick a virtqueue (virtqueue id given as a parameter) | ||
334 | */ | ||
335 | struct rproc_ops { | ||
336 | int (*start)(struct rproc *rproc); | ||
337 | int (*stop)(struct rproc *rproc); | ||
338 | void (*kick)(struct rproc *rproc, int vqid); | ||
339 | }; | ||
340 | |||
341 | /** | ||
342 | * enum rproc_state - remote processor states | ||
343 | * @RPROC_OFFLINE: device is powered off | ||
344 | * @RPROC_SUSPENDED: device is suspended; needs to be woken up to receive | ||
345 | * a message. | ||
346 | * @RPROC_RUNNING: device is up and running | ||
347 | * @RPROC_CRASHED: device has crashed; need to start recovery | ||
348 | * @RPROC_LAST: just keep this one at the end | ||
349 | * | ||
350 | * Please note that the values of these states are used as indices | ||
351 | * to rproc_state_string, a state-to-name lookup table, | ||
352 | * so please keep the two synchronized. @RPROC_LAST is used to check | ||
353 | * the validity of an index before the lookup table is accessed, so | ||
354 | * please update it as needed too. | ||
355 | */ | ||
356 | enum rproc_state { | ||
357 | RPROC_OFFLINE = 0, | ||
358 | RPROC_SUSPENDED = 1, | ||
359 | RPROC_RUNNING = 2, | ||
360 | RPROC_CRASHED = 3, | ||
361 | RPROC_LAST = 4, | ||
362 | }; | ||
363 | |||
364 | /** | ||
365 | * struct rproc - represents a physical remote processor device | ||
366 | * @node: klist node of this rproc object | ||
367 | * @domain: iommu domain | ||
368 | * @name: human readable name of the rproc | ||
369 | * @firmware: name of firmware file to be loaded | ||
370 | * @priv: private data which belongs to the platform-specific rproc module | ||
371 | * @ops: platform-specific start/stop rproc handlers | ||
372 | * @dev: underlying device | ||
373 | * @refcount: refcount of users that have a valid pointer to this rproc | ||
374 | * @power: refcount of users who need this rproc powered up | ||
375 | * @state: state of the device | ||
376 | * @lock: lock which protects concurrent manipulations of the rproc | ||
377 | * @dbg_dir: debugfs directory of this rproc device | ||
378 | * @traces: list of trace buffers | ||
379 | * @num_traces: number of trace buffers | ||
380 | * @carveouts: list of physically contiguous memory allocations | ||
381 | * @mappings: list of iommu mappings we initiated, needed on shutdown | ||
382 | * @firmware_loading_complete: marks e/o asynchronous firmware loading | ||
383 | * @bootaddr: address of first instruction to boot rproc with (optional) | ||
384 | * @rvdevs: list of remote virtio devices | ||
385 | * @notifyids: idr for dynamically assigning rproc-wide unique notify ids | ||
386 | */ | ||
387 | struct rproc { | ||
388 | struct klist_node node; | ||
389 | struct iommu_domain *domain; | ||
390 | const char *name; | ||
391 | const char *firmware; | ||
392 | void *priv; | ||
393 | const struct rproc_ops *ops; | ||
394 | struct device *dev; | ||
395 | struct kref refcount; | ||
396 | atomic_t power; | ||
397 | unsigned int state; | ||
398 | struct mutex lock; | ||
399 | struct dentry *dbg_dir; | ||
400 | struct list_head traces; | ||
401 | int num_traces; | ||
402 | struct list_head carveouts; | ||
403 | struct list_head mappings; | ||
404 | struct completion firmware_loading_complete; | ||
405 | u32 bootaddr; | ||
406 | struct list_head rvdevs; | ||
407 | struct idr notifyids; | ||
408 | }; | ||
409 | |||
410 | /* we currently support only two vrings per rvdev */ | ||
411 | #define RVDEV_NUM_VRINGS 2 | ||
412 | |||
413 | /** | ||
414 | * struct rproc_vring - remoteproc vring state | ||
415 | * @va: virtual address | ||
416 | * @dma: dma address | ||
417 | * @len: length, in bytes | ||
418 | * @da: device address | ||
419 | * @align: vring alignment | ||
420 | * @notifyid: rproc-specific unique vring index | ||
421 | * @rvdev: remote vdev | ||
422 | * @vq: the virtqueue of this vring | ||
423 | */ | ||
424 | struct rproc_vring { | ||
425 | void *va; | ||
426 | dma_addr_t dma; | ||
427 | int len; | ||
428 | u32 da; | ||
429 | u32 align; | ||
430 | int notifyid; | ||
431 | struct rproc_vdev *rvdev; | ||
432 | struct virtqueue *vq; | ||
433 | }; | ||
434 | |||
435 | /** | ||
436 | * struct rproc_vdev - remoteproc state for a supported virtio device | ||
437 | * @node: list node | ||
438 | * @rproc: the rproc handle | ||
439 | * @vdev: the virio device | ||
440 | * @vring: the vrings for this vdev | ||
441 | * @dfeatures: virtio device features | ||
442 | * @gfeatures: virtio guest features | ||
443 | */ | ||
444 | struct rproc_vdev { | ||
445 | struct list_head node; | ||
446 | struct rproc *rproc; | ||
447 | struct virtio_device vdev; | ||
448 | struct rproc_vring vring[RVDEV_NUM_VRINGS]; | ||
449 | unsigned long dfeatures; | ||
450 | unsigned long gfeatures; | ||
451 | }; | ||
452 | |||
453 | struct rproc *rproc_get_by_name(const char *name); | ||
454 | void rproc_put(struct rproc *rproc); | ||
455 | |||
456 | struct rproc *rproc_alloc(struct device *dev, const char *name, | ||
457 | const struct rproc_ops *ops, | ||
458 | const char *firmware, int len); | ||
459 | void rproc_free(struct rproc *rproc); | ||
460 | int rproc_register(struct rproc *rproc); | ||
461 | int rproc_unregister(struct rproc *rproc); | ||
462 | |||
463 | int rproc_boot(struct rproc *rproc); | ||
464 | void rproc_shutdown(struct rproc *rproc); | ||
465 | |||
466 | static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev) | ||
467 | { | ||
468 | return container_of(vdev, struct rproc_vdev, vdev); | ||
469 | } | ||
470 | |||
471 | static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) | ||
472 | { | ||
473 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
474 | |||
475 | return rvdev->rproc; | ||
476 | } | ||
477 | |||
478 | #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 c5d8455c68c0..7529b854b7fd 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_SCSI 8 /* virtio scsi */ | 38 | #define VIRTIO_ID_SCSI 8 /* virtio scsi */ |
38 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ | 39 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ |
39 | 40 | ||
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"); | ||