diff options
author | Craig Dooley <dooleyc@google.com> | 2021-09-09 00:06:40 +0000 |
---|---|---|
committer | Craig Dooley <dooleyc@google.com> | 2021-09-13 18:15:15 +0000 |
commit | 64b57dbc169c48eced11ea8356cead540eff2268 (patch) | |
tree | 7d31b0633c27730eb45f3e0f7b0e715dbbe0df7e | |
parent | 6600de8aa0aa43b9dad92652f7bc756491322421 (diff) | |
download | aoc-64b57dbc169c48eced11ea8356cead540eff2268.tar.gz |
Log services that have written messages while the AP is asleep
Bug: 197748952
Signed-off-by: Craig Dooley <dooleyc@google.com>
Change-Id: I5097efa2812b52e160d83db228991afe336f700b
-rw-r--r-- | aoc.c | 50 | ||||
-rw-r--r-- | aoc.h | 5 |
2 files changed, 54 insertions, 1 deletions
@@ -207,6 +207,14 @@ static bool aoc_autoload_firmware; module_param(aoc_autoload_firmware, bool, 0644); MODULE_PARM_DESC(aoc_autoload_firmware, "Automatically load firmware if true"); +static int aoc_core_suspend(struct device *dev); +static int aoc_core_resume(struct device *dev); + +const static struct dev_pm_ops aoc_core_pm_ops = { + .suspend = aoc_core_suspend, + .resume = aoc_core_resume, +}; + static int aoc_bus_match(struct device *dev, struct device_driver *drv); static int aoc_bus_probe(struct device *dev); static int aoc_bus_remove(struct device *dev); @@ -1688,6 +1696,7 @@ static struct platform_driver aoc_driver = { .driver = { .name = "aoc", .owner = THIS_MODULE, + .pm = &aoc_core_pm_ops, .of_match_table = of_match_ptr(aoc_match), }, }; @@ -1840,6 +1849,9 @@ static struct aoc_service_dev *create_service_device(struct aoc_prvdata *prvdata dev->ipc_base = prvdata->ipc_base; dev->dead = false; + if (aoc_service_is_queue(s)) + dev->wake_capable = true; + init_waitqueue_head(&dev->read_queue); init_waitqueue_head(&dev->write_queue); @@ -2746,6 +2758,44 @@ static int find_gsa_device(struct aoc_prvdata *prvdata) prvdata); } +static int aoc_core_suspend(struct device *dev) +{ + struct aoc_prvdata *prvdata = dev_get_drvdata(dev); + size_t total_services = aoc_num_services(); + int i = 0; + + for (i = 0; i < total_services; i++) { + struct aoc_service_dev *s = service_dev_at_index(prvdata, i); + + if (s->wake_capable) + s->suspend_rx_count = aoc_service_slots_available_to_read(s->service, + AOC_UP); + } + + return 0; +} + +static int aoc_core_resume(struct device *dev) +{ + struct aoc_prvdata *prvdata = dev_get_drvdata(dev); + size_t total_services = aoc_num_services(); + int i = 0; + + for (i = 0; i < total_services; i++) { + struct aoc_service_dev *s = service_dev_at_index(prvdata, i); + + if (s->wake_capable) { + size_t available = aoc_service_slots_available_to_read(s->service, AOC_UP); + + if (available != s->suspend_rx_count) + dev_notice(dev, "Service \"%s\" has %zu messages to read on wake\n", + dev_name(&s->dev), available); + } + } + + return 0; +} + static int aoc_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -28,10 +28,13 @@ struct aoc_service_dev { void *ipc_base; aoc_service_dev_handler handler; void *prvdata; + uint64_t suspend_rx_count; - bool dead; uint8_t mbox_index; uint8_t service_index; + + bool dead; + bool wake_capable; }; #define AOC_DEVICE(_d) container_of((_d), struct aoc_service_dev, dev) |