at v3.4-rc4 12 kB view raw
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 */ 56struct 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 */ 77struct 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 */ 89enum rpmsg_ns_flags { 90 RPMSG_NS_CREATE = 0, 91 RPMSG_NS_DESTROY = 1, 92}; 93 94#define RPMSG_ADDR_ANY 0xFFFFFFFF 95 96struct 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 */ 108struct 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 118typedef 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 */ 141struct 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 */ 156struct 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 164int register_rpmsg_device(struct rpmsg_channel *dev); 165void unregister_rpmsg_device(struct rpmsg_channel *dev); 166int register_rpmsg_driver(struct rpmsg_driver *drv); 167void unregister_rpmsg_driver(struct rpmsg_driver *drv); 168void rpmsg_destroy_ept(struct rpmsg_endpoint *); 169struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *, 170 rpmsg_rx_cb_t cb, void *priv, u32 addr); 171int 172rpmsg_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 */ 191static 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 */ 216static inline 217int 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 */ 244static inline 245int 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 */ 267static inline 268int 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 */ 292static inline 293int 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 */ 319static inline 320int 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 */