diff options
Diffstat (limited to 'include/linux/rpmsg.h')
-rw-r--r-- | include/linux/rpmsg.h | 115 |
1 files changed, 91 insertions, 24 deletions
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 9fe156d1c018..fb7ab9165645 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -17,8 +17,8 @@ #include <linux/kref.h> #include <linux/mutex.h> #include <linux/poll.h> - -#define RPMSG_ADDR_ANY 0xFFFFFFFF +#include <linux/rpmsg/byteorder.h> +#include <uapi/linux/rpmsg.h> struct rpmsg_device; struct rpmsg_endpoint; @@ -41,31 +41,37 @@ struct rpmsg_channel_info { * 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 + * @driver_override: driver name to force a match; do not set directly, + * because core frees it; use driver_set_override() to + * set or clear it. * @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 + * @little_endian: True if transport is using little endian byte representation */ struct rpmsg_device { struct device dev; struct rpmsg_device_id id; - char *driver_override; + const char *driver_override; u32 src; u32 dst; struct rpmsg_endpoint *ept; bool announce; + bool little_endian; const struct rpmsg_device_ops *ops; }; typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); +typedef int (*rpmsg_flowcontrol_cb_t)(struct rpmsg_device *, void *, bool); /** * 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 + * @flow_cb: remote flow control callback handler * @cb_lock: must be taken before accessing/changing @cb * @addr: local rpmsg address * @priv: private data for the driver's use @@ -88,6 +94,7 @@ struct rpmsg_endpoint { struct rpmsg_device *rpdev; struct kref refcount; rpmsg_rx_cb_t cb; + rpmsg_flowcontrol_cb_t flow_cb; struct mutex cb_lock; u32 addr; void *priv; @@ -102,6 +109,7 @@ struct rpmsg_endpoint { * @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 + * @flowcontrol: invoked when remote side flow control request is received */ struct rpmsg_driver { struct device_driver drv; @@ -109,12 +117,64 @@ struct rpmsg_driver { int (*probe)(struct rpmsg_device *dev); void (*remove)(struct rpmsg_device *dev); int (*callback)(struct rpmsg_device *, void *, int, void *, u32); + int (*flowcontrol)(struct rpmsg_device *, void *, bool); }; +static inline u16 rpmsg16_to_cpu(struct rpmsg_device *rpdev, __rpmsg16 val) +{ + if (!rpdev) + return __rpmsg16_to_cpu(rpmsg_is_little_endian(), val); + else + return __rpmsg16_to_cpu(rpdev->little_endian, val); +} + +static inline __rpmsg16 cpu_to_rpmsg16(struct rpmsg_device *rpdev, u16 val) +{ + if (!rpdev) + return __cpu_to_rpmsg16(rpmsg_is_little_endian(), val); + else + return __cpu_to_rpmsg16(rpdev->little_endian, val); +} + +static inline u32 rpmsg32_to_cpu(struct rpmsg_device *rpdev, __rpmsg32 val) +{ + if (!rpdev) + return __rpmsg32_to_cpu(rpmsg_is_little_endian(), val); + else + return __rpmsg32_to_cpu(rpdev->little_endian, val); +} + +static inline __rpmsg32 cpu_to_rpmsg32(struct rpmsg_device *rpdev, u32 val) +{ + if (!rpdev) + return __cpu_to_rpmsg32(rpmsg_is_little_endian(), val); + else + return __cpu_to_rpmsg32(rpdev->little_endian, val); +} + +static inline u64 rpmsg64_to_cpu(struct rpmsg_device *rpdev, __rpmsg64 val) +{ + if (!rpdev) + return __rpmsg64_to_cpu(rpmsg_is_little_endian(), val); + else + return __rpmsg64_to_cpu(rpdev->little_endian, val); +} + +static inline __rpmsg64 cpu_to_rpmsg64(struct rpmsg_device *rpdev, u64 val) +{ + if (!rpdev) + return __cpu_to_rpmsg64(rpmsg_is_little_endian(), val); + else + return __cpu_to_rpmsg64(rpdev->little_endian, val); +} + #if IS_ENABLED(CONFIG_RPMSG) -int register_rpmsg_device(struct rpmsg_device *dev); -void unregister_rpmsg_device(struct rpmsg_device *dev); +int rpmsg_register_device_override(struct rpmsg_device *rpdev, + const char *driver_override); +int rpmsg_register_device(struct rpmsg_device *rpdev); +int rpmsg_unregister_device(struct device *parent, + struct rpmsg_channel_info *chinfo); 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 *); @@ -124,28 +184,37 @@ struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *, 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); +ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept); + +int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u32 dst); + #else -static inline int register_rpmsg_device(struct rpmsg_device *dev) +static inline int rpmsg_register_device_override(struct rpmsg_device *rpdev, + const char *driver_override) { return -ENXIO; } -static inline void unregister_rpmsg_device(struct rpmsg_device *dev) +static inline int rpmsg_register_device(struct rpmsg_device *rpdev) +{ + return -ENXIO; +} + +static inline int rpmsg_unregister_device(struct device *parent, + struct rpmsg_channel_info *chinfo) { /* This shouldn't be possible */ WARN_ON(1); + + return -ENXIO; } static inline int __register_rpmsg_driver(struct rpmsg_driver *drv, @@ -177,7 +246,7 @@ static inline struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev /* This shouldn't be possible */ WARN_ON(1); - return ERR_PTR(-ENXIO); + return NULL; } static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) @@ -198,8 +267,7 @@ static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, } -static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, - u32 dst, void *data, int len) +static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) { /* This shouldn't be possible */ WARN_ON(1); @@ -207,7 +275,8 @@ static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, return -ENXIO; } -static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) +static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, + int len, u32 dst) { /* This shouldn't be possible */ WARN_ON(1); @@ -215,17 +284,16 @@ static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) return -ENXIO; } -static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, - int len, u32 dst) +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 -ENXIO; + return 0; } -static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, - u32 dst, void *data, int len) +static inline ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept) { /* This shouldn't be possible */ WARN_ON(1); @@ -233,13 +301,12 @@ static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, return -ENXIO; } -static inline __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, - struct file *filp, poll_table *wait) +static inline int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u32 dst) { /* This shouldn't be possible */ WARN_ON(1); - return 0; + return -ENXIO; } #endif /* IS_ENABLED(CONFIG_RPMSG) */ |