summaryrefslogtreecommitdiff
path: root/drivers/mailbox/qcom-ipcc.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.com>2025-03-26 13:42:07 +0100
committerJiri Kosina <jkosina@suse.com>2025-03-26 13:42:07 +0100
commitb3cc7428a32202936904b5b07cf9f135025bafd6 (patch)
treed4a1a6180ac5939fccd92acd6f8d7d1388575c4a /drivers/mailbox/qcom-ipcc.c
parentdb52926fb0be40e1d588a346df73f5ea3a34a4c6 (diff)
parent01601fdd40ecf4467c8ae4d215dbb7d2a0599a2c (diff)
Merge branch 'for-6.15/amd_sfh' into for-linus
From: Mario Limonciello <mario.limonciello@amd.com> Some platforms include a human presence detection (HPD) sensor. When enabled and a user is detected a wake event will be emitted from the sensor fusion hub that software can react to. Example use cases are "wake from suspend on approach" or to "lock when leaving". This is currently enabled by default on supported systems, but users can't control it. This essentially means that wake on approach is enabled which is a really surprising behavior to users that don't expect it. Instead of defaulting to enabled add a sysfs knob that users can use to enable the feature if desirable and set it to disabled by default.
Diffstat (limited to 'drivers/mailbox/qcom-ipcc.c')
-rw-r--r--drivers/mailbox/qcom-ipcc.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c
index 14c7907c66326..0b17a38ea6bf5 100644
--- a/drivers/mailbox/qcom-ipcc.c
+++ b/drivers/mailbox/qcom-ipcc.c
@@ -14,6 +14,7 @@
#include <dt-bindings/mailbox/qcom-ipcc.h>
/* IPCC Register offsets */
+#define IPCC_REG_CONFIG 0x08
#define IPCC_REG_SEND_ID 0x0c
#define IPCC_REG_RECV_ID 0x10
#define IPCC_REG_RECV_SIGNAL_ENABLE 0x14
@@ -21,6 +22,7 @@
#define IPCC_REG_RECV_SIGNAL_CLEAR 0x1c
#define IPCC_REG_CLIENT_CLEAR 0x38
+#define IPCC_CLEAR_ON_RECV_RD BIT(0)
#define IPCC_SIGNAL_ID_MASK GENMASK(15, 0)
#define IPCC_CLIENT_ID_MASK GENMASK(31, 16)
@@ -274,6 +276,7 @@ static int qcom_ipcc_pm_resume(struct device *dev)
static int qcom_ipcc_probe(struct platform_device *pdev)
{
struct qcom_ipcc *ipcc;
+ u32 config_value;
static int id;
char *name;
int ret;
@@ -288,6 +291,19 @@ static int qcom_ipcc_probe(struct platform_device *pdev)
if (IS_ERR(ipcc->base))
return PTR_ERR(ipcc->base);
+ /*
+ * It is possible that boot firmware is using the same IPCC instance
+ * as of the HLOS and it has kept CLEAR_ON_RECV_RD set which basically
+ * means Interrupt pending registers are cleared when RECV_ID is read.
+ * The register automatically updates to the next pending interrupt/client
+ * status based on priority.
+ */
+ config_value = readl(ipcc->base + IPCC_REG_CONFIG);
+ if (config_value & IPCC_CLEAR_ON_RECV_RD) {
+ config_value &= ~(IPCC_CLEAR_ON_RECV_RD);
+ writel(config_value, ipcc->base + IPCC_REG_CONFIG);
+ }
+
ipcc->irq = platform_get_irq(pdev, 0);
if (ipcc->irq < 0)
return ipcc->irq;