Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ba4ba90 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes Ib5ce3e22,I0b09219c into msm-4.14

* changes:
  rpmsg: glink: Fix character device allocation
  rpmsg: glink: Add GLINK signal support for RPMSG
parents 3e21b231 9bcf1266
Loading
Loading
Loading
Loading
+102 −24
Original line number Diff line number Diff line
@@ -159,13 +159,6 @@ enum {
	GLINK_STATE_CLOSING,
};

struct qcom_glink_device {
	struct rpmsg_device rpdev;
	struct qcom_glink *glink;
};

#define to_glink_device(_x) container_of(_x, struct qcom_glink_device, rpdev)

/**
 * struct glink_channel - internal representation of a channel
 * @rpdev:	rpdev reference, only used for primary endpoints
@@ -214,6 +207,9 @@ struct glink_channel {
	int buf_offset;
	int buf_size;

	unsigned int lsigs;
	unsigned int rsigs;

	struct completion open_ack;
	struct completion open_req;

@@ -240,6 +236,7 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;
#define RPM_CMD_TX_DATA_CONT		12
#define RPM_CMD_READ_NOTIF		13
#define RPM_CMD_RX_DONE_W_REUSE		14
#define RPM_CMD_SIGNALS			15

#define GLINK_FEATURE_INTENTLESS	BIT(1)

@@ -1021,6 +1018,54 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
	return 0;
}

/**
 * qcom_glink_send_signals() - convert a signal  cmd to wire format and transmit
 * @glink:	The transport to transmit on.
 * @channel:	The glink channel
 * @sigs:	The signals to encode.
 *
 * Return: 0 on success or standard Linux error code.
 */
static int qcom_glink_send_signals(struct qcom_glink *glink,
				   struct glink_channel *channel,
				   u32 sigs)
{
	struct glink_msg msg;

	msg.cmd = cpu_to_le16(RPM_CMD_SIGNALS);
	msg.param1 = cpu_to_le16(channel->lcid);
	msg.param2 = cpu_to_le32(sigs);

	GLINK_INFO(glink->ilc, "sigs:%d\n", sigs);
	return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}

static int qcom_glink_handle_signals(struct qcom_glink *glink,
				     unsigned int rcid, unsigned int signals)
{
	struct glink_channel *channel;
	unsigned long flags;
	u32 old;

	spin_lock_irqsave(&glink->idr_lock, flags);
	channel = idr_find(&glink->rcids, rcid);
	spin_unlock_irqrestore(&glink->idr_lock, flags);
	if (!channel) {
		dev_err(glink->dev, "signal for non-existing channel\n");
		return -EINVAL;
	}

	old = channel->rsigs;
	channel->rsigs = signals;

	if (channel->ept.sig_cb)
		channel->ept.sig_cb(channel->ept.rpdev, old, channel->rsigs);

	CH_INFO(channel, "old:%d new:%d\n", old, channel->rsigs);

	return 0;
}

static irqreturn_t qcom_glink_native_intr(int irq, void *data)
{
	struct qcom_glink *glink = data;
@@ -1082,6 +1127,10 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
			qcom_glink_handle_intent_req_ack(glink, param1, param2);
			qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
			break;
		case RPM_CMD_SIGNALS:
			qcom_glink_handle_signals(glink, param1, param2);
			qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
			break;
		default:
			dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
			ret = -EINVAL;
@@ -1233,7 +1282,7 @@ static int qcom_glink_announce_create(struct rpmsg_device *rpdev)
	__be32 *val = defaults;
	int size;

	if (glink->intentless)
	if (glink->intentless || !completion_done(&channel->open_ack))
		return 0;

	prop = of_find_property(np, "qcom,intents", NULL);
@@ -1389,6 +1438,27 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
	return __qcom_glink_send(channel, data, len, false);
}

static int qcom_glink_get_sigs(struct rpmsg_endpoint *ept,
			       u32 *lsigs, u32 *rsigs)
{
	struct glink_channel *channel = to_glink_channel(ept);

	*lsigs = channel->lsigs;
	*rsigs = channel->rsigs;

	return 0;
}

static int qcom_glink_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
{
	struct glink_channel *channel = to_glink_channel(ept);
	struct qcom_glink *glink = channel->glink;

	channel->lsigs = sigs;

	return qcom_glink_send_signals(glink, channel, sigs);
}

/*
 * Finds the device_node for the glink child interested in this channel.
 */
@@ -1413,10 +1483,6 @@ static struct device_node *qcom_glink_match_channel(struct device_node *node,
	return NULL;
}

static const struct rpmsg_device_ops glink_chrdev_ops = {
	.create_ept = qcom_glink_create_ept,
};

static const struct rpmsg_device_ops glink_device_ops = {
	.create_ept = qcom_glink_create_ept,
	.announce_create = qcom_glink_announce_create,
@@ -1426,6 +1492,8 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
	.destroy_ept = qcom_glink_destroy_ept,
	.send = qcom_glink_send,
	.trysend = qcom_glink_trysend,
	.get_sigs = qcom_glink_get_sigs,
	.set_sigs = qcom_glink_set_sigs,
};

static void qcom_glink_rpdev_release(struct device *dev)
@@ -1635,9 +1703,9 @@ static ssize_t rpmsg_name_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
	struct qcom_glink_device *gdev = to_glink_device(rpdev);
	struct glink_channel *channel = to_glink_channel(rpdev->ept);

	return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", gdev->glink->name);
	return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", channel->glink->name);
}
static DEVICE_ATTR_RO(rpmsg_name);

@@ -1650,25 +1718,35 @@ ATTRIBUTE_GROUPS(qcom_glink);
static void qcom_glink_device_release(struct device *dev)
{
	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
	struct qcom_glink_device *gdev = to_glink_device(rpdev);
	struct glink_channel *channel = to_glink_channel(rpdev->ept);

	kfree(gdev);
	/* Release qcom_glink_alloc_channel() reference */
	kref_put(&channel->refcount, qcom_glink_channel_release);
	kfree(rpdev);
}

static int qcom_glink_create_chrdev(struct qcom_glink *glink)
{
	struct qcom_glink_device *gdev;
	struct rpmsg_device *rpdev;
	struct glink_channel *channel;

	gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
	if (!gdev)
	rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL);
	if (!rpdev)
		return -ENOMEM;

	gdev->glink = glink;
	gdev->rpdev.ops = &glink_chrdev_ops;
	gdev->rpdev.dev.parent = glink->dev;
	gdev->rpdev.dev.release = qcom_glink_device_release;
	channel = qcom_glink_alloc_channel(glink, "rpmsg_chrdev");
	if (IS_ERR(channel)) {
		kfree(rpdev);
		return PTR_ERR(channel);
	}
	channel->rpdev = rpdev;

	rpdev->ept = &channel->ept;
	rpdev->ops = &glink_device_ops;
	rpdev->dev.parent = glink->dev;
	rpdev->dev.release = qcom_glink_device_release;

	return rpmsg_chrdev_register_device(&gdev->rpdev);
	return rpmsg_chrdev_register_device(rpdev);
}

struct qcom_glink *qcom_glink_native_probe(struct device *dev,
+41 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * Ohad Ben-Cohen <ohad@wizery.com>
 * Brian Swetland <swetland@google.com>
@@ -290,6 +291,42 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
}
EXPORT_SYMBOL(rpmsg_trysend_offchannel);

/**
 * rpmsg_get_sigs() - get the signals for this endpoint
 * @ept:	the rpmsg endpoint
 * @sigs:	serial signals bitmask
 *
 * Returns 0 on success and an appropriate error value on failure.
 */
int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs)
{
	if (WARN_ON(!ept))
		return -EINVAL;
	if (!ept->ops->get_sigs)
		return -ENXIO;

	return ept->ops->get_sigs(ept, lsigs, rsigs);
}
EXPORT_SYMBOL(rpmsg_get_sigs);

/**
 * rpmsg_set_sigs() - set the remote signals for this endpoint
 * @ept:	the rpmsg endpoint
 * @sigs:	serial signals bitmask
 *
 * Returns 0 on success and an appropriate error value on failure.
 */
int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
{
	if (WARN_ON(!ept))
		return -EINVAL;
	if (!ept->ops->set_sigs)
		return -ENXIO;

	return ept->ops->set_sigs(ept, sigs);
}
EXPORT_SYMBOL(rpmsg_set_sigs);

/*
 * match an rpmsg channel with a channel info struct.
 * this is used to make sure we're not creating rpmsg devices for channels
@@ -432,6 +469,10 @@ static int rpmsg_dev_probe(struct device *dev)

		rpdev->ept = ept;
		rpdev->src = ept->addr;

		if (rpdrv->signals)
			ept->sig_cb = rpdrv->signals;

	}

	err = rpdrv->probe(rpdev);
+5 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * Ohad Ben-Cohen <ohad@wizery.com>
 * Brian Swetland <swetland@google.com>
@@ -54,6 +55,8 @@ struct rpmsg_device_ops {
 * @trysend:		see @rpmsg_trysend(), required
 * @trysendto:		see @rpmsg_trysendto(), optional
 * @trysend_offchannel:	see @rpmsg_trysend_offchannel(), optional
 * @get_sigs:		see @rpmsg_get_sigs(), optional
 * @set_sigs:		see @rpmsg_set_sigs(), optional
 *
 * Indirection table for the operations that a rpmsg backend should implement.
 * In addition to @destroy_ept, the backend must at least implement @send and
@@ -73,6 +76,8 @@ struct rpmsg_endpoint_ops {
			     void *data, int len);
	unsigned int (*poll)(struct rpmsg_endpoint *ept, struct file *filp,
			     poll_table *wait);
	int (*get_sigs)(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs);
	int (*set_sigs)(struct rpmsg_endpoint *ept, u32 sigs);
};

int rpmsg_register_device(struct rpmsg_device *rpdev);
+126 −8
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/termios.h>

/* Define IPC Logging Macros */
#define GLINK_PKT_IPC_LOG_PAGE_CNT 2
@@ -52,6 +53,38 @@ do { \
	ipc_log_string(glink_pkt_ilctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \
} while (0)

#define SMD_DTR_SIG BIT(31)
#define SMD_CTS_SIG BIT(30)
#define SMD_CD_SIG BIT(29)
#define SMD_RI_SIG BIT(28)

#define to_smd_signal(sigs) \
do { \
	sigs &= 0x0fff; \
	if (sigs & TIOCM_DTR) \
		sigs |= SMD_DTR_SIG; \
	if (sigs & TIOCM_RTS) \
		sigs |= SMD_CTS_SIG; \
	if (sigs & TIOCM_CD) \
		sigs |= SMD_CD_SIG; \
	if (sigs & TIOCM_RI) \
		sigs |= SMD_RI_SIG; \
} while (0)

#define from_smd_signal(sigs) \
do { \
	if (sigs & SMD_DTR_SIG) \
		sigs |= TIOCM_DSR; \
	if (sigs & SMD_CTS_SIG) \
		sigs |= TIOCM_CTS; \
	if (sigs & SMD_CD_SIG) \
		sigs |= TIOCM_CD; \
	if (sigs & SMD_RI_SIG) \
		sigs |= TIOCM_RI; \
	sigs &= 0x0fff; \
} while (0)


#define MODULE_NAME "glink_pkt"
static dev_t glink_pkt_major;
static struct class *glink_pkt_class;
@@ -71,6 +104,7 @@ static DEFINE_IDA(glink_pkt_minor_ida);
 * @queue_lock:	synchronization of @queue operations
 * @queue:	incoming message queue
 * @readq:	wait object for incoming queue
 * @sig_change:	flag to indicate serial signal change
 * @dev_name:	/dev/@dev_name for glink_pkt device
 * @ch_name:	glink channel to match to
 * @edge:	glink edge to match to
@@ -89,6 +123,7 @@ struct glink_pkt_device {
	spinlock_t queue_lock;
	struct sk_buff_head queue;
	wait_queue_head_t readq;
	int sig_change;

	const char *dev_name;
	const char *ch_name;
@@ -156,6 +191,7 @@ static int glink_pkt_rpdev_cb(struct rpmsg_device *rpdev, void *buf, int len,
			      void *priv, u32 addr)
{
	struct glink_pkt_device *gpdev = priv;
	unsigned long flags;
	struct sk_buff *skb;

	skb = alloc_skb(len, GFP_ATOMIC);
@@ -164,9 +200,26 @@ static int glink_pkt_rpdev_cb(struct rpmsg_device *rpdev, void *buf, int len,

	skb_put_data(skb, buf, len);

	spin_lock(&gpdev->queue_lock);
	spin_lock_irqsave(&gpdev->queue_lock, flags);
	skb_queue_tail(&gpdev->queue, skb);
	spin_unlock(&gpdev->queue_lock);
	spin_unlock_irqrestore(&gpdev->queue_lock, flags);

	/* wake up any blocking processes, waiting for new data */
	wake_up_interruptible(&gpdev->readq);

	return 0;
}

static int glink_pkt_rpdev_sigs(struct rpmsg_device *rpdev, u32 old, u32 new)
{
	struct device_driver *drv = rpdev->dev.driver;
	struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
	struct glink_pkt_device *gpdev = rpdrv_to_gpdev(rpdrv);
	unsigned long flags;

	spin_lock_irqsave(&gpdev->queue_lock, flags);
	gpdev->sig_change = true;
	spin_unlock_irqrestore(&gpdev->queue_lock, flags);

	/* wake up any blocking processes, waiting for new data */
	wake_up_interruptible(&gpdev->readq);
@@ -243,13 +296,14 @@ int glink_pkt_release(struct inode *inode, struct file *file)
	struct glink_pkt_device *gpdev = cdev_to_gpdev(inode->i_cdev);
	struct device *dev = &gpdev->dev;
	struct sk_buff *skb;
	unsigned long flags;

	GLINK_PKT_INFO("for %s by %s:%ld ref_cnt[%d]\n",
		       gpdev->ch_name, current->comm,
		       task_pid_nr(current), refcount_read(&gpdev->refcount));

	if (refcount_dec_and_test(&gpdev->refcount)) {
		spin_lock(&gpdev->queue_lock);
		spin_lock_irqsave(&gpdev->queue_lock, flags);

		/* Discard all SKBs */
		while (!skb_queue_empty(&gpdev->queue)) {
@@ -257,7 +311,8 @@ int glink_pkt_release(struct inode *inode, struct file *file)
			kfree_skb(skb);
		}
		wake_up_interruptible(&gpdev->readq);
		spin_unlock(&gpdev->queue_lock);
		gpdev->sig_change = false;
		spin_unlock_irqrestore(&gpdev->queue_lock, flags);
	}

	put_device(dev);
@@ -404,6 +459,7 @@ static unsigned int glink_pkt_poll(struct file *file, poll_table *wait)
{
	struct glink_pkt_device *gpdev = file->private_data;
	unsigned int mask = 0;
	unsigned long flags;

	gpdev = file->private_data;
	if (!gpdev || !refcount_read(&gpdev->refcount)) {
@@ -425,10 +481,13 @@ static unsigned int glink_pkt_poll(struct file *file, poll_table *wait)
		return POLLHUP;
	}

	spin_lock(&gpdev->queue_lock);
	spin_lock_irqsave(&gpdev->queue_lock, flags);
	if (!skb_queue_empty(&gpdev->queue))
		mask |= POLLIN | POLLRDNORM;
	spin_unlock(&gpdev->queue_lock);

	if (gpdev->sig_change)
		mask |= POLLPRI;
	spin_unlock_irqrestore(&gpdev->queue_lock, flags);

	mask |= rpmsg_poll(gpdev->rpdev->ept, file, wait);

@@ -437,6 +496,47 @@ static unsigned int glink_pkt_poll(struct file *file, poll_table *wait)
	return mask;
}

/**
 * glink_pkt_tiocmset() - set the signals for glink_pkt device
 * devp:	Pointer to the glink_pkt device structure.
 * cmd:		IOCTL command.
 * arg:		Arguments to the ioctl call.
 *
 * This function is used to set the signals on the glink pkt device
 * when userspace client do a ioctl() system call with TIOCMBIS,
 * TIOCMBIC and TICOMSET.
 */
static int glink_pkt_tiocmset(struct glink_pkt_device *gpdev, unsigned int cmd,
			      unsigned long arg)
{
	u32 lsigs, rsigs, val;
	int ret;

	ret = get_user(val, (u32 *)arg);
	if (ret)
		return ret;

	to_smd_signal(val);
	ret = rpmsg_get_sigs(gpdev->rpdev->ept, &lsigs, &rsigs);
	if (ret < 0) {
		GLINK_PKT_ERR("%s: Get signals failed[%d]\n", __func__, ret);
		return ret;
	}
	switch (cmd) {
	case TIOCMBIS:
		lsigs |= val;
		break;
	case TIOCMBIC:
		lsigs &= ~val;
		break;
	case TIOCMSET:
		lsigs = val;
		break;
	}
	ret = rpmsg_set_sigs(gpdev->rpdev->ept, lsigs);
	GLINK_PKT_INFO("sigs[0x%x] ret[%d]\n", lsigs, ret);
	return ret;
}

/**
 * glink_pkt_ioctl() - ioctl() syscall for the glink_pkt device
@@ -452,6 +552,8 @@ static long glink_pkt_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{
	struct glink_pkt_device *gpdev;
	unsigned long flags;
	u32 lsigs, rsigs;
	int ret;

	gpdev = file->private_data;
@@ -469,9 +571,23 @@ static long glink_pkt_ioctl(struct file *file, unsigned int cmd,
	}

	switch (cmd) {
	case TIOCMGET:
		spin_lock_irqsave(&gpdev->queue_lock, flags);
		gpdev->sig_change = false;
		spin_unlock_irqrestore(&gpdev->queue_lock, flags);

		ret = rpmsg_get_sigs(gpdev->rpdev->ept, &lsigs, &rsigs);
		from_smd_signal(rsigs);
		if (!ret)
			ret = put_user(rsigs, (uint32_t *)arg);
		break;
	case TIOCMSET:
	case TIOCMBIS:
	case TIOCMBIC:
		ret = glink_pkt_tiocmset(gpdev, cmd, arg);
		break;
	/*
	 * Need to add support later for GLINK Signals and check with any client
	 * if they have any intent requirements.
	 * Need to add support later any intent requirements.
	 */
	default:
		GLINK_PKT_ERR("unrecognized ioctl command 0x%x\n", cmd);
@@ -578,6 +694,7 @@ static int glink_pkt_init_rpmsg(struct glink_pkt_device *gpdev)
	rpdrv->probe = glink_pkt_rpdev_probe;
	rpdrv->remove = glink_pkt_rpdev_remove;
	rpdrv->callback = glink_pkt_rpdev_cb;
	rpdrv->signals = glink_pkt_rpdev_sigs;
	rpdrv->id_table = match;
	rpdrv->drv.name = drv_name;

@@ -616,6 +733,7 @@ static int glink_pkt_create_device(struct device *parent,

	/* Default open timeout for open is 120 sec */
	gpdev->open_tout = 120;
	gpdev->sig_change = false;

	spin_lock_init(&gpdev->queue_lock);
	skb_queue_head_init(&gpdev->queue);
+26 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Copyright (C) 2011 Google, Inc.
 * All rights reserved.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -85,12 +86,14 @@ struct rpmsg_device {
};

typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32);
typedef int (*rpmsg_rx_sig_t)(struct rpmsg_device *, u32, 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
 * @sig_cb: rx serial signal handler
 * @cb_lock: must be taken before accessing/changing @cb
 * @addr: local rpmsg address
 * @priv: private data for the driver's use
@@ -113,6 +116,7 @@ struct rpmsg_endpoint {
	struct rpmsg_device *rpdev;
	struct kref refcount;
	rpmsg_rx_cb_t cb;
	rpmsg_rx_sig_t sig_cb;
	struct mutex cb_lock;
	u32 addr;
	void *priv;
@@ -127,6 +131,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
 * @signals: invoked when a serial signal change is received on the channel
 */
struct rpmsg_driver {
	struct device_driver drv;
@@ -134,6 +139,7 @@ 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 (*signals)(struct rpmsg_device *, u32, u32);
};

#if IS_ENABLED(CONFIG_RPMSG)
@@ -160,6 +166,9 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
unsigned int rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
			poll_table *wait);

int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs);
int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs);

#else

static inline int register_rpmsg_device(struct rpmsg_device *dev)
@@ -267,6 +276,23 @@ static inline unsigned int rpmsg_poll(struct rpmsg_endpoint *ept,
	return 0;
}

static inline int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs,
				 u32 *rsigs)
{
	/* This shouldn't be possible */
	WARN_ON(1);

	return -ENXIO;
}

static inline int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
{
	/* This shouldn't be possible */
	WARN_ON(1);

	return -ENXIO;
}

#endif /* IS_ENABLED(CONFIG_RPMSG) */

/* use a macro to avoid include chaining to get THIS_MODULE */