summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/arm_ffa/driver.c13
-rw-r--r--drivers/firmware/arm_scmi/common.h2
-rw-r--r--drivers/firmware/arm_scmi/driver.c4
-rw-r--r--drivers/firmware/arm_scmi/protocols.h2
-rw-r--r--drivers/firmware/arm_scmi/transports/Makefile6
-rw-r--r--drivers/firmware/arm_scmi/transports/mailbox.c32
-rw-r--r--drivers/firmware/dmi_scan.c2
-rw-r--r--drivers/firmware/efi/fdtparams.c2
-rw-r--r--drivers/firmware/efi/libstub/riscv-stub.c2
-rw-r--r--drivers/firmware/efi/libstub/riscv.c2
-rw-r--r--drivers/firmware/efi/libstub/zboot.c2
-rw-r--r--drivers/firmware/sysfb.c4
12 files changed, 45 insertions, 28 deletions
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 4d231bc375e0..b14cbdae94e8 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -481,11 +481,16 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
struct ffa_send_direct_data2 *data)
{
u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+ union {
+ uuid_t uuid;
+ __le64 regs[2];
+ } uuid_regs = { .uuid = *uuid };
ffa_value_t ret, args = {
- .a0 = FFA_MSG_SEND_DIRECT_REQ2, .a1 = src_dst_ids,
+ .a0 = FFA_MSG_SEND_DIRECT_REQ2,
+ .a1 = src_dst_ids,
+ .a2 = le64_to_cpu(uuid_regs.regs[0]),
+ .a3 = le64_to_cpu(uuid_regs.regs[1]),
};
-
- export_uuid((u8 *)&args.a2, uuid);
memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data));
invoke_ffa_fn(args, &ret);
@@ -496,7 +501,7 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
return ffa_to_linux_errno((int)ret.a2);
if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) {
- memcpy(data, &ret.a4, sizeof(*data));
+ memcpy(data, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*data));
return 0;
}
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 6d9227db473f..c4b8e7ff88aa 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -22,7 +22,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include "protocols.h"
#include "notify.h"
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 88c5c4ff4bb6..a477b5ade38d 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2976,10 +2976,8 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
dbg->top_dentry = top_dentry;
if (devm_add_action_or_reset(info->dev,
- scmi_debugfs_common_cleanup, dbg)) {
- scmi_debugfs_common_cleanup(dbg);
+ scmi_debugfs_common_cleanup, dbg))
return NULL;
- }
return dbg;
}
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 8e95f53bd7b7..aaee57cdcd55 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -22,7 +22,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0)
#define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16)
diff --git a/drivers/firmware/arm_scmi/transports/Makefile b/drivers/firmware/arm_scmi/transports/Makefile
index 362a406f08e6..3ba3d3bee151 100644
--- a/drivers/firmware/arm_scmi/transports/Makefile
+++ b/drivers/firmware/arm_scmi/transports/Makefile
@@ -1,8 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
-scmi_transport_mailbox-objs := mailbox.o
-obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
+# Keep before scmi_transport_mailbox.o to allow precedence
+# while matching the compatible.
scmi_transport_smc-objs := smc.o
obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o
+scmi_transport_mailbox-objs := mailbox.o
+obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
scmi_transport_optee-objs := optee.o
obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o
scmi_transport_virtio-objs := virtio.o
diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c
index 1a754dee24f7..e3d5f7560990 100644
--- a/drivers/firmware/arm_scmi/transports/mailbox.c
+++ b/drivers/firmware/arm_scmi/transports/mailbox.c
@@ -25,6 +25,7 @@
* @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
+ * @chan_lock: Lock that prevents multiple xfers from being queued
*/
struct scmi_mailbox {
struct mbox_client cl;
@@ -33,6 +34,7 @@ struct scmi_mailbox {
struct mbox_chan *chan_platform_receiver;
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
+ struct mutex chan_lock;
};
#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,
cinfo->transport_info = smbox;
smbox->cinfo = cinfo;
+ mutex_init(&smbox->chan_lock);
return 0;
}
@@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo,
struct scmi_mailbox *smbox = cinfo->transport_info;
int ret;
- ret = mbox_send_message(smbox->chan, xfer);
+ /*
+ * The mailbox layer has its own queue. However the mailbox queue
+ * confuses the per message SCMI timeouts since the clock starts when
+ * the message is submitted into the mailbox queue. So when multiple
+ * messages are queued up the clock starts on all messages instead of
+ * only the one inflight.
+ */
+ mutex_lock(&smbox->chan_lock);
- /* mbox_send_message returns non-negative value on success, so reset */
- if (ret > 0)
- ret = 0;
+ ret = mbox_send_message(smbox->chan, xfer);
+ /* mbox_send_message returns non-negative value on success */
+ if (ret < 0) {
+ mutex_unlock(&smbox->chan_lock);
+ return ret;
+ }
- return ret;
+ return 0;
}
static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
@@ -281,13 +294,10 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
{
struct scmi_mailbox *smbox = cinfo->transport_info;
- /*
- * NOTE: we might prefer not to need the mailbox ticker to manage the
- * transfer queueing since the protocol layer queues things by itself.
- * Unfortunately, we have to kick the mailbox framework after we have
- * received our message.
- */
mbox_client_txdone(smbox->chan, ret);
+
+ /* Release channel */
+ mutex_unlock(&smbox->chan_lock);
}
static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 23b002e4d4a0..fde0656481cc 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -9,7 +9,7 @@
#include <linux/memblock.h>
#include <linux/random.h>
#include <asm/dmi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#ifndef SMBIOS_ENTRY_POINT_SCAN_START
#define SMBIOS_ENTRY_POINT_SCAN_START 0xF0000
diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c
index 0ec83ba58097..b815d2a754ee 100644
--- a/drivers/firmware/efi/fdtparams.c
+++ b/drivers/firmware/efi/fdtparams.c
@@ -8,7 +8,7 @@
#include <linux/libfdt.h>
#include <linux/of_fdt.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
enum {
SYSTAB,
diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c
index c96d6dcee86c..e7d9204baee3 100644
--- a/drivers/firmware/efi/libstub/riscv-stub.c
+++ b/drivers/firmware/efi/libstub/riscv-stub.c
@@ -7,7 +7,7 @@
#include <asm/efi.h>
#include <asm/sections.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include "efistub.h"
diff --git a/drivers/firmware/efi/libstub/riscv.c b/drivers/firmware/efi/libstub/riscv.c
index 8022b104c3e6..f66f33ceb99e 100644
--- a/drivers/firmware/efi/libstub/riscv.c
+++ b/drivers/firmware/efi/libstub/riscv.c
@@ -7,7 +7,7 @@
#include <linux/libfdt.h>
#include <asm/efi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include "efistub.h"
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 1ceace956758..af23b3c50228 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -3,7 +3,7 @@
#include <linux/efi.h>
#include <linux/pe.h>
#include <asm/efi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include "efistub.h"
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 02a07d3d0d40..a3df782fa687 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -67,9 +67,11 @@ static bool sysfb_unregister(void)
void sysfb_disable(struct device *dev)
{
struct screen_info *si = &screen_info;
+ struct device *parent;
mutex_lock(&disable_lock);
- if (!dev || dev == sysfb_parent_dev(si)) {
+ parent = sysfb_parent_dev(si);
+ if (!dev || !parent || dev == parent) {
sysfb_unregister();
disabled = true;
}