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

Commit 39e47767 authored by Anup Patel's avatar Anup Patel Committed by Bjorn Andersson
Browse files

rpmsg: Add driver_override device attribute for rpmsg_device



This patch adds "driver_override" device attribute for rpmsg_device which
will allow users to explicitly specify the rpmsg_driver to be used via
sysfs entry.

The "driver_override" device attribute implemented here is very similar
to "driver_override" implemented for platform, pci, and amba bus types.

One important use-case of "driver_override" device attribute is to force
use of rpmsg_chrdev driver for certain rpmsg_device instances.

Signed-off-by: default avatarAnup Patel <anup@brainfault.org>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 60cc43fc
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -73,3 +73,23 @@ Description:
		This sysfs entry tells us whether the channel is a local
		server channel that is announced (values are either
		true or false).

What:		/sys/bus/rpmsg/devices/.../driver_override
Date:		April 2018
KernelVersion:	4.18
Contact:	Bjorn Andersson <bjorn.andersson@linaro.org>
Description:
		Every rpmsg device is a communication channel with a remote
		processor. Channels are identified by a textual name (see
		/sys/bus/rpmsg/devices/.../name above) and have a local
		("source") rpmsg address, and remote ("destination") rpmsg
		address.

		The listening entity (or client) which communicates with a
		remote processor is referred as rpmsg driver. The rpmsg device
		and rpmsg driver are matched based on rpmsg device name and
		rpmsg driver ID table.

		This sysfs entry allows the rpmsg driver for a rpmsg device
		to be specified which will override standard OF, ID table
		and name matching.
+39 −0
Original line number Diff line number Diff line
@@ -333,11 +333,49 @@ field##_show(struct device *dev, \
}									\
static DEVICE_ATTR_RO(field);

#define rpmsg_string_attr(field, member)				\
static ssize_t								\
field##_store(struct device *dev, struct device_attribute *attr,	\
	      const char *buf, size_t sz)				\
{									\
	struct rpmsg_device *rpdev = to_rpmsg_device(dev);		\
	char *new, *old;						\
									\
	new = kstrndup(buf, sz, GFP_KERNEL);				\
	if (!new)							\
		return -ENOMEM;						\
	new[strcspn(new, "\n")] = '\0';					\
									\
	device_lock(dev);						\
	old = rpdev->member;						\
	if (strlen(new)) {						\
		rpdev->member = new;					\
	} else {							\
		kfree(new);						\
		rpdev->member = NULL;					\
	}								\
	device_unlock(dev);						\
									\
	kfree(old);							\
									\
	return sz;							\
}									\
static ssize_t								\
field##_show(struct device *dev,					\
	     struct device_attribute *attr, char *buf)			\
{									\
	struct rpmsg_device *rpdev = to_rpmsg_device(dev);		\
									\
	return sprintf(buf, "%s\n", rpdev->member);			\
}									\
static DEVICE_ATTR_RW(field)

/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
rpmsg_show_attr(name, id.name, "%s\n");
rpmsg_show_attr(src, src, "0x%x\n");
rpmsg_show_attr(dst, dst, "0x%x\n");
rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
rpmsg_string_attr(driver_override, driver_override);

static ssize_t modalias_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
@@ -359,6 +397,7 @@ static struct attribute *rpmsg_dev_attrs[] = {
	&dev_attr_dst.attr,
	&dev_attr_src.attr,
	&dev_attr_announce.attr,
	&dev_attr_driver_override.attr,
	NULL,
};
ATTRIBUTE_GROUPS(rpmsg_dev);