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:
Linus Torvalds 2017-07-06 15:38:31 -07:00
Родитель 0dfaeb618f f4ce852811
Коммит 426b8eeb05
8 изменённых файлов: 1352 добавлений и 17 удалений

Просмотреть файл

@ -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;