| .. | .. |
|---|
| 553 | 553 | break; |
|---|
| 554 | 554 | case GLINK_VERSION_1: |
|---|
| 555 | 555 | glink->features &= features; |
|---|
| 556 | | - /* FALLTHROUGH */ |
|---|
| 556 | + fallthrough; |
|---|
| 557 | 557 | default: |
|---|
| 558 | 558 | qcom_glink_send_version_ack(glink); |
|---|
| 559 | 559 | break; |
|---|
| .. | .. |
|---|
| 584 | 584 | break; |
|---|
| 585 | 585 | |
|---|
| 586 | 586 | glink->features &= features; |
|---|
| 587 | | - /* FALLTHROUGH */ |
|---|
| 587 | + fallthrough; |
|---|
| 588 | 588 | default: |
|---|
| 589 | 589 | qcom_glink_send_version(glink); |
|---|
| 590 | 590 | break; |
|---|
| .. | .. |
|---|
| 914 | 914 | struct intent_pair intents[]; |
|---|
| 915 | 915 | } __packed * msg; |
|---|
| 916 | 916 | |
|---|
| 917 | | - const size_t msglen = sizeof(*msg) + sizeof(struct intent_pair) * count; |
|---|
| 917 | + const size_t msglen = struct_size(msg, intents, count); |
|---|
| 918 | 918 | int ret; |
|---|
| 919 | 919 | int i; |
|---|
| 920 | 920 | unsigned long flags; |
|---|
| .. | .. |
|---|
| 1472 | 1472 | cancel_work_sync(&channel->intent_work); |
|---|
| 1473 | 1473 | |
|---|
| 1474 | 1474 | if (channel->rpdev) { |
|---|
| 1475 | | - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); |
|---|
| 1475 | + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); |
|---|
| 1476 | 1476 | chinfo.src = RPMSG_ADDR_ANY; |
|---|
| 1477 | 1477 | chinfo.dst = RPMSG_ADDR_ANY; |
|---|
| 1478 | 1478 | |
|---|
| .. | .. |
|---|
| 1575 | 1575 | kfree(dcmd); |
|---|
| 1576 | 1576 | } |
|---|
| 1577 | 1577 | |
|---|
| 1578 | +static ssize_t rpmsg_name_show(struct device *dev, |
|---|
| 1579 | + struct device_attribute *attr, char *buf) |
|---|
| 1580 | +{ |
|---|
| 1581 | + int ret = 0; |
|---|
| 1582 | + const char *name; |
|---|
| 1583 | + |
|---|
| 1584 | + ret = of_property_read_string(dev->of_node, "label", &name); |
|---|
| 1585 | + if (ret < 0) |
|---|
| 1586 | + name = dev->of_node->name; |
|---|
| 1587 | + |
|---|
| 1588 | + return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", name); |
|---|
| 1589 | +} |
|---|
| 1590 | +static DEVICE_ATTR_RO(rpmsg_name); |
|---|
| 1591 | + |
|---|
| 1592 | +static struct attribute *qcom_glink_attrs[] = { |
|---|
| 1593 | + &dev_attr_rpmsg_name.attr, |
|---|
| 1594 | + NULL |
|---|
| 1595 | +}; |
|---|
| 1596 | +ATTRIBUTE_GROUPS(qcom_glink); |
|---|
| 1597 | + |
|---|
| 1598 | +static void qcom_glink_device_release(struct device *dev) |
|---|
| 1599 | +{ |
|---|
| 1600 | + struct rpmsg_device *rpdev = to_rpmsg_device(dev); |
|---|
| 1601 | + struct glink_channel *channel = to_glink_channel(rpdev->ept); |
|---|
| 1602 | + |
|---|
| 1603 | + /* Release qcom_glink_alloc_channel() reference */ |
|---|
| 1604 | + kref_put(&channel->refcount, qcom_glink_channel_release); |
|---|
| 1605 | + kfree(rpdev); |
|---|
| 1606 | +} |
|---|
| 1607 | + |
|---|
| 1608 | +static int qcom_glink_create_chrdev(struct qcom_glink *glink) |
|---|
| 1609 | +{ |
|---|
| 1610 | + struct rpmsg_device *rpdev; |
|---|
| 1611 | + struct glink_channel *channel; |
|---|
| 1612 | + |
|---|
| 1613 | + rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); |
|---|
| 1614 | + if (!rpdev) |
|---|
| 1615 | + return -ENOMEM; |
|---|
| 1616 | + |
|---|
| 1617 | + channel = qcom_glink_alloc_channel(glink, "rpmsg_chrdev"); |
|---|
| 1618 | + if (IS_ERR(channel)) { |
|---|
| 1619 | + kfree(rpdev); |
|---|
| 1620 | + return PTR_ERR(channel); |
|---|
| 1621 | + } |
|---|
| 1622 | + channel->rpdev = rpdev; |
|---|
| 1623 | + |
|---|
| 1624 | + rpdev->ept = &channel->ept; |
|---|
| 1625 | + rpdev->ops = &glink_device_ops; |
|---|
| 1626 | + rpdev->dev.parent = glink->dev; |
|---|
| 1627 | + rpdev->dev.release = qcom_glink_device_release; |
|---|
| 1628 | + |
|---|
| 1629 | + return rpmsg_chrdev_register_device(rpdev); |
|---|
| 1630 | +} |
|---|
| 1631 | + |
|---|
| 1578 | 1632 | struct qcom_glink *qcom_glink_native_probe(struct device *dev, |
|---|
| 1579 | 1633 | unsigned long features, |
|---|
| 1580 | 1634 | struct qcom_glink_pipe *rx, |
|---|
| .. | .. |
|---|
| 1605 | 1659 | idr_init(&glink->lcids); |
|---|
| 1606 | 1660 | idr_init(&glink->rcids); |
|---|
| 1607 | 1661 | |
|---|
| 1662 | + glink->dev->groups = qcom_glink_groups; |
|---|
| 1663 | + |
|---|
| 1664 | + ret = device_add_groups(dev, qcom_glink_groups); |
|---|
| 1665 | + if (ret) |
|---|
| 1666 | + dev_err(dev, "failed to add groups\n"); |
|---|
| 1667 | + |
|---|
| 1608 | 1668 | ret = of_property_read_string(dev->of_node, "label", &glink->name); |
|---|
| 1609 | 1669 | if (ret < 0) |
|---|
| 1610 | 1670 | glink->name = dev->of_node->name; |
|---|
| .. | .. |
|---|
| 1634 | 1694 | if (ret) |
|---|
| 1635 | 1695 | return ERR_PTR(ret); |
|---|
| 1636 | 1696 | |
|---|
| 1697 | + ret = qcom_glink_create_chrdev(glink); |
|---|
| 1698 | + if (ret) |
|---|
| 1699 | + dev_err(glink->dev, "failed to register chrdev\n"); |
|---|
| 1700 | + |
|---|
| 1637 | 1701 | return glink; |
|---|
| 1638 | 1702 | } |
|---|
| 1639 | 1703 | EXPORT_SYMBOL_GPL(qcom_glink_native_probe); |
|---|