|
13 | 13 | #include <linux/notifier.h> |
14 | 14 | #include <linux/remoteproc.h> |
15 | 15 | #include <linux/remoteproc/qcom_rproc.h> |
| 16 | +#include <linux/auxiliary_bus.h> |
16 | 17 | #include <linux/rpmsg/qcom_glink.h> |
17 | 18 | #include <linux/rpmsg/qcom_smd.h> |
18 | 19 | #include <linux/slab.h> |
|
25 | 26 | #define to_glink_subdev(d) container_of(d, struct qcom_rproc_glink, subdev) |
26 | 27 | #define to_smd_subdev(d) container_of(d, struct qcom_rproc_subdev, subdev) |
27 | 28 | #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev) |
| 29 | +#define to_pdm_subdev(d) container_of(d, struct qcom_rproc_pdm, subdev) |
28 | 30 |
|
29 | 31 | #define MAX_NUM_OF_SS 10 |
30 | 32 | #define MAX_REGION_NAME_LENGTH 16 |
@@ -519,5 +521,90 @@ void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr) |
519 | 521 | } |
520 | 522 | EXPORT_SYMBOL_GPL(qcom_remove_ssr_subdev); |
521 | 523 |
|
| 524 | +static void pdm_dev_release(struct device *dev) |
| 525 | +{ |
| 526 | + struct auxiliary_device *adev = to_auxiliary_dev(dev); |
| 527 | + |
| 528 | + kfree(adev); |
| 529 | +} |
| 530 | + |
| 531 | +static int pdm_notify_prepare(struct rproc_subdev *subdev) |
| 532 | +{ |
| 533 | + struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev); |
| 534 | + struct auxiliary_device *adev; |
| 535 | + int ret; |
| 536 | + |
| 537 | + adev = kzalloc(sizeof(*adev), GFP_KERNEL); |
| 538 | + if (!adev) |
| 539 | + return -ENOMEM; |
| 540 | + |
| 541 | + adev->dev.parent = pdm->dev; |
| 542 | + adev->dev.release = pdm_dev_release; |
| 543 | + adev->name = "pd-mapper"; |
| 544 | + adev->id = pdm->index; |
| 545 | + |
| 546 | + ret = auxiliary_device_init(adev); |
| 547 | + if (ret) { |
| 548 | + kfree(adev); |
| 549 | + return ret; |
| 550 | + } |
| 551 | + |
| 552 | + ret = auxiliary_device_add(adev); |
| 553 | + if (ret) { |
| 554 | + auxiliary_device_uninit(adev); |
| 555 | + return ret; |
| 556 | + } |
| 557 | + |
| 558 | + pdm->adev = adev; |
| 559 | + |
| 560 | + return 0; |
| 561 | +} |
| 562 | + |
| 563 | + |
| 564 | +static void pdm_notify_unprepare(struct rproc_subdev *subdev) |
| 565 | +{ |
| 566 | + struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev); |
| 567 | + |
| 568 | + if (!pdm->adev) |
| 569 | + return; |
| 570 | + |
| 571 | + auxiliary_device_delete(pdm->adev); |
| 572 | + auxiliary_device_uninit(pdm->adev); |
| 573 | + pdm->adev = NULL; |
| 574 | +} |
| 575 | + |
| 576 | +/** |
| 577 | + * qcom_add_pdm_subdev() - register PD Mapper subdevice |
| 578 | + * @rproc: rproc handle |
| 579 | + * @pdm: PDM subdevice handle |
| 580 | + * |
| 581 | + * Register @pdm so that Protection Device mapper service is started when the |
| 582 | + * DSP is started too. |
| 583 | + */ |
| 584 | +void qcom_add_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm) |
| 585 | +{ |
| 586 | + pdm->dev = &rproc->dev; |
| 587 | + pdm->index = rproc->index; |
| 588 | + |
| 589 | + pdm->subdev.prepare = pdm_notify_prepare; |
| 590 | + pdm->subdev.unprepare = pdm_notify_unprepare; |
| 591 | + |
| 592 | + rproc_add_subdev(rproc, &pdm->subdev); |
| 593 | +} |
| 594 | +EXPORT_SYMBOL_GPL(qcom_add_pdm_subdev); |
| 595 | + |
| 596 | +/** |
| 597 | + * qcom_remove_pdm_subdev() - remove PD Mapper subdevice |
| 598 | + * @rproc: rproc handle |
| 599 | + * @pdm: PDM subdevice handle |
| 600 | + * |
| 601 | + * Remove the PD Mapper subdevice. |
| 602 | + */ |
| 603 | +void qcom_remove_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm) |
| 604 | +{ |
| 605 | + rproc_remove_subdev(rproc, &pdm->subdev); |
| 606 | +} |
| 607 | +EXPORT_SYMBOL_GPL(qcom_remove_pdm_subdev); |
| 608 | + |
522 | 609 | MODULE_DESCRIPTION("Qualcomm Remoteproc helper driver"); |
523 | 610 | MODULE_LICENSE("GPL v2"); |
0 commit comments