diff options
author | Neela Chithirala <chithiralan@google.com> | 2022-01-17 04:41:54 +0000 |
---|---|---|
committer | Neela Chithirala <chithiralan@google.com> | 2022-02-03 06:27:20 +0000 |
commit | 3ccb2479717de3089dbbcb894ddd045b2ddc256c (patch) | |
tree | a577f284ff42d11b1fcfb7c338a7f0b59b10672a /gxp-wakelock.c | |
parent | e14069f1739b05c7a7f60ae73c8ce14b91ef12e0 (diff) | |
download | gs201-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.c | 128 |
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; +} |