blob: 1f7ba091c50bb1184424d07f91f3afc2f11604c1 [file] [log] [blame] [edit]
/*
* Remote processor messaging
*
* Copyright(c) 2011 Texas Instruments. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Texas Instruments nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LINUX_RPMSG_H
#define _LINUX_RPMSG_H
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
/* The feature bitmap for virtio rpmsg */
#define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
/**
* struct rpmsg_hdr -
*
* ... keep documenting ...
*/
struct rpmsg_hdr {
u16 len;
u16 flags;
u32 src;
u32 dst;
u32 unused;
u8 data[0];
} __packed;
enum rpmsg_ns_flags {
RPMSG_NS_CREATE = 0,
RPMSG_NS_DESTROY = 1,
};
struct rpmsg_ns_msg {
char name[RPMSG_NAME_SIZE];
u32 addr;
u32 flags;
} __packed;
/* driver requests */
enum {
VPROC_BUF_ADDR,
VPROC_BUF_NUM,
VPROC_BUF_SZ,
VPROC_SIM_BASE,
VPROC_STATIC_CHANNELS,
};
#define RPMSG_ADDR_ANY 0xFFFFFFFF
struct virtproc_info;
/**
* rpmsg_channel - rpmsg channels are the devices of the rpmsg bus
*
* @vrp: the remote processor this channel connects to
* @dev: underlying device
* @id: the device type identification (used to match an rpmsg driver)
* @src: local address of this channel
* @dst: destination address of the remote service
* @priv: private pointer for the driver's use.
* @ept: local rpmsg endpoint of this channel
* @announce: need to tell remoteproc about channel creation/removal
*/
struct rpmsg_channel {
struct virtproc_info *vrp;
struct device dev;
struct rpmsg_device_id id;
u32 src;
u32 dst;
void *priv;
struct rpmsg_endpoint *ept;
bool announce;
};
struct rpmsg_channel_info {
char name[RPMSG_NAME_SIZE];
u32 src;
u32 dst;
};
/**
* struct rpmsg_endpoint
*
* @rpdev:
* @cb:
* @src: local rpmsg address
* @priv:
*/
struct rpmsg_endpoint {
struct rpmsg_channel *rpdev;
void (*cb)(struct rpmsg_channel *, void *, int, void *, u32);
u32 addr;
void *priv;
};
/**
* rpmsg_driver - operations for a rpmsg I/O driver
* @driver: underlying device driver (populate name and owner).
* @id_table: the ids serviced by this driver.
* @probe: the function to call when a device is found. Returns 0 or -errno.
* @remove: the function when a device is removed.
* @callback: invoked when a message is received on the channel
*/
struct rpmsg_driver {
struct device_driver drv;
const struct rpmsg_device_id *id_table;
int (*probe)(struct rpmsg_channel *dev);
void (*remove)(struct rpmsg_channel *dev);
void (*callback)(struct rpmsg_channel *, void *, int, void *, u32);
};
int register_rpmsg_device(struct rpmsg_channel *dev);
void unregister_rpmsg_device(struct rpmsg_channel *dev);
int register_rpmsg_driver(struct rpmsg_driver *drv);
void unregister_rpmsg_driver(struct rpmsg_driver *drv);
void rpmsg_destroy_ept(struct rpmsg_endpoint *);
struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *,
void (*cb)(struct rpmsg_channel *, void *, int, void *, u32),
void *priv, u32 addr);
int
rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool);
static inline
int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
void *data, int len)
{
return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
}
static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len)
{
return rpmsg_send_offchannel(rpdev, rpdev->src, rpdev->dst, data, len);
}
static inline
int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
{
return rpmsg_send_offchannel(rpdev, rpdev->src, dst, data, len);
}
static inline
int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
void *data, int len)
{
return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
}
static inline
int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len)
{
return rpmsg_trysend_offchannel(rpdev, rpdev->src, rpdev->dst,
data, len);
}
static inline
int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
{
return rpmsg_trysend_offchannel(rpdev, rpdev->src, dst, data, len);
}
#endif /* _LINUX_RPMSG_H */