Skip to content

Commit 1b59d6c

Browse files
committed
Merge tag 'scmi-fixes-6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm SCMI fixes for v6.12 Couple of fixes to address the issues found and reported on Broadcom STB platforms following the recent refactor of all the SCMI transports as standalone drivers. One of the issue is that the effective timeout value is much less than the intended value due to the way mailbox messages are queues in the mailbox framework. Since we block or serialise the shmem access anyway, there is no point in utilizing mailbox queues. The issue is fixed with exclusive lock on the channel when sending the message. The other issues is actually non-issue for upstream, but the workaround is just changing the link order of the transport drivers which enables Broadcom STB platforms to run both upstream and custom downstream kernel without any device tree changes. So pushing this to help them test upstream seamlessly as it has no practical or theoretical impact for others. There is also a fix to address possible double freeing of the name string in scmi_debugfs_common_cleanup() when devm_add_action_or_reset() fails. * tag 'scmi-fixes-6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Queue in scmi layer for mailbox implementation firmware: arm_scmi: Give SMC transport precedence over mailbox firmware: arm_scmi: Fix the double free in scmi_debugfs_common_setup() Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents aa56d75 + da1642b commit 1b59d6c

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

drivers/firmware/arm_scmi/driver.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,10 +2976,8 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
29762976
dbg->top_dentry = top_dentry;
29772977

29782978
if (devm_add_action_or_reset(info->dev,
2979-
scmi_debugfs_common_cleanup, dbg)) {
2980-
scmi_debugfs_common_cleanup(dbg);
2979+
scmi_debugfs_common_cleanup, dbg))
29812980
return NULL;
2982-
}
29832981

29842982
return dbg;
29852983
}

drivers/firmware/arm_scmi/transports/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
scmi_transport_mailbox-objs := mailbox.o
3-
obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
2+
# Keep before scmi_transport_mailbox.o to allow precedence
3+
# while matching the compatible.
44
scmi_transport_smc-objs := smc.o
55
obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o
6+
scmi_transport_mailbox-objs := mailbox.o
7+
obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
68
scmi_transport_optee-objs := optee.o
79
obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o
810
scmi_transport_virtio-objs := virtio.o

drivers/firmware/arm_scmi/transports/mailbox.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel
2626
* @cinfo: SCMI channel info
2727
* @shmem: Transmit/Receive shared memory area
28+
* @chan_lock: Lock that prevents multiple xfers from being queued
2829
*/
2930
struct scmi_mailbox {
3031
struct mbox_client cl;
@@ -33,6 +34,7 @@ struct scmi_mailbox {
3334
struct mbox_chan *chan_platform_receiver;
3435
struct scmi_chan_info *cinfo;
3536
struct scmi_shared_mem __iomem *shmem;
37+
struct mutex chan_lock;
3638
};
3739

3840
#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@@ -238,6 +240,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
238240

239241
cinfo->transport_info = smbox;
240242
smbox->cinfo = cinfo;
243+
mutex_init(&smbox->chan_lock);
241244

242245
return 0;
243246
}
@@ -267,27 +270,34 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo,
267270
struct scmi_mailbox *smbox = cinfo->transport_info;
268271
int ret;
269272

270-
ret = mbox_send_message(smbox->chan, xfer);
273+
/*
274+
* The mailbox layer has its own queue. However the mailbox queue
275+
* confuses the per message SCMI timeouts since the clock starts when
276+
* the message is submitted into the mailbox queue. So when multiple
277+
* messages are queued up the clock starts on all messages instead of
278+
* only the one inflight.
279+
*/
280+
mutex_lock(&smbox->chan_lock);
271281

272-
/* mbox_send_message returns non-negative value on success, so reset */
273-
if (ret > 0)
274-
ret = 0;
282+
ret = mbox_send_message(smbox->chan, xfer);
283+
/* mbox_send_message returns non-negative value on success */
284+
if (ret < 0) {
285+
mutex_unlock(&smbox->chan_lock);
286+
return ret;
287+
}
275288

276-
return ret;
289+
return 0;
277290
}
278291

279292
static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
280293
struct scmi_xfer *__unused)
281294
{
282295
struct scmi_mailbox *smbox = cinfo->transport_info;
283296

284-
/*
285-
* NOTE: we might prefer not to need the mailbox ticker to manage the
286-
* transfer queueing since the protocol layer queues things by itself.
287-
* Unfortunately, we have to kick the mailbox framework after we have
288-
* received our message.
289-
*/
290297
mbox_client_txdone(smbox->chan, ret);
298+
299+
/* Release channel */
300+
mutex_unlock(&smbox->chan_lock);
291301
}
292302

293303
static void mailbox_fetch_response(struct scmi_chan_info *cinfo,

0 commit comments

Comments
 (0)