diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-22 21:58:21 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-22 21:58:21 +0200 |
commit | 60573c2966a1b560fabdffe308d47b6ba5585b15 (patch) | |
tree | f55bbcb787f86c1f19e784c48eba88c57d55512e /drivers/rpmsg/qcom_glink_native.c | |
parent | Merge tag 'rproc-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ande... (diff) | |
parent | rpmsg: glink: Expose rpmsg name attr for glink (diff) | |
download | linux-60573c2966a1b560fabdffe308d47b6ba5585b15.tar.xz linux-60573c2966a1b560fabdffe308d47b6ba5585b15.zip |
Merge tag 'rpmsg-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc
Pull rpmsg updates from Bjorn Andersson:
"This introduces rpmsg_char support for GLINK and fixes a few issues"
* tag 'rpmsg-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc:
rpmsg: glink: Expose rpmsg name attr for glink
rpmsg: glink: Add support for rpmsg glink chrdev
rpmsg: Guard against null endpoint ops in destroy
rpmsg: glink: Use complete_all for open states
rpmsg: virtio: fix compilation warning for virtio_rpmsg_channel description
rpmsg: Avoid double-free in mtk_rpmsg_register_device
rpmsg: smd: Fix a kobj leak in in qcom_smd_parse_edge()
Diffstat (limited to 'drivers/rpmsg/qcom_glink_native.c')
-rw-r--r-- | drivers/rpmsg/qcom_glink_native.c | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index f40312b16da0..27a05167c18c 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -970,7 +970,7 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) return -EINVAL; } - complete(&channel->open_ack); + complete_all(&channel->open_ack); return 0; } @@ -1178,7 +1178,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); @@ -1413,7 +1413,7 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, channel->rcid = ret; spin_unlock_irqrestore(&glink->idr_lock, flags); - complete(&channel->open_req); + complete_all(&channel->open_req); if (create_device) { rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); @@ -1574,6 +1574,60 @@ static void qcom_glink_cancel_rx_work(struct qcom_glink *glink) kfree(dcmd); } +static ssize_t rpmsg_name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + const char *name; + + ret = of_property_read_string(dev->of_node, "label", &name); + if (ret < 0) + name = dev->of_node->name; + + return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", name); +} +static DEVICE_ATTR_RO(rpmsg_name); + +static struct attribute *qcom_glink_attrs[] = { + &dev_attr_rpmsg_name.attr, + NULL +}; +ATTRIBUTE_GROUPS(qcom_glink); + +static void qcom_glink_device_release(struct device *dev) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + struct glink_channel *channel = to_glink_channel(rpdev->ept); + + /* 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 rpmsg_device *rpdev; + struct glink_channel *channel; + + rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); + if (!rpdev) + return -ENOMEM; + + 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(rpdev); +} + struct qcom_glink *qcom_glink_native_probe(struct device *dev, unsigned long features, struct qcom_glink_pipe *rx, @@ -1604,6 +1658,12 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, idr_init(&glink->lcids); idr_init(&glink->rcids); + glink->dev->groups = qcom_glink_groups; + + ret = device_add_groups(dev, qcom_glink_groups); + if (ret) + dev_err(dev, "failed to add groups\n"); + ret = of_property_read_string(dev->of_node, "label", &glink->name); if (ret < 0) glink->name = dev->of_node->name; @@ -1633,6 +1693,10 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, if (ret) return ERR_PTR(ret); + ret = qcom_glink_create_chrdev(glink); + if (ret) + dev_err(glink->dev, "failed to register chrdev\n"); + return glink; } EXPORT_SYMBOL_GPL(qcom_glink_native_probe); |