diff options
author | Anup Patel <anup@brainfault.org> | 2018-03-23 21:41:17 +0530 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2018-04-25 16:59:53 -0700 |
commit | 39e47767ec9b22f844c2a07c9d329256960d4021 (patch) | |
tree | d34066f379c86a35f0a249af39046c784b6a850d /drivers/rpmsg | |
parent | 60cc43fc888428bb2f18f08997432d426a243338 (diff) |
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: Anup Patel <anup@brainfault.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/rpmsg_core.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 920a02f0462c..bea7c74e12eb 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -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); |