summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Dooley <dooleyc@google.com>2021-09-09 00:06:40 +0000
committerCraig Dooley <dooleyc@google.com>2021-09-13 18:15:15 +0000
commit64b57dbc169c48eced11ea8356cead540eff2268 (patch)
tree7d31b0633c27730eb45f3e0f7b0e715dbbe0df7e
parent6600de8aa0aa43b9dad92652f7bc756491322421 (diff)
downloadaoc-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.c50
-rw-r--r--aoc.h5
2 files changed, 54 insertions, 1 deletions
diff --git a/aoc.c b/aoc.c
index a329a3e..fb8e2cc 100644
--- a/aoc.c
+++ b/aoc.c
@@ -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;
diff --git a/aoc.h b/aoc.h
index db5f812..506e7df 100644
--- a/aoc.h
+++ b/aoc.h
@@ -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)