diff options
Diffstat (limited to 'drivers/remoteproc/qcom_q6v5_ipa_notify.c')
-rw-r--r-- | drivers/remoteproc/qcom_q6v5_ipa_notify.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/remoteproc/qcom_q6v5_ipa_notify.c b/drivers/remoteproc/qcom_q6v5_ipa_notify.c new file mode 100644 index 000000000000..e1c10a128bfd --- /dev/null +++ b/drivers/remoteproc/qcom_q6v5_ipa_notify.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Qualcomm IPA notification subdev support + * + * Copyright (C) 2019 Linaro Ltd. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/remoteproc.h> +#include <linux/remoteproc/qcom_q6v5_ipa_notify.h> + +static void +ipa_notify_common(struct rproc_subdev *subdev, enum qcom_rproc_event event) +{ + struct qcom_rproc_ipa_notify *ipa_notify; + qcom_ipa_notify_t notify; + + ipa_notify = container_of(subdev, struct qcom_rproc_ipa_notify, subdev); + notify = ipa_notify->notify; + if (notify) + notify(ipa_notify->data, event); +} + +static int ipa_notify_prepare(struct rproc_subdev *subdev) +{ + ipa_notify_common(subdev, MODEM_STARTING); + + return 0; +} + +static int ipa_notify_start(struct rproc_subdev *subdev) +{ + ipa_notify_common(subdev, MODEM_RUNNING); + + return 0; +} + +static void ipa_notify_stop(struct rproc_subdev *subdev, bool crashed) + +{ + ipa_notify_common(subdev, crashed ? MODEM_CRASHED : MODEM_STOPPING); +} + +static void ipa_notify_unprepare(struct rproc_subdev *subdev) +{ + ipa_notify_common(subdev, MODEM_OFFLINE); +} + +static void ipa_notify_removing(struct rproc_subdev *subdev) +{ + ipa_notify_common(subdev, MODEM_REMOVING); +} + +/* Register the IPA notification subdevice with the Q6V5 MSS remoteproc */ +void qcom_add_ipa_notify_subdev(struct rproc *rproc, + struct qcom_rproc_ipa_notify *ipa_notify) +{ + ipa_notify->notify = NULL; + ipa_notify->data = NULL; + ipa_notify->subdev.prepare = ipa_notify_prepare; + ipa_notify->subdev.start = ipa_notify_start; + ipa_notify->subdev.stop = ipa_notify_stop; + ipa_notify->subdev.unprepare = ipa_notify_unprepare; + + rproc_add_subdev(rproc, &ipa_notify->subdev); +} +EXPORT_SYMBOL_GPL(qcom_add_ipa_notify_subdev); + +/* Remove the IPA notification subdevice */ +void qcom_remove_ipa_notify_subdev(struct rproc *rproc, + struct qcom_rproc_ipa_notify *ipa_notify) +{ + struct rproc_subdev *subdev = &ipa_notify->subdev; + + ipa_notify_removing(subdev); + + rproc_remove_subdev(rproc, subdev); + ipa_notify->notify = NULL; /* Make it obvious */ +} +EXPORT_SYMBOL_GPL(qcom_remove_ipa_notify_subdev); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Qualcomm IPA notification remoteproc subdev"); |