diff options
Diffstat (limited to 'drivers/remoteproc/qcom_common.c')
| -rw-r--r-- | drivers/remoteproc/qcom_common.c | 87 | 
1 files changed, 87 insertions, 0 deletions
| diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 03e5f5d533eb..8c8688f99f0a 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -13,6 +13,7 @@  #include <linux/notifier.h>  #include <linux/remoteproc.h>  #include <linux/remoteproc/qcom_rproc.h> +#include <linux/auxiliary_bus.h>  #include <linux/rpmsg/qcom_glink.h>  #include <linux/rpmsg/qcom_smd.h>  #include <linux/slab.h> @@ -25,6 +26,7 @@  #define to_glink_subdev(d) container_of(d, struct qcom_rproc_glink, subdev)  #define to_smd_subdev(d) container_of(d, struct qcom_rproc_subdev, subdev)  #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev) +#define to_pdm_subdev(d) container_of(d, struct qcom_rproc_pdm, subdev)  #define MAX_NUM_OF_SS           10  #define MAX_REGION_NAME_LENGTH  16 @@ -519,5 +521,90 @@ void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr)  }  EXPORT_SYMBOL_GPL(qcom_remove_ssr_subdev); +static void pdm_dev_release(struct device *dev) +{ +	struct auxiliary_device *adev = to_auxiliary_dev(dev); + +	kfree(adev); +} + +static int pdm_notify_prepare(struct rproc_subdev *subdev) +{ +	struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev); +	struct auxiliary_device *adev; +	int ret; + +	adev = kzalloc(sizeof(*adev), GFP_KERNEL); +	if (!adev) +		return -ENOMEM; + +	adev->dev.parent = pdm->dev; +	adev->dev.release = pdm_dev_release; +	adev->name = "pd-mapper"; +	adev->id = pdm->index; + +	ret = auxiliary_device_init(adev); +	if (ret) { +		kfree(adev); +		return ret; +	} + +	ret = auxiliary_device_add(adev); +	if (ret) { +		auxiliary_device_uninit(adev); +		return ret; +	} + +	pdm->adev = adev; + +	return 0; +} + + +static void pdm_notify_unprepare(struct rproc_subdev *subdev) +{ +	struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev); + +	if (!pdm->adev) +		return; + +	auxiliary_device_delete(pdm->adev); +	auxiliary_device_uninit(pdm->adev); +	pdm->adev = NULL; +} + +/** + * qcom_add_pdm_subdev() - register PD Mapper subdevice + * @rproc:	rproc handle + * @pdm:	PDM subdevice handle + * + * Register @pdm so that Protection Device mapper service is started when the + * DSP is started too. + */ +void qcom_add_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm) +{ +	pdm->dev = &rproc->dev; +	pdm->index = rproc->index; + +	pdm->subdev.prepare = pdm_notify_prepare; +	pdm->subdev.unprepare = pdm_notify_unprepare; + +	rproc_add_subdev(rproc, &pdm->subdev); +} +EXPORT_SYMBOL_GPL(qcom_add_pdm_subdev); + +/** + * qcom_remove_pdm_subdev() - remove PD Mapper subdevice + * @rproc:	rproc handle + * @pdm:	PDM subdevice handle + * + * Remove the PD Mapper subdevice. + */ +void qcom_remove_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm) +{ +	rproc_remove_subdev(rproc, &pdm->subdev); +} +EXPORT_SYMBOL_GPL(qcom_remove_pdm_subdev); +  MODULE_DESCRIPTION("Qualcomm Remoteproc helper driver");  MODULE_LICENSE("GPL v2"); |