--- zzzz-none-000/linux-5.4.213/drivers/remoteproc/qcom_q6v5.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/drivers/remoteproc/qcom_q6v5.c 2024-08-14 09:02:08.000000000 +0000 @@ -14,6 +14,9 @@ #include #include #include "qcom_q6v5.h" +#include + +#define STOP_ACK_TIMEOUT_MS 5000 /** * qcom_q6v5_prepare() - reinitialize the qcom_q6v5 context before start @@ -61,7 +64,7 @@ return IRQ_HANDLED; } - msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, &len); + msg = qcom_smem_get(q6v5->remote_id, q6v5->crash_reason, &len); if (!IS_ERR(msg) && len > 0 && msg[0]) dev_err(q6v5->dev, "watchdog received: %s\n", msg); else @@ -72,13 +75,13 @@ return IRQ_HANDLED; } -static irqreturn_t q6v5_fatal_interrupt(int irq, void *data) +irqreturn_t q6v5_fatal_interrupt(int irq, void *data) { struct qcom_q6v5 *q6v5 = data; size_t len; char *msg; - msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, q6v5->crash_reason, &len); + msg = qcom_smem_get(q6v5->remote_id, q6v5->crash_reason, &len); if (!IS_ERR(msg) && len > 0 && msg[0]) dev_err(q6v5->dev, "fatal error received: %s\n", msg); else @@ -90,10 +93,12 @@ return IRQ_HANDLED; } -static irqreturn_t q6v5_ready_interrupt(int irq, void *data) +irqreturn_t q6v5_ready_interrupt(int irq, void *data) { struct qcom_q6v5 *q6v5 = data; + pr_info("Subsystem error monitoring/handling services are up\n"); + complete(&q6v5->start_done); return IRQ_HANDLED; @@ -132,7 +137,16 @@ return IRQ_HANDLED; } -static irqreturn_t q6v5_stop_interrupt(int irq, void *data) +irqreturn_t q6v5_spawn_interrupt(int irq, void *data) +{ + struct qcom_q6v5 *q6v5 = data; + + complete(&q6v5->spawn_done); + + return IRQ_HANDLED; +} + +irqreturn_t q6v5_stop_interrupt(int irq, void *data) { struct qcom_q6v5 *q6v5 = data; @@ -154,9 +168,10 @@ q6v5->running = false; qcom_smem_state_update_bits(q6v5->state, - BIT(q6v5->stop_bit), BIT(q6v5->stop_bit)); + BIT(q6v5->stop_bit), BIT(q6v5->stop_bit)); - ret = wait_for_completion_timeout(&q6v5->stop_done, 5 * HZ); + ret = wait_for_completion_timeout(&q6v5->stop_done, + msecs_to_jiffies(10000)); qcom_smem_state_update_bits(q6v5->state, BIT(q6v5->stop_bit), 0); @@ -165,6 +180,45 @@ EXPORT_SYMBOL_GPL(qcom_q6v5_request_stop); /** + * qcom_q6v5_request_spawn() - request the remote processor to spawn + * @q6v5: reference to qcom_q6v5 context + * + * Return: 0 on success, negative errno on failure + */ +int qcom_q6v5_request_spawn(struct qcom_q6v5 *q6v5) +{ + int ret; + + ret = qcom_smem_state_update_bits(q6v5->spawn_state, + BIT(q6v5->spawn_bit), BIT(q6v5->spawn_bit)); + + ret = wait_for_completion_timeout(&q6v5->spawn_done, + msecs_to_jiffies(10000)); + + qcom_smem_state_update_bits(q6v5->spawn_state, + BIT(q6v5->spawn_bit), 0); + + return ret == 0 ? -ETIMEDOUT : 0; +} +EXPORT_SYMBOL_GPL(qcom_q6v5_request_spawn); + +/** + * qcom_q6v5_panic_handler() - stop remote processor on panic + * @q6v5: reference to qcom_q6v5 context + * + */ +void qcom_q6v5_panic_handler(struct qcom_q6v5 *q6v5) +{ + q6v5->running = false; + + smem_panic_handler(); + qcom_smem_state_update_bits(q6v5->shutdown_state, + BIT(q6v5->shutdown_bit), BIT(q6v5->shutdown_bit)); + mdelay(STOP_ACK_TIMEOUT_MS); +} +EXPORT_SYMBOL_GPL(qcom_q6v5_panic_handler); + +/** * qcom_q6v5_init() - initializer of the q6v5 common struct * @q6v5: handle to be initialized * @pdev: platform_device reference for acquiring resources @@ -175,7 +229,7 @@ * Return: 0 on success, negative errno on failure */ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, - struct rproc *rproc, int crash_reason, + struct rproc *rproc, int remote_id, int crash_reason, void (*handover)(struct qcom_q6v5 *q6v5)) { int ret; @@ -184,6 +238,7 @@ q6v5->dev = &pdev->dev; q6v5->crash_reason = crash_reason; q6v5->handover = handover; + q6v5->remote_id = remote_id; init_completion(&q6v5->start_done); init_completion(&q6v5->stop_done); @@ -260,6 +315,12 @@ return PTR_ERR(q6v5->state); } + q6v5->shutdown_state = qcom_smem_state_get(&pdev->dev, "shutdown", &q6v5->shutdown_bit); + if (IS_ERR(q6v5->shutdown_state)) { + dev_err(&pdev->dev, "failed to acquire shutdown state\n"); + return PTR_ERR(q6v5->shutdown_state); + } + return 0; } EXPORT_SYMBOL_GPL(qcom_q6v5_init);