* [PATCH v3] slimbus: qcom-ngd-ctrl: Implement disable_stream callback
@ 2026-09-25 9:22 Viken Dadhaniya
2026-09-25 9:28 ` Srinivas Kandagatla
0 siblings, 1 reply; 2+ messages in thread
From: Viken Dadhaniya @ 2026-09-25 9:22 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: linux-arm-msm, linux-sound, linux-kernel, mukesh.savaliya,
Viken Dadhaniya
Switching a channel to a new frequency without first disabling the stream
causes the channel to be re-enabled without a clean shutdown, leading to a
crash on the DSP subsystem.
Implement qcom_slim_ngd_disable_stream() so clients can properly close a
channel before switching to a new frequency.
Acked-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
Changes in v3:
- Handle -EREMOTEIO as success during stream disable.
- Drop copyright update changes.
- Link to v2: https://patch.msgid.link/20260810-slim-disable-stream-support-v2-1-c2e8fcc3c99d@oss.qualcomm.com
Changes in v2:
- Rewrite commit description for clarity.
- Fix initializers: use { 0 } instead of {0} and {0,}.
- Use reverse christmas tree ordering for local variable declarations.
- Replace open-coded shift/mask with FIELD_PREP() and GENMASK-based defines.
- Add SLIM_MSG_HDR_LEN macro to replace magic number +4 in txn.rl assignments.
- Fix dev_err format strings: add spaces after colons and commas.
- Update enum slim_ch_control comment to kernel-doc format with @member tags.
- Link to v1: https://lore.kernel.org/linux-arm-msm/247e4ce7-1ba2-43b8-8a11-ec70f99a4fc1@linaro.org/T/#m3b50aa43a6493f8d3b607b1607b37bf14b199f69
---
drivers/slimbus/qcom-ngd-ctrl.c | 78 +++++++++++++++++++++++++++++++++++++++++
drivers/slimbus/slimbus.h | 12 +++++++
2 files changed, 90 insertions(+)
diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
index eb0ccb31e907..f0a402069aea 100644
--- a/drivers/slimbus/qcom-ngd-ctrl.c
+++ b/drivers/slimbus/qcom-ngd-ctrl.c
@@ -2,6 +2,7 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <linux/bitfield.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -87,6 +88,10 @@
#define SLIM_ROOT_FREQ 24576000
#define LADDR_RETRY 5
+#define SLIM_CHAN_CTRL_CMD GENMASK(7, 6)
+#define SLIM_CHAN_CTRL_LADDR GENMASK(4, 0)
+#define SLIM_MSG_HDR_LEN 4
+
/* Per spec.max 40 bytes per received message */
#define SLIM_MSGQ_BUF_LEN 40
#define QCOM_SLIM_NGD_DESC_NUM 32
@@ -1086,6 +1091,78 @@ static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt)
return ret;
}
+static int qcom_slim_ngd_disable_stream(struct slim_stream_runtime *rt)
+{
+ struct slim_device *sdev = rt->dev;
+ struct slim_controller *ctrl = sdev->ctrl;
+ struct slim_msg_txn txn = { 0 };
+ struct slim_val_inf msg = { 0 };
+ u8 wbuf[SLIM_MSGQ_BUF_LEN];
+ u8 rbuf[SLIM_MSGQ_BUF_LEN];
+ int i, ret;
+
+ txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
+ txn.dt = SLIM_MSG_DEST_LOGICALADDR;
+ txn.la = SLIM_LA_MGR;
+ txn.ec = 0;
+ txn.msg = &msg;
+ txn.msg->num_bytes = 0;
+ txn.msg->wbuf = wbuf;
+ txn.msg->rbuf = rbuf;
+
+ for (i = 0; i < rt->num_ports; i++) {
+ struct slim_port *port = &rt->ports[i];
+
+ if (txn.msg->num_bytes == 0) {
+ wbuf[txn.msg->num_bytes++] =
+ FIELD_PREP(SLIM_CHAN_CTRL_CMD, SLIM_CH_REMOVE) |
+ FIELD_PREP(SLIM_CHAN_CTRL_LADDR, sdev->laddr);
+
+ ret = slim_alloc_txn_tid(ctrl, &txn);
+ if (ret) {
+ dev_err(&sdev->dev, "Fail to allocate TID ret:%d\n", ret);
+ return ret;
+ }
+ wbuf[txn.msg->num_bytes++] = txn.tid;
+ }
+ wbuf[txn.msg->num_bytes++] = port->ch.id;
+ }
+
+ txn.mc = SLIM_USR_MC_CHAN_CTRL;
+ txn.rl = txn.msg->num_bytes + SLIM_MSG_HDR_LEN;
+ ret = qcom_slim_ngd_xfer_msg_sync(ctrl, &txn);
+ if (ret) {
+ slim_free_txn_tid(ctrl, &txn);
+ /* Controller restarting, the channels are gone anyway */
+ if (ret == -EREMOTEIO)
+ return 0;
+ dev_err(&sdev->dev, "TX timed out: MC: 0x%x, mt: 0x%x, laddr: 0x%x, ret: %d\n",
+ txn.mc, txn.mt, sdev->laddr, ret);
+ return ret;
+ }
+
+ txn.mc = SLIM_USR_MC_RECONFIG_NOW;
+ txn.msg->num_bytes = 2;
+ wbuf[1] = sdev->laddr;
+ txn.rl = txn.msg->num_bytes + SLIM_MSG_HDR_LEN;
+
+ ret = slim_alloc_txn_tid(ctrl, &txn);
+ if (ret) {
+ dev_err(&sdev->dev, "Fail to allocate TID ret:%d\n", ret);
+ return ret;
+ }
+
+ wbuf[0] = txn.tid;
+ ret = qcom_slim_ngd_xfer_msg_sync(ctrl, &txn);
+ if (ret) {
+ slim_free_txn_tid(ctrl, &txn);
+ dev_err(&sdev->dev, "TX timed out: MC: 0x%x, mt: 0x%x, laddr: 0x%x, ret: %d\n",
+ txn.mc, txn.mt, sdev->laddr, ret);
+ }
+
+ return ret;
+}
+
static int qcom_slim_ngd_get_laddr(struct slim_controller *ctrl,
struct slim_eaddr *ea, u8 *laddr)
{
@@ -1625,6 +1702,7 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
ctrl->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
ctrl->ctrl.get_laddr = qcom_slim_ngd_get_laddr;
ctrl->ctrl.enable_stream = qcom_slim_ngd_enable_stream;
+ ctrl->ctrl.disable_stream = qcom_slim_ngd_disable_stream;
ctrl->ctrl.xfer_msg = qcom_slim_ngd_xfer_msg;
ctrl->ctrl.wakeup = NULL;
ctrl->state = QCOM_SLIM_NGD_CTRL_DOWN;
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index 3a03993c3ac8..8e34f30601d3 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -316,6 +316,18 @@ enum slim_transport_protocol {
SLIM_PROTO_EXT_HALF_DUP,
};
+/**
+ * enum slim_ch_control: Channel control.
+ * @SLIM_CH_ACTIVATE: Schedules channel or group of channels in the TDM frame.
+ * @SLIM_CH_SUSPEND: Keeps the TDM schedule but halts data transfer.
+ * @SLIM_CH_REMOVE: Drops the channel or group from the TDM frame.
+ */
+enum slim_ch_control {
+ SLIM_CH_ACTIVATE,
+ SLIM_CH_SUSPEND,
+ SLIM_CH_REMOVE,
+};
+
/**
* struct slim_stream_runtime - SLIMbus stream runtime instance
*
---
base-commit: 4c253ac4b29b8c6cc6fdef8f92d4facde62e63b9
change-id: 20260803-slim-disable-stream-support-43599401607f
Best regards,
--
Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v3] slimbus: qcom-ngd-ctrl: Implement disable_stream callback
2026-09-25 9:22 [PATCH v3] slimbus: qcom-ngd-ctrl: Implement disable_stream callback Viken Dadhaniya
@ 2026-09-25 9:28 ` Srinivas Kandagatla
0 siblings, 0 replies; 2+ messages in thread
From: Srinivas Kandagatla @ 2026-09-25 9:28 UTC (permalink / raw)
To: Viken Dadhaniya; +Cc: linux-arm-msm, linux-sound, linux-kernel, mukesh.savaliya
On Fri, 25 Sep 2026 14:52:49 +0530, Viken Dadhaniya wrote:
> Switching a channel to a new frequency without first disabling the stream
> causes the channel to be re-enabled without a clean shutdown, leading to a
> crash on the DSP subsystem.
>
> Implement qcom_slim_ngd_disable_stream() so clients can properly close a
> channel before switching to a new frequency.
>
> [...]
Applied, thanks!
[1/1] slimbus: qcom-ngd-ctrl: Implement disable_stream callback
commit: 82d873c864b033af83f2b8f34da025d08e4e886d
Best regards,
--
Srinivas Kandagatla <srini@kernel.org>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-25 9:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-25 9:22 [PATCH v3] slimbus: qcom-ngd-ctrl: Implement disable_stream callback Viken Dadhaniya
2026-09-25 9:28 ` Srinivas Kandagatla
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®