summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuan-Yu Lin <guanyulin@google.com>2023-09-12 18:04:01 +0800
committerAlex Iacobucci <alexiacobucci@google.com>2024-02-27 00:32:07 +0000
commite537f38acba686723e0e611782726a9958b349b6 (patch)
treec773ee07a3338bc37be461b214190055fa11f215
parentdaf4829f21691fa7954bd90df61d005a8f83a7e0 (diff)
downloadaoc-e537f38acba686723e0e611782726a9958b349b6.tar.gz
aoc: add new a state to indicate aoc ssr
Add a new state to indicate AoC is under SSR. This prevents other drivers access aoc services during AoC SSR. Bug: 298015705 Test: Local AoC SSR multiple times. Change-Id: I615adf38f7ae3f64ee076d11d4b5e59d6cb3d8e9 Signed-off-by: Guan-Yu Lin <guanyulin@google.com> (cherry picked from commit 3b2398053ecdd6f4c74a3d0bdd55decc36063ba8)
-rw-r--r--aoc.c14
-rw-r--r--aoc.h3
-rw-r--r--aoc_service_core.c10
-rw-r--r--aoc_v1.c2
4 files changed, 16 insertions, 13 deletions
diff --git a/aoc.c b/aoc.c
index 2079a80..bb5da79 100644
--- a/aoc.c
+++ b/aoc.c
@@ -854,7 +854,7 @@ static ssize_t services_show(struct device *dev, struct device_attribute *attr,
int i;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work))
+ if (aoc_state != AOC_STATE_ONLINE)
goto exit;
ret += scnprintf(buf, PAGE_SIZE, "Services : %d\n", services);
@@ -941,7 +941,7 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
struct aoc_prvdata *prvdata = dev_get_drvdata(dev);
char reason_str[MAX_RESET_REASON_STRING_LEN + 1];
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
+ if (aoc_state != AOC_STATE_ONLINE) {
dev_err(dev, "Reset requested while AoC is not online");
return -ENODEV;
}
@@ -978,7 +978,6 @@ static ssize_t force_reload_store(struct device *dev, struct device_attribute *a
strlcpy(prvdata->ap_reset_reason, "Force Reload AoC", AP_RESET_REASON_LENGTH);
prvdata->ap_triggered_reset = true;
-
schedule_work(&prvdata->watchdog_work);
return count;
@@ -1550,7 +1549,7 @@ static void aoc_take_offline(struct aoc_prvdata *prvdata)
int rc;
/* check if devices/services are ready */
- if (aoc_state == AOC_STATE_ONLINE) {
+ if (aoc_state == AOC_STATE_ONLINE || aoc_state == AOC_STATE_SSR) {
pr_notice("taking aoc offline\n");
aoc_state = AOC_STATE_OFFLINE;
@@ -1615,7 +1614,7 @@ static void aoc_process_services(struct aoc_prvdata *prvdata, int offset)
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work))
+ if (aoc_state != AOC_STATE_ONLINE)
goto exit;
services = aoc_num_services();
@@ -1701,6 +1700,7 @@ static void aoc_watchdog(struct work_struct *work)
bool ap_reset = false, valid_magic;
struct aoc_section_header *crash_info_section;
+ aoc_state = AOC_STATE_SSR;
prvdata->total_restarts++;
/* Initialize crash_info[0] to identify if it has changed later in the function. */
@@ -2191,7 +2191,7 @@ static int aoc_core_suspend(struct device *dev)
int i = 0;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work))
+ if (aoc_state != AOC_STATE_ONLINE)
goto exit;
for (i = 0; i < total_services; i++) {
@@ -2214,7 +2214,7 @@ static int aoc_core_resume(struct device *dev)
int i = 0;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work))
+ if (aoc_state != AOC_STATE_ONLINE)
goto exit;
for (i = 0; i < total_services; i++) {
diff --git a/aoc.h b/aoc.h
index 81616b6..df4f9d6 100644
--- a/aoc.h
+++ b/aoc.h
@@ -52,7 +52,8 @@ enum AOC_FW_STATE {
AOC_STATE_OFFLINE,
AOC_STATE_FIRMWARE_LOADED,
AOC_STATE_STARTING,
- AOC_STATE_ONLINE
+ AOC_STATE_ONLINE,
+ AOC_STATE_SSR
};
struct mbox_slot {
diff --git a/aoc_service_core.c b/aoc_service_core.c
index 846cea5..c180865 100644
--- a/aoc_service_core.c
+++ b/aoc_service_core.c
@@ -37,7 +37,7 @@ ssize_t aoc_service_read_timeout(struct aoc_service_dev *dev, uint8_t *buffer,
return -ENODEV;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
+ if (aoc_state != AOC_STATE_ONLINE) {
ret = -EBUSY;
goto err;
}
@@ -132,7 +132,7 @@ ssize_t aoc_service_write(struct aoc_service_dev *dev, const uint8_t *buffer,
return -EINVAL;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
+ if (aoc_state != AOC_STATE_ONLINE) {
ret = -EBUSY;
goto err;
}
@@ -223,7 +223,7 @@ ssize_t aoc_service_write_timeout(struct aoc_service_dev *dev, const uint8_t *bu
return -ENODEV;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
+ if (aoc_state != AOC_STATE_ONLINE) {
ret = -EBUSY;
goto err;
}
@@ -438,7 +438,7 @@ ssize_t aoc_service_read(struct aoc_service_dev *dev, uint8_t *buffer,
return -ENODEV;
atomic_inc(&prvdata->aoc_process_active);
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
+ if (aoc_state != AOC_STATE_ONLINE) {
ret = -EBUSY;
goto err;
}
@@ -528,7 +528,7 @@ bool aoc_online_state(struct aoc_service_dev *dev)
if (!prvdata)
return false;
- if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work))
+ if (aoc_state != AOC_STATE_ONLINE)
return false;
return true;
}
diff --git a/aoc_v1.c b/aoc_v1.c
index 93045b3..58572d2 100644
--- a/aoc_v1.c
+++ b/aoc_v1.c
@@ -25,6 +25,7 @@
#define SSMT_NS_READ_PID(n) (0x4000 + 4 * (n))
#define SSMT_NS_WRITE_PID(n) (0x4200 + 4 * (n))
+extern enum AOC_FW_STATE aoc_state;
extern struct platform_device *aoc_platform_device;
extern struct resource *aoc_sram_resource;
extern struct mutex aoc_service_lock;
@@ -441,6 +442,7 @@ static irqreturn_t watchdog_int_handler(int irq, void *dev)
/* AP shouldn't access AoC registers to clear the IRQ. */
/* Mask the IRQ until the IRQ gets cleared by AoC reset during SSR. */
disable_irq_nosync(irq);
+ aoc_state = AOC_STATE_SSR;
schedule_work(&prvdata->watchdog_work);
return IRQ_HANDLED;