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:
Коммит
426b8eeb05
|
@ -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
|
in /dev. They make it possible for user-space programs to send and
|
||||||
receive rpmsg packets.
|
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
|
config RPMSG_QCOM_SMD
|
||||||
tristate "Qualcomm Shared Memory Driver (SMD)"
|
tristate "Qualcomm Shared Memory Driver (SMD)"
|
||||||
depends on QCOM_SMEM
|
depends on QCOM_SMEM
|
||||||
|
@ -26,6 +36,5 @@ config RPMSG_VIRTIO
|
||||||
tristate
|
tristate
|
||||||
select RPMSG
|
select RPMSG
|
||||||
select VIRTIO
|
select VIRTIO
|
||||||
select VIRTUALIZATION
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
obj-$(CONFIG_RPMSG) += rpmsg_core.o
|
obj-$(CONFIG_RPMSG) += rpmsg_core.o
|
||||||
obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.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_QCOM_SMD) += qcom_smd.o
|
||||||
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
|
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -969,6 +969,14 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
|
||||||
.poll = qcom_smd_poll,
|
.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.
|
* 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.of_node = qcom_smd_match_channel(edge->of_node, channel->name);
|
||||||
rpdev->dev.parent = &edge->dev;
|
rpdev->dev.parent = &edge->dev;
|
||||||
|
rpdev->dev.release = qcom_smd_release_device;
|
||||||
|
|
||||||
return rpmsg_register_device(rpdev);
|
return rpmsg_register_device(rpdev);
|
||||||
}
|
}
|
||||||
|
@ -1013,6 +1022,8 @@ static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge)
|
||||||
qsdev->edge = edge;
|
qsdev->edge = edge;
|
||||||
qsdev->rpdev.ops = &qcom_smd_device_ops;
|
qsdev->rpdev.ops = &qcom_smd_device_ops;
|
||||||
qsdev->rpdev.dev.parent = &edge->dev;
|
qsdev->rpdev.dev.parent = &edge->dev;
|
||||||
|
qsdev->rpdev.dev.release = qcom_smd_release_device;
|
||||||
|
|
||||||
return rpmsg_chrdev_register_device(&qsdev->rpdev);
|
return rpmsg_chrdev_register_device(&qsdev->rpdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@ static int rpmsg_eptdev_create(struct rpmsg_ctrldev *ctrldev,
|
||||||
|
|
||||||
ret = device_add(dev);
|
ret = device_add(dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "device_register failed: %d\n", ret);
|
dev_err(dev, "device_add failed: %d\n", ret);
|
||||||
put_device(dev);
|
put_device(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
|
||||||
|
|
||||||
ret = device_add(dev);
|
ret = device_add(dev);
|
||||||
if (ret) {
|
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);
|
put_device(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,11 @@ static ssize_t modalias_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
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);
|
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)
|
static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
|
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,
|
return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
|
||||||
rpdev->id.name);
|
rpdev->id.name);
|
||||||
|
@ -464,13 +474,6 @@ static struct bus_type rpmsg_bus = {
|
||||||
.remove = rpmsg_dev_remove,
|
.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)
|
int rpmsg_register_device(struct rpmsg_device *rpdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &rpdev->dev;
|
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->id.name, rpdev->src, rpdev->dst);
|
||||||
|
|
||||||
rpdev->dev.bus = &rpmsg_bus;
|
rpdev->dev.bus = &rpmsg_bus;
|
||||||
rpdev->dev.release = rpmsg_release_device;
|
|
||||||
|
|
||||||
ret = device_register(&rpdev->dev);
|
ret = device_register(&rpdev->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -314,7 +314,7 @@ static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* need to tell remote processor's name service about this channel ? */
|
/* 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)) {
|
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
|
||||||
struct rpmsg_ns_msg nsm;
|
struct rpmsg_ns_msg nsm;
|
||||||
|
|
||||||
|
@ -338,12 +338,12 @@ static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* tell remote processor's name service we're removing this channel */
|
/* 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)) {
|
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
|
||||||
struct rpmsg_ns_msg nsm;
|
struct rpmsg_ns_msg nsm;
|
||||||
|
|
||||||
strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
|
strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
|
||||||
nsm.addr = rpdev->src;
|
nsm.addr = rpdev->ept->addr;
|
||||||
nsm.flags = RPMSG_NS_DESTROY;
|
nsm.flags = RPMSG_NS_DESTROY;
|
||||||
|
|
||||||
err = rpmsg_sendto(rpdev->ept, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
|
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,
|
.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.
|
* create an rpmsg channel using its name and address info.
|
||||||
* this function will be used to create both static and dynamic
|
* 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 */
|
/* Link the channel to our vrp */
|
||||||
vch->vrp = vrp;
|
vch->vrp = vrp;
|
||||||
|
|
||||||
/* Assign callbacks for rpmsg_channel */
|
|
||||||
vch->rpdev.ops = &virtio_rpmsg_ops;
|
|
||||||
|
|
||||||
/* Assign public information to the rpmsg_device */
|
/* Assign public information to the rpmsg_device */
|
||||||
rpdev = &vch->rpdev;
|
rpdev = &vch->rpdev;
|
||||||
rpdev->src = chinfo->src;
|
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);
|
strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
|
||||||
|
|
||||||
rpdev->dev.parent = &vrp->vdev->dev;
|
rpdev->dev.parent = &vrp->vdev->dev;
|
||||||
|
rpdev->dev.release = virtio_rpmsg_release_device;
|
||||||
ret = rpmsg_register_device(rpdev);
|
ret = rpmsg_register_device(rpdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче