rpmsg updates for v4.13
This introduces the Qualcomm GLINK protocol driver and DeviceTree-based modalias support, as well as a number of smaller fixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZXXVMAAoJEAsfOT8Nma3FQQgP/3J8RiSyURi5EUKs59LBHQ6Z hpQgsxa0idTY4AbS6phUiBMxyxSSJltGn/8hjlddixp/iiaqSv3z+d5zHRiyOsHt TiOYkE5z8HvG/i/fA9+ZFCeTakqeq9qWhyYEJ0r1j49le4iWRPwQ0NGHxNhyTZJZ dTPIC4C5FJPl5LEyeU5ZTzLTtPWZKu2+Ll5xB8vZz6qmU2aQMdX4XL30sbgdXB9y Xg04AYTYrphoTLT7y7wKJ3/acZyJDZp+6kfr1mMvZttZiGZJLbaAN3+jlLvAqO25 NMZzTsBW6sCfWhh/v/IP7AVIYde6yzTfvcj7z9Z0RFb/QdFA691Y6dxLbJtSmVGR FRCq739NKmvbe3l3xWdMSXOcSMZng534u/Ws/p6orUNzCrBHAcc0f9Qz5URIXo8R tw5/IZwUurBDlAIJeBJM/AKWj75C7Wxuy1SUcG7ks3NyKejCM2Pl+Y2gwWOSXvJj 0slS1EnUmiypT5dR4IJXYni34eP0yfXtwfxHuUPZvcaLCpdbSMRULAubGpgcOOT0 d/lFv29UDudh7vxEqV2tEcEk5NVvcAuwsGytZddxFOGU1tCsrLa/BMBiiA3aKn5S sS5puLXPwl3ndwQV8Kr+48LjepQ44UoVvlh9edZUKVcaeDUDRM7WOvPyVUE9Rc+C UMPkHyvD/sYPaDRhXyTD =rhfx -----END PGP SIGNATURE----- Merge tag 'rpmsg-v4.13' of git://github.com/andersson/remoteproc Pull rpmsg updates from Bjorn Andersson: "This introduces the Qualcomm GLINK protocol driver and DeviceTree-based modalias support, as well as a number of smaller fixes" * tag 'rpmsg-v4.13' of git://github.com/andersson/remoteproc: rpmsg: Make modalias work for DeviceTree based devices rpmsg: Drop VIRTUALIZATION dependency from RPMSG_VIRTIO rpmsg: Don't overwrite release op of rpdev rpmsg: virtio_rpmsg_bus: cleanup multiple assignment to ops rpmsg: virtio_rpmsg_bus: fix nameservice address rpmsg: cleanup incorrect function in dev_err message rpmsg: virtio_rpmsg_bus: fix announce for devices without endpoint rpmsg: Introduce Qualcomm RPM glink driver soc: qcom: Add device tree binding for GLINK RPM rpmsg: Release rpmsg devices in backends
This commit is contained in:
commit
426b8eeb05
73
Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt
Normal file
73
Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt
Normal file
|
@ -0,0 +1,73 @@
|
|||
Qualcomm RPM GLINK binding
|
||||
|
||||
This binding describes the Qualcomm RPM GLINK, a fifo based mechanism for
|
||||
communication with the Resource Power Management system on various Qualcomm
|
||||
platforms.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,glink-rpm"
|
||||
|
||||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the IRQ used by the remote processor to
|
||||
signal this processor about communication related events
|
||||
|
||||
- qcom,rpm-msg-ram:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: handle to RPM message memory resource
|
||||
|
||||
- mboxes:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: reference to the "rpm_hlos" mailbox in APCS, as described
|
||||
in mailbox/mailbox.txt
|
||||
|
||||
= GLINK DEVICES
|
||||
Each subnode of the GLINK node represent function tied to a virtual
|
||||
communication channel. The name of the nodes are not important. The properties
|
||||
of these nodes are defined by the individual bindings for the specific function
|
||||
- but must contain the following property:
|
||||
|
||||
- qcom,glink-channels:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: a list of channels tied to this function, used for matching
|
||||
the function to a set of virtual channels
|
||||
|
||||
= EXAMPLE
|
||||
The following example represents the GLINK RPM node on a MSM8996 device, with
|
||||
the function for the "rpm_request" channel defined, which is used for
|
||||
regualtors and root clocks.
|
||||
|
||||
apcs_glb: mailbox@9820000 {
|
||||
compatible = "qcom,msm8996-apcs-hmss-global";
|
||||
reg = <0x9820000 0x1000>;
|
||||
|
||||
#mbox-cells = <1>;
|
||||
};
|
||||
|
||||
rpm_msg_ram: memory@68000 {
|
||||
compatible = "qcom,rpm-msg-ram";
|
||||
reg = <0x68000 0x6000>;
|
||||
};
|
||||
|
||||
rpm-glink {
|
||||
compatible = "qcom,glink-rpm";
|
||||
|
||||
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
|
||||
|
||||
qcom,rpm-msg-ram = <&rpm_msg_ram>;
|
||||
|
||||
mboxes = <&apcs_glb 0>;
|
||||
|
||||
rpm-requests {
|
||||
compatible = "qcom,rpm-msm8996";
|
||||
qcom,glink-channels = "rpm_requests";
|
||||
|
||||
...
|
||||
};
|
||||
};
|
|
@ -13,6 +13,16 @@ config RPMSG_CHAR
|
|||
in /dev. They make it possible for user-space programs to send and
|
||||
receive rpmsg packets.
|
||||
|
||||
config RPMSG_QCOM_GLINK_RPM
|
||||
tristate "Qualcomm RPM Glink driver"
|
||||
select RPMSG
|
||||
depends on HAS_IOMEM
|
||||
depends on MAILBOX
|
||||
help
|
||||
Say y here to enable support for the GLINK RPM communication driver,
|
||||
which serves as a channel for communication with the RPM in GLINK
|
||||
enabled systems.
|
||||
|
||||
config RPMSG_QCOM_SMD
|
||||
tristate "Qualcomm Shared Memory Driver (SMD)"
|
||||
depends on QCOM_SMEM
|
||||
|
@ -26,6 +36,5 @@ config RPMSG_VIRTIO
|
|||
tristate
|
||||
select RPMSG
|
||||
select VIRTIO
|
||||
select VIRTUALIZATION
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
obj-$(CONFIG_RPMSG) += rpmsg_core.o
|
||||
obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
|
||||
obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
|
||||
obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o
|
||||
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
|
||||
|
|
1233
drivers/rpmsg/qcom_glink_rpm.c
Normal file
1233
drivers/rpmsg/qcom_glink_rpm.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -969,6 +969,14 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
|
|||
.poll = qcom_smd_poll,
|
||||
};
|
||||
|
||||
static void qcom_smd_release_device(struct device *dev)
|
||||
{
|
||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
||||
struct qcom_smd_device *qsdev = to_smd_device(rpdev);
|
||||
|
||||
kfree(qsdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a smd client device for channel that is being opened.
|
||||
*/
|
||||
|
@ -998,6 +1006,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel)
|
|||
|
||||
rpdev->dev.of_node = qcom_smd_match_channel(edge->of_node, channel->name);
|
||||
rpdev->dev.parent = &edge->dev;
|
||||
rpdev->dev.release = qcom_smd_release_device;
|
||||
|
||||
return rpmsg_register_device(rpdev);
|
||||
}
|
||||
|
@ -1013,6 +1022,8 @@ static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge)
|
|||
qsdev->edge = edge;
|
||||
qsdev->rpdev.ops = &qcom_smd_device_ops;
|
||||
qsdev->rpdev.dev.parent = &edge->dev;
|
||||
qsdev->rpdev.dev.release = qcom_smd_release_device;
|
||||
|
||||
return rpmsg_chrdev_register_device(&qsdev->rpdev);
|
||||
}
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ static int rpmsg_eptdev_create(struct rpmsg_ctrldev *ctrldev,
|
|||
|
||||
ret = device_add(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "device_register failed: %d\n", ret);
|
||||
dev_err(dev, "device_add failed: %d\n", ret);
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
|
@ -505,7 +505,7 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
|
|||
|
||||
ret = device_add(dev);
|
||||
if (ret) {
|
||||
dev_err(&rpdev->dev, "device_register failed: %d\n", ret);
|
||||
dev_err(&rpdev->dev, "device_add failed: %d\n", ret);
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -343,6 +343,11 @@ static ssize_t modalias_show(struct device *dev,
|
|||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
||||
ssize_t len;
|
||||
|
||||
len = of_device_modalias(dev, buf, PAGE_SIZE);
|
||||
if (len != -ENODEV)
|
||||
return len;
|
||||
|
||||
return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
|
||||
}
|
||||
|
@ -387,6 +392,11 @@ static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
|
|||
static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
||||
int ret;
|
||||
|
||||
ret = of_device_uevent_modalias(dev, env);
|
||||
if (ret != -ENODEV)
|
||||
return ret;
|
||||
|
||||
return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
|
||||
rpdev->id.name);
|
||||
|
@ -464,13 +474,6 @@ static struct bus_type rpmsg_bus = {
|
|||
.remove = rpmsg_dev_remove,
|
||||
};
|
||||
|
||||
static void rpmsg_release_device(struct device *dev)
|
||||
{
|
||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
||||
|
||||
kfree(rpdev);
|
||||
}
|
||||
|
||||
int rpmsg_register_device(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct device *dev = &rpdev->dev;
|
||||
|
@ -480,7 +483,6 @@ int rpmsg_register_device(struct rpmsg_device *rpdev)
|
|||
rpdev->id.name, rpdev->src, rpdev->dst);
|
||||
|
||||
rpdev->dev.bus = &rpmsg_bus;
|
||||
rpdev->dev.release = rpmsg_release_device;
|
||||
|
||||
ret = device_register(&rpdev->dev);
|
||||
if (ret) {
|
||||
|
|
|
@ -314,7 +314,7 @@ static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev)
|
|||
int err = 0;
|
||||
|
||||
/* need to tell remote processor's name service about this channel ? */
|
||||
if (rpdev->announce &&
|
||||
if (rpdev->announce && rpdev->ept &&
|
||||
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
|
||||
struct rpmsg_ns_msg nsm;
|
||||
|
||||
|
@ -338,12 +338,12 @@ static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev)
|
|||
int err = 0;
|
||||
|
||||
/* tell remote processor's name service we're removing this channel */
|
||||
if (rpdev->announce &&
|
||||
if (rpdev->announce && rpdev->ept &&
|
||||
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
|
||||
struct rpmsg_ns_msg nsm;
|
||||
|
||||
strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
|
||||
nsm.addr = rpdev->src;
|
||||
nsm.addr = rpdev->ept->addr;
|
||||
nsm.flags = RPMSG_NS_DESTROY;
|
||||
|
||||
err = rpmsg_sendto(rpdev->ept, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
|
||||
|
@ -360,6 +360,14 @@ static const struct rpmsg_device_ops virtio_rpmsg_ops = {
|
|||
.announce_destroy = virtio_rpmsg_announce_destroy,
|
||||
};
|
||||
|
||||
static void virtio_rpmsg_release_device(struct device *dev)
|
||||
{
|
||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
||||
struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
|
||||
|
||||
kfree(vch);
|
||||
}
|
||||
|
||||
/*
|
||||
* create an rpmsg channel using its name and address info.
|
||||
* this function will be used to create both static and dynamic
|
||||
|
@ -390,9 +398,6 @@ static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp,
|
|||
/* Link the channel to our vrp */
|
||||
vch->vrp = vrp;
|
||||
|
||||
/* Assign callbacks for rpmsg_channel */
|
||||
vch->rpdev.ops = &virtio_rpmsg_ops;
|
||||
|
||||
/* Assign public information to the rpmsg_device */
|
||||
rpdev = &vch->rpdev;
|
||||
rpdev->src = chinfo->src;
|
||||
|
@ -408,6 +413,7 @@ static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp,
|
|||
strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
|
||||
|
||||
rpdev->dev.parent = &vrp->vdev->dev;
|
||||
rpdev->dev.release = virtio_rpmsg_release_device;
|
||||
ret = rpmsg_register_device(rpdev);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue
Block a user