diff options
author | Erick Reyes <erickreyes@google.com> | 2021-03-03 02:06:30 +0000 |
---|---|---|
committer | Erick Reyes <erickreyes@google.com> | 2021-03-03 20:26:39 +0000 |
commit | b8b26620b543a5789bac0e7e2636a42ed0a2f3b7 (patch) | |
tree | a41a0aea03cfe9ffdf991c565dadd1f426105b57 /drivers | |
parent | c850c0750912c2ce39959a6d2129c281e133dd17 (diff) | |
download | abrolhos-b8b26620b543a5789bac0e7e2636a42ed0a2f3b7.tar.gz |
edgetpu: prevent system suspend when clients are active
Implement minimal suspend/resume handlers to notify the system the
device cannot go to sleep state when a client is holding the firmware
wakelock.
Bug: 181578920
Signed-off-by: Erick Reyes <erickreyes@google.com>
Change-Id: I387d073c9b2a9012b84427805918d3731171e7e0
(cherry picked from commit 6438b8f6536c9383ae0e59e4a0b22de7e7063afb)
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/edgetpu/abrolhos-platform.c | 31 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-pm.c | 37 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-pm.h | 8 |
3 files changed, 73 insertions, 3 deletions
diff --git a/drivers/edgetpu/abrolhos-platform.c b/drivers/edgetpu/abrolhos-platform.c index d04c0ae..e5e9a94 100644 --- a/drivers/edgetpu/abrolhos-platform.c +++ b/drivers/edgetpu/abrolhos-platform.c @@ -28,6 +28,7 @@ #include "edgetpu-internal.h" #include "edgetpu-iremap-pool.h" #include "edgetpu-mmu.h" +#include "edgetpu-pm.h" #include "edgetpu-telemetry.h" static const struct of_device_id edgetpu_of_match[] = { @@ -360,13 +361,37 @@ static int edgetpu_platform_remove(struct platform_device *pdev) return 0; } +#if IS_ENABLED(CONFIG_PM_SLEEP) + +static int edgetpu_platform_suspend(struct device *dev) +{ + struct edgetpu_dev *etdev = dev_get_drvdata(dev); + + return edgetpu_pm_suspend(etdev); +} + +static int edgetpu_platform_resume(struct device *dev) +{ + struct edgetpu_dev *etdev = dev_get_drvdata(dev); + + return edgetpu_pm_resume(etdev); +} + +#endif /* IS_ENABLED(CONFIG_PM_SLEEP) */ + +static const struct dev_pm_ops edgetpu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(edgetpu_platform_suspend, + edgetpu_platform_resume) +}; + static struct platform_driver edgetpu_platform_driver = { .probe = edgetpu_platform_probe, .remove = edgetpu_platform_remove, .driver = { - .name = "edgetpu_platform", - .of_match_table = edgetpu_of_match, - }, + .name = "edgetpu_platform", + .of_match_table = edgetpu_of_match, + .pm = &edgetpu_pm_ops, + }, }; static int __init edgetpu_platform_init(void) diff --git a/drivers/edgetpu/edgetpu-pm.c b/drivers/edgetpu/edgetpu-pm.c index f0eb316..c29ce9e 100644 --- a/drivers/edgetpu/edgetpu-pm.c +++ b/drivers/edgetpu/edgetpu-pm.c @@ -258,3 +258,40 @@ void edgetpu_pchannel_power_up(struct edgetpu_dev *etdev) { pchannel_state_change_request(etdev, STATE_RUN); } + + +#if IS_ENABLED(CONFIG_PM_SLEEP) + +int edgetpu_pm_suspend(struct edgetpu_dev *etdev) +{ + struct edgetpu_pm *etpm = etdev->pm; + + if (!etpm) + return 0; + + if (etpm->p->power_up_count) { + etdev_warn_ratelimited( + etdev, "%s: cannot suspend with power up count = %d\n", + __func__, etpm->p->power_up_count); + return -EAGAIN; + } + + return 0; +} + +int edgetpu_pm_resume(struct edgetpu_dev *etdev) +{ + struct edgetpu_pm *etpm = etdev->pm; + + if (!etpm) + return 0; + + if (etpm->p->power_up_count) + etdev_warn_ratelimited(etdev, + "%s: resumed with power up count = %d\n", + __func__, etpm->p->power_up_count); + + return 0; +} + +#endif /* IS_ENABLED(CONFIG_PM_SLEEP) */ diff --git a/drivers/edgetpu/edgetpu-pm.h b/drivers/edgetpu/edgetpu-pm.h index 345ad29..3ec7f66 100644 --- a/drivers/edgetpu/edgetpu-pm.h +++ b/drivers/edgetpu/edgetpu-pm.h @@ -89,4 +89,12 @@ void edgetpu_pchannel_power_up(struct edgetpu_dev *etdev); int edgetpu_pchannel_power_down(struct edgetpu_dev *etdev, bool wait_on_pactive); +#if IS_ENABLED(CONFIG_PM_SLEEP) + +int edgetpu_pm_suspend(struct edgetpu_dev *etdev); + +int edgetpu_pm_resume(struct edgetpu_dev *etdev); + +#endif /* IS_ENABLED(CONFIG_PM_SLEEP) */ + #endif /* __EDGETPU_PM_H__ */ |