summaryrefslogtreecommitdiff
path: root/gxp-wakelock.c
diff options
context:
space:
mode:
authorNeela Chithirala <chithiralan@google.com>2022-01-17 04:41:54 +0000
committerNeela Chithirala <chithiralan@google.com>2022-02-03 06:27:20 +0000
commit3ccb2479717de3089dbbcb894ddd045b2ddc256c (patch)
treea577f284ff42d11b1fcfb7c338a7f0b59b10672a /gxp-wakelock.c
parente14069f1739b05c7a7f60ae73c8ce14b91ef12e0 (diff)
downloadgs201-3ccb2479717de3089dbbcb894ddd045b2ddc256c.tar.gz
Merge branch 'gs201-release' to android13-gs-pixel-5.10
* gs201-release: gxp: Fix multicore VDs not shutting down clean Bug: 215303765 gxp: Rework VD locking and remove mailbox locking Bug: 189018271 gxp: initial commit for thermal driver Bug: 177217526 gxp: Add wakelock interface and make debugfs wakelock aware Bug: 215192870 gxp: Hook-up pm ops for driver suspend/resume Bug: 204924965 gxp: Dynamically power BLK_AUR on and off Bug: 204924965 gxp: support GXP_PLATFORM=GEM5 Bug: 204942713 gxp: Remove delay waiting for FW mailbox init Bug: 207037428 gxp: Fix infrequent crash during mailbox release gxp: Release FW file on firmware loading errors gxp: return GXP_RESP_CANCELLED if timeout occurs Bug: 207432733 gxp: Remove initial 10ms delay when disabling telemetry gxp: Cast telemetry buffer IOVAs to u32s before use gxp: check sscoredump by CONFIG_SUBSYSTEM_COREDUMP gxp: Fix double-lock hang in gxp_telemetry_vma_close gxp: Log driver git commit hash on probe Bug: 206744969 gxp: Add ioctl for reading the TOP global counter gxp: Implement eventfd signalling for telemetry gxp: Notify running cores of telemetry state changes gxp: Add notification interface Signed-off-by: Neela Chithirala <chithiralan@google.com> Change-Id: Ic7cd7b81ee643371c600ac208ae33d6344ed7f1b
Diffstat (limited to 'gxp-wakelock.c')
-rw-r--r--gxp-wakelock.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/gxp-wakelock.c b/gxp-wakelock.c
new file mode 100644
index 0000000..feb5c88
--- /dev/null
+++ b/gxp-wakelock.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GXP wakelock support
+ *
+ * Copyright (C) 2022 Google LLC
+ */
+
+#include "gxp-dma.h"
+#include "gxp-pm.h"
+#include "gxp-wakelock.h"
+
+int gxp_wakelock_init(struct gxp_dev *gxp)
+{
+ struct gxp_wakelock_manager *mgr;
+
+ mgr = devm_kzalloc(gxp->dev, sizeof(*mgr), GFP_KERNEL);
+ if (!mgr)
+ return -ENOMEM;
+
+ mutex_init(&mgr->lock);
+
+ gxp->wakelock_mgr = mgr;
+
+ return 0;
+}
+
+int gxp_wakelock_acquire(struct gxp_dev *gxp)
+{
+ struct gxp_wakelock_manager *mgr = gxp->wakelock_mgr;
+ int ret = 0;
+
+ mutex_lock(&mgr->lock);
+
+ if (mgr->suspended) {
+ /*
+ * Don't allow a new client to obtain a wakelock, powering up
+ * BLK_AUR, when the system is going to sleep.
+ */
+ dev_warn(gxp->dev,
+ "Attempt to obtain wakelock while suspending.\n");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ if (!mgr->count++) {
+ ret = gxp_pm_blk_on(gxp);
+ if (ret) {
+ dev_err(gxp->dev,
+ "Failed to power on BLK_AUR (ret=%d, client count=%u)\n",
+ ret, mgr->count);
+ goto err_blk_on;
+ }
+
+ ret = gxp_dma_ssmt_program(gxp);
+ if (ret) {
+ dev_err(gxp->dev,
+ "Failed to program SSMTs after powering on BLK_AUR (ret=%d)\n",
+ ret);
+ goto err_ssmt_program;
+ }
+ }
+
+out:
+ mutex_unlock(&mgr->lock);
+
+ return ret;
+
+err_ssmt_program:
+ gxp_pm_blk_off(gxp);
+err_blk_on:
+ mgr->count--;
+ mutex_unlock(&mgr->lock);
+ return ret;
+}
+
+void gxp_wakelock_release(struct gxp_dev *gxp)
+{
+ struct gxp_wakelock_manager *mgr = gxp->wakelock_mgr;
+ int ret = 0;
+
+ mutex_lock(&mgr->lock);
+
+ if (!mgr->count) {
+ dev_err(gxp->dev,
+ "Attempt to release wakelock with none held.\n");
+ goto out;
+ }
+
+ if (!--mgr->count) {
+ ret = gxp_pm_blk_off(gxp);
+ if (ret)
+ dev_err(gxp->dev,
+ "Failed to power down BLK_AUR (ret=%d, client count=%u)\n",
+ ret, mgr->count);
+ }
+
+out:
+ mutex_unlock(&mgr->lock);
+}
+
+int gxp_wakelock_suspend(struct gxp_dev *gxp)
+{
+ struct gxp_wakelock_manager *mgr = gxp->wakelock_mgr;
+ int ret;
+
+ mutex_lock(&mgr->lock);
+
+ /* Can't suspend if there are any active clients */
+ mgr->suspended = mgr->count == 0;
+ ret = mgr->suspended ? 0 : -EAGAIN;
+
+ mutex_unlock(&mgr->lock);
+
+ return ret;
+}
+
+int gxp_wakelock_resume(struct gxp_dev *gxp)
+{
+ struct gxp_wakelock_manager *mgr = gxp->wakelock_mgr;
+
+ mutex_lock(&mgr->lock);
+
+ mgr->suspended = false;
+
+ mutex_unlock(&mgr->lock);
+
+ return 0;
+}