summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2023-12-03 18:55:11 -0800
committerSecurityBot <android-nexus-securitybot@system.gserviceaccount.com>2023-12-03 18:55:12 -0800
commita7ee00026cd3dd4457c6d9849e019ec0ca2be836 (patch)
tree8f12f7281ebfd884ee6cfb002e4368952b59e4dd
parent10bcd0e5a07ac79fc725174aaeb8ec4150d74162 (diff)
parentc69225db7dde64287e2cdb8d17472cc65324f999 (diff)
downloadaoc-a7ee00026cd3dd4457c6d9849e019ec0ca2be836.tar.gz
SBMerger: 571992243 Change-Id: Iac42b53b23a42f55678602fad8c999f8761f3e6c Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--Documentation/ABI/sysfs-devices-platform-aoc9
-rw-r--r--alsa/aoc_alsa.h1
-rw-r--r--alsa/aoc_alsa_hw.c45
-rw-r--r--aoc.c115
-rw-r--r--aoc.h2
-rw-r--r--aoc_channel_dev.c5
-rw-r--r--aoc_v1.c3
7 files changed, 92 insertions, 88 deletions
diff --git a/Documentation/ABI/sysfs-devices-platform-aoc b/Documentation/ABI/sysfs-devices-platform-aoc
new file mode 100644
index 0000000..81a5b6c
--- /dev/null
+++ b/Documentation/ABI/sysfs-devices-platform-aoc
@@ -0,0 +1,9 @@
+What: /sys/devices/platform/[0-9]+.aoc/notify_timeout_aoc_status
+Date: Nov 2023
+KernelVersion: 2.6.22
+Contact: alexiacobucci@google.com
+Description:
+ Read-only node used by AOC's kernel driver to notify userspace
+ if a request for AOC fabric to reach a certain state has timed out.
+
+Users: AOC kernel driver, aocd process in userspace.
diff --git a/alsa/aoc_alsa.h b/alsa/aoc_alsa.h
index 2ac015c..0707e05 100644
--- a/alsa/aoc_alsa.h
+++ b/alsa/aoc_alsa.h
@@ -484,6 +484,7 @@ int aoc_incall_init(void);
void aoc_incall_exit(void);
int aoc_voip_init(void);
void aoc_voip_exit(void);
+int aoc_audio_mic_mask_set(struct aoc_chip *chip, bool is_voice);
int aoc_audio_us_record(struct aoc_chip *chip, bool enable);
#endif
diff --git a/alsa/aoc_alsa_hw.c b/alsa/aoc_alsa_hw.c
index 8da92c6..db0230d 100644
--- a/alsa/aoc_alsa_hw.c
+++ b/alsa/aoc_alsa_hw.c
@@ -422,6 +422,10 @@ int aoc_audio_capture_mic_prepare(struct aoc_chip *chip)
goto exit;
}
+ /* Update mask before start capture */
+ if (mic_input_source == AP_INPUT_PROCESSOR_MIC_INPUT_INDEX)
+ aoc_audio_mic_mask_set(chip, false);
+
// CMD_AUDIO_INPUT_AP_INPUT_START_ID with mic_input_source
pr_info("mic_input_source = %d\n", mic_input_source);
@@ -2844,8 +2848,6 @@ int aoc_audio_set_params(struct aoc_alsa_stream *alsa_stream, uint32_t channels,
uint32_t samplerate, uint32_t bps, bool pcm_float_fmt, int source_mode)
{
int err = 0;
- struct aoc_chip *chip = alsa_stream->chip;
-
pr_debug("setting channels(%u), samplerate(%u), bits-per-sample(%u)\n", channels,
samplerate, bps);
@@ -2861,13 +2863,6 @@ int aoc_audio_set_params(struct aoc_alsa_stream *alsa_stream, uint32_t channels,
pr_err("ERR:%d capture audio param set fails\n", err);
goto exit;
}
-
- /* To deal with recording with spatial module enabled */
- if (chip->mic_spatial_module_enable && !aoc_pcm_is_mmap_raw(alsa_stream)) {
- err = aoc_audio_capture_spatial_module_trigger(chip, START);
- if (err < 0)
- pr_err("ERR:%d mic proc spatial module failed to start!\n", err);
- }
}
exit:
@@ -3023,6 +3018,12 @@ static int aoc_telephony_mic_open(struct aoc_chip *chip, int mic)
}
mic_input_source = hw_id_to_phone_mic_source(mic);
+
+ /* Update mask before start capture */
+ if (mic_input_source == MODEM_MIC_INPUT_INDEX ||
+ mic_input_source == MODEM_INCALL_INPUT_INDEX)
+ aoc_audio_mic_mask_set(chip, true);
+
pr_info("open telephony mic: %d - %d\n", mic_input_source, mic);
if (mic_input_source != NULL_PATH) {
err = aoc_audio_modem_mic_input(chip, START, mic_input_source);
@@ -3634,7 +3635,6 @@ int aoc_audio_open(struct aoc_alsa_stream *alsa_stream)
int aoc_audio_close(struct aoc_alsa_stream *alsa_stream)
{
- int err = 0;
struct aoc_chip *chip = alsa_stream->chip;
struct snd_pcm_substream *substream = alsa_stream->substream;
@@ -3643,14 +3643,6 @@ int aoc_audio_close(struct aoc_alsa_stream *alsa_stream)
if (alsa_stream->idx == UC_ULTRASONIC_RECORD)
ap_record_stop(chip, alsa_stream);
else if (ap_filter_capture_stream(alsa_stream)) {
- /* Disable spatial module */
- if (chip->mic_spatial_module_enable && !aoc_pcm_is_mmap_raw(alsa_stream)) {
- err = aoc_audio_capture_spatial_module_trigger(chip, STOP);
- if (err < 0)
- pr_err("ERR:%d mic proc spatial module failed to stop!\n",
- err);
- }
-
/* Stop the capturing mic*/
if (aoc_audio_capture_active_stream_num(chip) == 0) {
pr_info("%s: record stop\n", __func__);
@@ -3789,3 +3781,20 @@ int aoc_audio_set_chre_src_aec_timeout(struct aoc_chip *chip, int timeout)
return 0;
}
}
+
+/* Update PDM mic mask */
+int aoc_audio_mic_mask_set(struct aoc_chip *chip, bool is_voice)
+{
+ uint32_t value = UINT_MAX;
+ uint8_t *mask = (uint8_t *)(&value);
+ int key = is_voice, i;
+ const int cmd_id = CMD_AUDIO_INPUT_SET_PARAMETER_ID;
+ const int block = 139; /* ABLOCK_INPUT_PDM_MIC */
+ const int component = ASP_ID_NONE;
+ const int total_lists = min(NUM_OF_BUILTIN_MIC, (int)sizeof(uint32_t));
+
+ for (i = 0; i < total_lists; i++)
+ mask[i] = chip->buildin_mic_id_list[i];
+
+ return aoc_audio_set_parameters(cmd_id, block, component, key, value, chip);
+}
diff --git a/aoc.c b/aoc.c
index f6b6aaa..654306b 100644
--- a/aoc.c
+++ b/aoc.c
@@ -938,15 +938,13 @@ 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];
- size_t reason_str_len = min(MAX_RESET_REASON_STRING_LEN, count);
if (aoc_state != AOC_STATE_ONLINE || work_busy(&prvdata->watchdog_work)) {
dev_err(dev, "Reset requested while AoC is not online");
return -ENODEV;
}
- strscpy(reason_str, buf, reason_str_len);
- reason_str[reason_str_len] = '\0';
+ strscpy(reason_str, buf, sizeof(reason_str));
dev_err(dev, "Reset requested from userspace, reason: %s", reason_str);
if (prvdata->no_ap_resets) {
@@ -1016,6 +1014,14 @@ static ssize_t sensor_power_enable_store(struct device *dev,
static DEVICE_ATTR_WO(sensor_power_enable);
+static ssize_t notify_timeout_aoc_status_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return 0;
+}
+
+static DEVICE_ATTR_RO(notify_timeout_aoc_status);
+
static struct attribute *aoc_attrs[] = {
&dev_attr_firmware.attr,
&dev_attr_revision.attr,
@@ -1029,6 +1035,7 @@ static struct attribute *aoc_attrs[] = {
&dev_attr_sensor_power_enable.attr,
&dev_attr_force_reload.attr,
&dev_attr_dmic_power_enable.attr,
+ &dev_attr_notify_timeout_aoc_status.attr,
NULL
};
@@ -1571,6 +1578,7 @@ static void aoc_take_offline(struct aoc_prvdata *prvdata)
dev_err(prvdata->dev, "timed out waiting for aoc_ack\n");
if (prvdata->protected_by_gsa)
dev_err(prvdata->dev, "skipping GSA commands");
+ notify_timeout_aoc_status();
return;
}
}
@@ -1637,6 +1645,16 @@ exit:
atomic_dec(&prvdata->aoc_process_active);
}
+void notify_timeout_aoc_status(void)
+{
+ if (aoc_platform_device == NULL) {
+ pr_err("AOC platform device is undefined, can't notify aocd\n");
+ return;
+ }
+ sysfs_notify(&aoc_platform_device->dev.kobj, NULL,
+ "notify_timeout_aoc_status");
+}
+
void aoc_set_map_handler(struct aoc_service_dev *dev, aoc_map_handler handler,
void *ctx)
{
@@ -1658,21 +1676,6 @@ void aoc_remove_map_handler(struct aoc_service_dev *dev)
}
EXPORT_SYMBOL_GPL(aoc_remove_map_handler);
-static struct aoc_section_header *find_ramdump_section(struct aoc_ramdump_header
- *ramdump_header, int section_type)
-{
- int i;
-
- if (ramdump_header->num_sections != RAMDUMP_NUM_SECTIONS)
- return NULL;
-
- for (i = 0; i < ramdump_header->num_sections; i++)
- if (ramdump_header->sections[i].type == section_type)
- return &ramdump_header->sections[i];
-
- return NULL;
-}
-
static void aoc_watchdog(struct work_struct *work)
{
struct aoc_prvdata *prvdata =
@@ -1696,9 +1699,8 @@ static void aoc_watchdog(struct work_struct *work)
int sscd_rc;
char crash_info[RAMDUMP_SECTION_CRASH_INFO_SIZE];
int restart_rc;
- bool ap_reset = false, invalid_magic;
- struct aoc_section_header *crash_info_section =
- find_ramdump_section(ramdump_header, SECTION_TYPE_CRASH_INFO);
+ bool ap_reset = false, valid_magic;
+ struct aoc_section_header *crash_info_section;
prvdata->total_restarts++;
@@ -1747,18 +1749,27 @@ static void aoc_watchdog(struct work_struct *work)
ramdump_timeout = jiffies + (5 * HZ);
while (time_before(jiffies, ramdump_timeout)) {
- if (ramdump_header->valid)
+ valid_magic = memcmp(ramdump_header, RAMDUMP_MAGIC, sizeof(RAMDUMP_MAGIC)) == 0;
+ if (ramdump_header->valid == 1 && valid_magic)
break;
msleep(100);
}
- if (!ramdump_header->valid) {
- dev_err(prvdata->dev, "aoc coredump timed out, coredump only contains DRAM\n");
+ crash_info_section = &ramdump_header->sections[RAMDUMP_SECTION_CRASH_INFO_INDEX];
+ if (crash_info_section->type != SECTION_TYPE_CRASH_INFO)
+ crash_info_section = NULL;
+
+ if (!(ramdump_header->valid == 1) || !valid_magic) {
+ if (!(ramdump_header->valid == 1))
+ dev_info(prvdata->dev, "aoc coredump timed out, coredump only contains DRAM\n");
+ if (!valid_magic)
+ dev_info(prvdata->dev, "aoc coredump has invalid magic\n");
+
if (crash_info_section) {
const char *crash_reason = (const char *)ramdump_header +
crash_info_section->offset;
- bool crash_reason_valid = (strnlen(crash_reason,
- sizeof(crash_info)) != 0);
+ bool crash_reason_valid = crash_reason < (char *)prvdata->dram_virt +
+ prvdata->dram_size && crash_reason[0] != 0;
snprintf(crash_info, sizeof(crash_info),
"AoC watchdog : %s (incomplete %u:%u)",
@@ -1772,31 +1783,17 @@ static void aoc_watchdog(struct work_struct *work)
}
}
- invalid_magic = memcmp(ramdump_header, RAMDUMP_MAGIC, sizeof(RAMDUMP_MAGIC));
- if (ramdump_header->valid && invalid_magic) {
- dev_err(prvdata->dev,
- "aoc coredump possibly failed: invalid magic\n");
- if (crash_info_section) {
+ if (ramdump_header->valid == 1 && valid_magic) {
+ if (crash_info_section && crash_info_section->flags & RAMDUMP_FLAG_VALID) {
const char *crash_reason = (const char *)ramdump_header +
crash_info_section->offset;
- /* Check that offset was not corrupted and that we are not reading
- random bytes */
- bool crash_reason_valid = crash_reason < (char *)prvdata->dram_virt +
- prvdata->dram_size && crash_reason[0] != 0;
-
- if (crash_reason_valid) {
- snprintf(crash_info, sizeof(crash_info),
- "AoC watchdog : coredump corrupt [%s]", crash_reason);
- } else {
- snprintf(crash_info, sizeof(crash_info),
- "AoC watchdog : coredump corrupt (incomplete %u:%u)",
- ramdump_header->breadcrumbs[0],
- ramdump_header->breadcrumbs[1]);
- }
+ dev_info(prvdata->dev,
+ "aoc coredump has valid coredump header, crash reason [%s]", crash_reason);
+ strscpy(crash_info, crash_reason, sizeof(crash_info));
} else {
- dev_err(prvdata->dev,
- "could not find crash info section in aoc coredump header");
- strscpy(crash_info, "AoC Watchdog : coredump corrupt",
+ dev_info(prvdata->dev,
+ "aoc coredump has valid coredump header, but invalid crash reason");
+ strscpy(crash_info, "AoC Watchdog : invalid crash info",
sizeof(crash_info));
}
}
@@ -1824,27 +1821,6 @@ static void aoc_watchdog(struct work_struct *work)
sscd_info.segs[0].addr = prvdata->dram_virt;
}
- if (ramdump_header->valid && !invalid_magic) {
-
- if (crash_info_section && crash_info_section->flags & RAMDUMP_FLAG_VALID) {
- const char *crash_reason = (const char *)ramdump_header +
- crash_info_section->offset;
- bool crash_reason_valid = crash_reason < (char *)prvdata->dram_virt +
- prvdata->dram_size && crash_reason[0] != 0;
-
- if (crash_reason_valid)
- pr_err(">>> valid!!");
- else
- pr_err(">>> invalid!!!");
- dev_info(prvdata->dev, "aoc coredump has valid coredump header, crash reason [%s]",
- crash_reason);
- strscpy(crash_info, crash_reason, sizeof(crash_info));
- } else {
- dev_info(prvdata->dev, "aoc coredump has valid coredump header, but invalid crash reason");
- strscpy(crash_info, "AoC Watchdog : invalid crash info",
- sizeof(crash_info));
- }
- }
if (ap_reset) {
/* Prefer the user specified reason */
@@ -2553,6 +2529,7 @@ err_memnode:
err_chardev:
err_failed_prvdata_alloc:
err_invalid_dt:
+ aoc_platform_device = NULL;
err_platform_not_null:
return rc;
}
diff --git a/aoc.h b/aoc.h
index 44b4539..2dc2e8a 100644
--- a/aoc.h
+++ b/aoc.h
@@ -287,6 +287,8 @@ u32 dt_property(struct device_node *node, const char *key);
void configure_crash_interrupts(struct aoc_prvdata *prvdata, bool enable);
+void notify_timeout_aoc_status(void);
+
#define AOC_SERVICE_NAME_LENGTH 32
/* Rings should have the ring flag set, slots = 1, size = ring size
diff --git a/aoc_channel_dev.c b/aoc_channel_dev.c
index 396b8ab..8e0a513 100644
--- a/aoc_channel_dev.c
+++ b/aoc_channel_dev.c
@@ -70,6 +70,8 @@ static const char * const channel_service_names[] = {
"com.google.usf.non_wake_up",
"com.google.chre",
"com.google.chre.non_wake_up",
+ "com.google.bt",
+ "com.google.bt.non_wake_up",
"usf_sh_mem_doorbell",
NULL,
};
@@ -209,7 +211,8 @@ static int aocc_demux_kthread(void *data)
handler_found = 1;
if (!node->msg.non_wake_up &&
(strcmp(dev_name(&service->dev),"com.google.usf") == 0 ||
- strcmp(dev_name(&service->dev),"com.google.chre") == 0)) {
+ strcmp(dev_name(&service->dev),"com.google.chre") == 0 ||
+ strcmp(dev_name(&service->dev),"com.google.bt") == 0)) {
take_wake_lock = true;
}
diff --git a/aoc_v1.c b/aoc_v1.c
index 1147c43..e67937f 100644
--- a/aoc_v1.c
+++ b/aoc_v1.c
@@ -142,6 +142,7 @@ int aoc_watchdog_restart(struct aoc_prvdata *prvdata,
aoc_req_rc = wait_for_aoc_status(prvdata, true);
if (aoc_req_rc) {
dev_err(prvdata->dev, "timed out waiting for aoc_ack\n");
+ notify_timeout_aoc_status();
continue;
}
dev_info(prvdata->dev, "resetting aoc\n");
@@ -174,6 +175,8 @@ int aoc_watchdog_restart(struct aoc_prvdata *prvdata,
if (aoc_req_rc && *(aoc_module_params->aoc_panic_on_req_timeout)) {
dev_err(prvdata->dev, "timed out too many times waiting for aoc_ack, triggering kernel panic\n");
+ /* Sleep to ensure aocd can process notification of timeout before panic */
+ msleep(1000);
panic("AoC kernel panic: timed out waiting for aoc_ack");
}