The SMEM and RPM transports request their receive interrupt with IRQF_NO_AUTOEN and enable it only after qcom_glink_native_probe() returns. Since native_probe() sends the initial version command, the remote may ACK before the local IRQ is enabled, stalling the version handshake on a fast remote.
Split the protocol start (qcom_glink_send_version() and qcom_glink_create_chrdev()) into a new qcom_glink_native_start(). Transports now enable their IRQ first, then call native_start(), so the version ACK is guaranteed to be serviced. Signed-off-by: Chunkai Deng <[email protected]> --- drivers/rpmsg/qcom_glink_native.c | 32 ++++++++++++++++++++++++++++---- drivers/rpmsg/qcom_glink_native.h | 1 + drivers/rpmsg/qcom_glink_rpm.c | 8 ++++++++ drivers/rpmsg/qcom_glink_smem.c | 8 ++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index d9d4468e4cbd..2a284b22a037 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1928,17 +1928,41 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, if (ret) dev_err(dev, "failed to add groups\n"); + return glink; +} +EXPORT_SYMBOL_GPL(qcom_glink_native_probe); + +/** + * qcom_glink_native_start() - start the GLINK protocol handshake + * @glink: glink handle returned by qcom_glink_native_probe() + * + * Send the initial version command and register the chrdev. This is split + * out from qcom_glink_native_probe() so that a transport can enable its + * receive interrupt before the version handshake is initiated, ensuring the + * version ACK from the remote is not missed. + * + * Failure to register the chrdev is not fatal and only logged, matching the + * previous behaviour of qcom_glink_native_probe(). + * + * Return: 0 on success, negative errno if sending the version command failed. + */ +int qcom_glink_native_start(struct qcom_glink *glink) +{ + int ret; + ret = qcom_glink_send_version(glink); - if (ret) - return ERR_PTR(ret); + if (ret) { + dev_err(glink->dev, "failed to send version: %d\n", ret); + return ret; + } ret = qcom_glink_create_chrdev(glink); if (ret) dev_err(glink->dev, "failed to register chrdev\n"); - return glink; + return 0; } -EXPORT_SYMBOL_GPL(qcom_glink_native_probe); +EXPORT_SYMBOL_GPL(qcom_glink_native_start); static int qcom_glink_remove_device(struct device *dev, void *data) { diff --git a/drivers/rpmsg/qcom_glink_native.h b/drivers/rpmsg/qcom_glink_native.h index 8dbec24de23e..783209980c3a 100644 --- a/drivers/rpmsg/qcom_glink_native.h +++ b/drivers/rpmsg/qcom_glink_native.h @@ -35,6 +35,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, struct qcom_glink_pipe *rx, struct qcom_glink_pipe *tx, bool intentless); +int qcom_glink_native_start(struct qcom_glink *glink); void qcom_glink_native_remove(struct qcom_glink *glink); void qcom_glink_native_rx(struct qcom_glink *glink); diff --git a/drivers/rpmsg/qcom_glink_rpm.c b/drivers/rpmsg/qcom_glink_rpm.c index e3ba2c63a5fc..34f18c3e58c8 100644 --- a/drivers/rpmsg/qcom_glink_rpm.c +++ b/drivers/rpmsg/qcom_glink_rpm.c @@ -358,6 +358,14 @@ static int glink_rpm_probe(struct platform_device *pdev) enable_irq(rpm->irq); + ret = qcom_glink_native_start(glink); + if (ret) { + disable_irq(rpm->irq); + qcom_glink_native_remove(glink); + mbox_free_channel(rpm->mbox_chan); + return ret; + } + return 0; } diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 62adc4db2317..28f6cfda6352 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -348,8 +348,16 @@ struct qcom_glink_smem *qcom_glink_smem_register(struct device *parent, enable_irq(smem->irq); + ret = qcom_glink_native_start(glink); + if (ret) + goto err_disable_irq; + return smem; +err_disable_irq: + disable_irq(smem->irq); + qcom_glink_native_remove(glink); + err_free_mbox: mbox_free_channel(smem->mbox_chan); --- base-commit: a225caacc36546a09586e3ece36c0313146e7da9 change-id: 20260604-rpmsg-glink-split-protocol-start-3df74dbd5c94 Best regards, -- Chunkai Deng <[email protected]>

