1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2018, Linaro Limited
5 #include <linux/kernel.h>
6 #include <linux/module.h>
7 #include <linux/device.h>
8 #include <linux/spinlock.h>
10 #include <linux/slab.h>
11 #include <linux/workqueue.h>
12 #include <linux/of_device.h>
13 #include <linux/soc/qcom/apr.h>
14 #include <linux/rpmsg.h>
18 struct rpmsg_endpoint
*ch
;
24 struct workqueue_struct
*rxwq
;
25 struct work_struct rx_work
;
26 struct list_head rx_list
;
30 struct list_head node
;
36 * apr_send_pkt() - Send a apr message from apr device
38 * @adev: Pointer to previously registered apr device.
39 * @pkt: Pointer to apr packet to send
41 * Return: Will be an negative on packet size on success.
43 int apr_send_pkt(struct apr_device
*adev
, struct apr_pkt
*pkt
)
45 struct apr
*apr
= dev_get_drvdata(adev
->dev
.parent
);
50 spin_lock_irqsave(&adev
->lock
, flags
);
53 hdr
->src_domain
= APR_DOMAIN_APPS
;
54 hdr
->src_svc
= adev
->svc_id
;
55 hdr
->dest_domain
= adev
->domain_id
;
56 hdr
->dest_svc
= adev
->svc_id
;
58 ret
= rpmsg_trysend(apr
->ch
, pkt
, hdr
->pkt_size
);
59 spin_unlock_irqrestore(&adev
->lock
, flags
);
61 return ret
? ret
: hdr
->pkt_size
;
63 EXPORT_SYMBOL_GPL(apr_send_pkt
);
65 static void apr_dev_release(struct device
*dev
)
67 struct apr_device
*adev
= to_apr_device(dev
);
72 static int apr_callback(struct rpmsg_device
*rpdev
, void *buf
,
73 int len
, void *priv
, u32 addr
)
75 struct apr
*apr
= dev_get_drvdata(&rpdev
->dev
);
76 struct apr_rx_buf
*abuf
;
79 if (len
<= APR_HDR_SIZE
) {
80 dev_err(apr
->dev
, "APR: Improper apr pkt received:%p %d\n",
85 abuf
= kzalloc(sizeof(*abuf
) + len
, GFP_ATOMIC
);
90 memcpy(abuf
->buf
, buf
, len
);
92 spin_lock_irqsave(&apr
->rx_lock
, flags
);
93 list_add_tail(&abuf
->node
, &apr
->rx_list
);
94 spin_unlock_irqrestore(&apr
->rx_lock
, flags
);
96 queue_work(apr
->rxwq
, &apr
->rx_work
);
102 static int apr_do_rx_callback(struct apr
*apr
, struct apr_rx_buf
*abuf
)
104 uint16_t hdr_size
, msg_type
, ver
, svc_id
;
105 struct apr_device
*svc
= NULL
;
106 struct apr_driver
*adrv
= NULL
;
107 struct apr_resp_pkt resp
;
110 void *buf
= abuf
->buf
;
114 ver
= APR_HDR_FIELD_VER(hdr
->hdr_field
);
115 if (ver
> APR_PKT_VER
+ 1)
118 hdr_size
= APR_HDR_FIELD_SIZE_BYTES(hdr
->hdr_field
);
119 if (hdr_size
< APR_HDR_SIZE
) {
120 dev_err(apr
->dev
, "APR: Wrong hdr size:%d\n", hdr_size
);
124 if (hdr
->pkt_size
< APR_HDR_SIZE
|| hdr
->pkt_size
!= len
) {
125 dev_err(apr
->dev
, "APR: Wrong packet size\n");
129 msg_type
= APR_HDR_FIELD_MT(hdr
->hdr_field
);
130 if (msg_type
>= APR_MSG_TYPE_MAX
) {
131 dev_err(apr
->dev
, "APR: Wrong message type: %d\n", msg_type
);
135 if (hdr
->src_domain
>= APR_DOMAIN_MAX
||
136 hdr
->dest_domain
>= APR_DOMAIN_MAX
||
137 hdr
->src_svc
>= APR_SVC_MAX
||
138 hdr
->dest_svc
>= APR_SVC_MAX
) {
139 dev_err(apr
->dev
, "APR: Wrong APR header\n");
143 svc_id
= hdr
->dest_svc
;
144 spin_lock_irqsave(&apr
->svcs_lock
, flags
);
145 svc
= idr_find(&apr
->svcs_idr
, svc_id
);
146 if (svc
&& svc
->dev
.driver
)
147 adrv
= to_apr_driver(svc
->dev
.driver
);
148 spin_unlock_irqrestore(&apr
->svcs_lock
, flags
);
151 dev_err(apr
->dev
, "APR: service is not registered\n");
156 resp
.payload_size
= hdr
->pkt_size
- hdr_size
;
159 * NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include
160 * optional headers in to apr_hdr which should be ignored
162 if (resp
.payload_size
> 0)
163 resp
.payload
= buf
+ hdr_size
;
165 adrv
->callback(svc
, &resp
);
170 static void apr_rxwq(struct work_struct
*work
)
172 struct apr
*apr
= container_of(work
, struct apr
, rx_work
);
173 struct apr_rx_buf
*abuf
, *b
;
176 if (!list_empty(&apr
->rx_list
)) {
177 list_for_each_entry_safe(abuf
, b
, &apr
->rx_list
, node
) {
178 apr_do_rx_callback(apr
, abuf
);
179 spin_lock_irqsave(&apr
->rx_lock
, flags
);
180 list_del(&abuf
->node
);
181 spin_unlock_irqrestore(&apr
->rx_lock
, flags
);
187 static int apr_device_match(struct device
*dev
, struct device_driver
*drv
)
189 struct apr_device
*adev
= to_apr_device(dev
);
190 struct apr_driver
*adrv
= to_apr_driver(drv
);
191 const struct apr_device_id
*id
= adrv
->id_table
;
193 /* Attempt an OF style match first */
194 if (of_driver_match_device(dev
, drv
))
200 while (id
->domain_id
!= 0 || id
->svc_id
!= 0) {
201 if (id
->domain_id
== adev
->domain_id
&&
202 id
->svc_id
== adev
->svc_id
)
210 static int apr_device_probe(struct device
*dev
)
212 struct apr_device
*adev
= to_apr_device(dev
);
213 struct apr_driver
*adrv
= to_apr_driver(dev
->driver
);
215 return adrv
->probe(adev
);
218 static int apr_device_remove(struct device
*dev
)
220 struct apr_device
*adev
= to_apr_device(dev
);
221 struct apr_driver
*adrv
;
222 struct apr
*apr
= dev_get_drvdata(adev
->dev
.parent
);
225 adrv
= to_apr_driver(dev
->driver
);
228 spin_lock(&apr
->svcs_lock
);
229 idr_remove(&apr
->svcs_idr
, adev
->svc_id
);
230 spin_unlock(&apr
->svcs_lock
);
236 static int apr_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
238 struct apr_device
*adev
= to_apr_device(dev
);
241 ret
= of_device_uevent_modalias(dev
, env
);
245 return add_uevent_var(env
, "MODALIAS=apr:%s", adev
->name
);
248 struct bus_type aprbus
= {
250 .match
= apr_device_match
,
251 .probe
= apr_device_probe
,
252 .uevent
= apr_uevent
,
253 .remove
= apr_device_remove
,
255 EXPORT_SYMBOL_GPL(aprbus
);
257 static int apr_add_device(struct device
*dev
, struct device_node
*np
,
258 const struct apr_device_id
*id
)
260 struct apr
*apr
= dev_get_drvdata(dev
);
261 struct apr_device
*adev
= NULL
;
264 adev
= kzalloc(sizeof(*adev
), GFP_KERNEL
);
268 spin_lock_init(&adev
->lock
);
270 adev
->svc_id
= id
->svc_id
;
271 adev
->domain_id
= id
->domain_id
;
272 adev
->version
= id
->svc_version
;
274 snprintf(adev
->name
, APR_NAME_SIZE
, "%pOFn", np
);
276 strscpy(adev
->name
, id
->name
, APR_NAME_SIZE
);
278 dev_set_name(&adev
->dev
, "aprsvc:%s:%x:%x", adev
->name
,
279 id
->domain_id
, id
->svc_id
);
281 adev
->dev
.bus
= &aprbus
;
282 adev
->dev
.parent
= dev
;
283 adev
->dev
.of_node
= np
;
284 adev
->dev
.release
= apr_dev_release
;
285 adev
->dev
.driver
= NULL
;
287 spin_lock(&apr
->svcs_lock
);
288 idr_alloc(&apr
->svcs_idr
, adev
, id
->svc_id
,
289 id
->svc_id
+ 1, GFP_ATOMIC
);
290 spin_unlock(&apr
->svcs_lock
);
292 dev_info(dev
, "Adding APR dev: %s\n", dev_name(&adev
->dev
));
294 ret
= device_register(&adev
->dev
);
296 dev_err(dev
, "device_register failed: %d\n", ret
);
297 put_device(&adev
->dev
);
303 static void of_register_apr_devices(struct device
*dev
)
305 struct apr
*apr
= dev_get_drvdata(dev
);
306 struct device_node
*node
;
308 for_each_child_of_node(dev
->of_node
, node
) {
309 struct apr_device_id id
= { {0} };
311 if (of_property_read_u32(node
, "reg", &id
.svc_id
))
314 id
.domain_id
= apr
->dest_domain_id
;
316 if (apr_add_device(dev
, node
, &id
))
317 dev_err(dev
, "Failed to add apr %d svc\n", id
.svc_id
);
321 static int apr_probe(struct rpmsg_device
*rpdev
)
323 struct device
*dev
= &rpdev
->dev
;
327 apr
= devm_kzalloc(dev
, sizeof(*apr
), GFP_KERNEL
);
331 ret
= of_property_read_u32(dev
->of_node
, "qcom,apr-domain", &apr
->dest_domain_id
);
333 dev_err(dev
, "APR Domain ID not specified in DT\n");
337 dev_set_drvdata(dev
, apr
);
338 apr
->ch
= rpdev
->ept
;
340 apr
->rxwq
= create_singlethread_workqueue("qcom_apr_rx");
342 dev_err(apr
->dev
, "Failed to start Rx WQ\n");
345 INIT_WORK(&apr
->rx_work
, apr_rxwq
);
346 INIT_LIST_HEAD(&apr
->rx_list
);
347 spin_lock_init(&apr
->rx_lock
);
348 spin_lock_init(&apr
->svcs_lock
);
349 idr_init(&apr
->svcs_idr
);
350 of_register_apr_devices(dev
);
355 static int apr_remove_device(struct device
*dev
, void *null
)
357 struct apr_device
*adev
= to_apr_device(dev
);
359 device_unregister(&adev
->dev
);
364 static void apr_remove(struct rpmsg_device
*rpdev
)
366 struct apr
*apr
= dev_get_drvdata(&rpdev
->dev
);
368 device_for_each_child(&rpdev
->dev
, NULL
, apr_remove_device
);
369 flush_workqueue(apr
->rxwq
);
370 destroy_workqueue(apr
->rxwq
);
374 * __apr_driver_register() - Client driver registration with aprbus
376 * @drv:Client driver to be associated with client-device.
377 * @owner: owning module/driver
379 * This API will register the client driver with the aprbus
380 * It is called from the driver's module-init function.
382 int __apr_driver_register(struct apr_driver
*drv
, struct module
*owner
)
384 drv
->driver
.bus
= &aprbus
;
385 drv
->driver
.owner
= owner
;
387 return driver_register(&drv
->driver
);
389 EXPORT_SYMBOL_GPL(__apr_driver_register
);
392 * apr_driver_unregister() - Undo effect of apr_driver_register
394 * @drv: Client driver to be unregistered
396 void apr_driver_unregister(struct apr_driver
*drv
)
398 driver_unregister(&drv
->driver
);
400 EXPORT_SYMBOL_GPL(apr_driver_unregister
);
402 static const struct of_device_id apr_of_match
[] = {
403 { .compatible
= "qcom,apr"},
404 { .compatible
= "qcom,apr-v2"},
407 MODULE_DEVICE_TABLE(of
, apr_of_match
);
409 static struct rpmsg_driver apr_driver
= {
411 .remove
= apr_remove
,
412 .callback
= apr_callback
,
415 .of_match_table
= apr_of_match
,
419 static int __init
apr_init(void)
423 ret
= bus_register(&aprbus
);
425 ret
= register_rpmsg_driver(&apr_driver
);
427 bus_unregister(&aprbus
);
432 static void __exit
apr_exit(void)
434 bus_unregister(&aprbus
);
435 unregister_rpmsg_driver(&apr_driver
);
438 subsys_initcall(apr_init
);
439 module_exit(apr_exit
);
441 MODULE_LICENSE("GPL v2");
442 MODULE_DESCRIPTION("Qualcomm APR Bus");