Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | /* SPDX-License-Identifier: BSD-3-Clause */ /* * Remote processor messaging * * Copyright (C) 2011 Texas Instruments, Inc. * Copyright (C) 2011 Google, Inc. * All rights reserved. */ #ifndef _LINUX_RPMSG_H #define _LINUX_RPMSG_H #include <linux/types.h> #include <linux/device.h> #include <linux/err.h> #include <linux/mod_devicetable.h> #include <linux/kref.h> #include <linux/mutex.h> #include <linux/poll.h> #define RPMSG_ADDR_ANY 0xFFFFFFFF struct rpmsg_device; struct rpmsg_endpoint; struct rpmsg_device_ops; struct rpmsg_endpoint_ops; /** * struct rpmsg_channel_info - channel info representation * @name: name of service * @src: local address * @dst: destination address */ struct rpmsg_channel_info { char name[RPMSG_NAME_SIZE]; u32 src; u32 dst; }; /** * rpmsg_device - device that belong to the rpmsg bus * @dev: the device struct * @id: device id (used to match between rpmsg drivers and devices) * @driver_override: driver name to force a match * @src: local address * @dst: destination address * @ept: the rpmsg endpoint of this channel * @announce: if set, rpmsg will announce the creation/removal of this channel */ struct rpmsg_device { struct device dev; struct rpmsg_device_id id; char *driver_override; u32 src; u32 dst; struct rpmsg_endpoint *ept; bool announce; const struct rpmsg_device_ops *ops; }; typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); /** * struct rpmsg_endpoint - binds a local rpmsg address to its user * @rpdev: rpmsg channel device * @refcount: when this drops to zero, the ept is deallocated * @cb: rx callback handler * @cb_lock: must be taken before accessing/changing @cb * @addr: local rpmsg address * @priv: private data for the driver's use * * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as * it binds an rpmsg address with an rx callback handler. * * Simple rpmsg drivers shouldn't use this struct directly, because * things just work: every rpmsg driver provides an rx callback upon * registering to the bus, and that callback is then bound to its rpmsg * address when the driver is probed. When relevant inbound messages arrive * (i.e. messages which their dst address equals to the src address of * the rpmsg channel), the driver's handler is invoked to process it. * * More complicated drivers though, that do need to allocate additional rpmsg * addresses, and bind them to different rx callbacks, must explicitly * create additional endpoints by themselves (see rpmsg_create_ept()). */ struct rpmsg_endpoint { struct rpmsg_device *rpdev; struct kref refcount; rpmsg_rx_cb_t cb; struct mutex cb_lock; u32 addr; void *priv; const struct rpmsg_endpoint_ops *ops; }; /** * struct rpmsg_driver - rpmsg driver struct * @drv: underlying device driver * @id_table: rpmsg ids serviced by this driver * @probe: invoked when a matching rpmsg channel (i.e. device) is found * @remove: invoked when the rpmsg channel is removed * @callback: invoked when an inbound message is received on the channel */ struct rpmsg_driver { struct device_driver drv; const struct rpmsg_device_id *id_table; int (*probe)(struct rpmsg_device *dev); void (*remove)(struct rpmsg_device *dev); int (*callback)(struct rpmsg_device *, void *, int, void *, u32); }; #if IS_ENABLED(CONFIG_RPMSG) int register_rpmsg_device(struct rpmsg_device *dev); void unregister_rpmsg_device(struct rpmsg_device *dev); int __register_rpmsg_driver(struct rpmsg_driver *drv, struct module *owner); void unregister_rpmsg_driver(struct rpmsg_driver *drv); void rpmsg_destroy_ept(struct rpmsg_endpoint *); struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *, rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo); int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len); int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst); int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len); int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len); int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst); int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len); __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, poll_table *wait); #else static inline int register_rpmsg_device(struct rpmsg_device *dev) { return -ENXIO; } static inline void unregister_rpmsg_device(struct rpmsg_device *dev) { /* This shouldn't be possible */ WARN_ON(1); } static inline int __register_rpmsg_driver(struct rpmsg_driver *drv, struct module *owner) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline void unregister_rpmsg_driver(struct rpmsg_driver *drv) { /* This shouldn't be possible */ WARN_ON(1); } static inline void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) { /* This shouldn't be possible */ WARN_ON(1); } static inline struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo) { /* This shouldn't be possible */ WARN_ON(1); return NULL; } static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, void *data, int len) { /* This shouldn't be possible */ WARN_ON(1); return -ENXIO; } static inline __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, poll_table *wait) { /* This shouldn't be possible */ WARN_ON(1); return 0; } #endif /* IS_ENABLED(CONFIG_RPMSG) */ /* use a macro to avoid include chaining to get THIS_MODULE */ #define register_rpmsg_driver(drv) \ __register_rpmsg_driver(drv, THIS_MODULE) /** * module_rpmsg_driver() - Helper macro for registering an rpmsg driver * @__rpmsg_driver: rpmsg_driver struct * * Helper macro for rpmsg drivers which do not do anything special in module * init/exit. This eliminates a lot of boilerplate. Each module may only * use this macro once, and calling it replaces module_init() and module_exit() */ #define module_rpmsg_driver(__rpmsg_driver) \ module_driver(__rpmsg_driver, register_rpmsg_driver, \ unregister_rpmsg_driver) #endif /* _LINUX_RPMSG_H */ |