summaryrefslogtreecommitdiff
path: root/lwis_device_test.c
diff options
context:
space:
mode:
authorWill McVicker <willmcvicker@google.com>2024-04-15 11:14:18 -0700
committerWill McVicker <willmcvicker@google.com>2024-04-15 11:19:24 -0700
commit951a7837ea2391035fe384a81b14748d093926b6 (patch)
tree821286663e7ba94b7dd5db4b6da28b1edb3cbf19 /lwis_device_test.c
parente5d0b690ab61ca932240b5a77b05214397112a7a (diff)
parente93b073b2f1f5f9a0c479714efceb9ac78c027cd (diff)
downloadlwis-951a7837ea2391035fe384a81b14748d093926b6.tar.gz
Merge aosp/android-gs-raviole-5.10-android14-qpr2 into aosp/android14-gs-pixel-6.1android14-gs-pixel-6.1
* aosp/android-gs-raviole-5.10-android14-qpr2: LWIS: fix race condition LWIS: Fix spinlock flags are overwritten by the nested using LWIS: Add mutex lock to I2C process queue LWIS: Check transaction limit based on flag LWIS: Fix race condition while disabling device LWIS: Transactions optimizations LWIS: Handle device flush for transactions with limit LWIS: Move transaction limit logging LWIS: Update read buffer pointer LWIS: Fix the processing end limit for transactions LWIS: Update the trace information LWIS: Pass irq state to correctly restore transaction lock LWIS: Fix use of transaction pointer after free LWIS: Fix transaction free Add entry processing limit for queued transactions LWIS: Fix memory leak Revert^2 "Optimize I2C Bus manager scheduling" Revert^3 "Revert "LWIS: Implement I2C Bus Manager"" Revert^2 "Revert "LWIS: Implement I2C Bus Manager"" Revert "Optimize I2C Bus manager scheduling" Optimize I2C Bus manager scheduling Revert "Revert "LWIS: Implement I2C Bus Manager"" Revert "LWIS: Implement I2C Bus Manager" LWIS: Implement I2C Bus Manager Top: Use GFP_ATOMIC flag in kmalloc IOEntry: Allow max wait time of 1 second IO Entry: Support Wait and Poll in short interval functions Debug: Fix formatting on dump state logs I2C: Remove redundant parameter in lwis_i2c_io_entry_rw LWIS: Remove fence enable flag LWIS: Remove partial fence enable flag LWIS: Remove bts block name enable flag LWIS: Allow user input GFP flags for different use cases Revert "LWIS: print cleanup transaction read result" LWIS: Use IS_ERR_OR_NULL instead of IS_ERR LWIS: Reset variables when error LWIS: implement the fake injection in Kernel side Transaction: Add debug parameter to skip transaction timestamping Fix formatting. LWIS: test infra refactor: implement the lwis_test device read the interrupt info from dts tree. LWIS: Fix stack size warning LWIS: Add a new command for current LWIS_BTS_BLOCK_NAME_ENABLED on LWIS: Remove partial bts block name enable flag LWIS: test infra refactor: add more functions for lwis-test device. LWIS: do not update BTS for unsupported devices LWIS: Clean up TODO for flash driver Top: Fix lwis_top_event_subscribe() UAF Change-Id: I0844e4e5efd56eb6e97cdc90eabbf1531ae0609e Signed-off-by: Will McVicker <willmcvicker@google.com>
Diffstat (limited to 'lwis_device_test.c')
-rw-r--r--lwis_device_test.c134
1 files changed, 129 insertions, 5 deletions
diff --git a/lwis_device_test.c b/lwis_device_test.c
index 75fd4dc..31b9ce5 100644
--- a/lwis_device_test.c
+++ b/lwis_device_test.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include "lwis_commands.h"
+#include "lwis_device.h"
#include "lwis_init.h"
#include "lwis_platform.h"
@@ -26,11 +27,16 @@
#define LWIS_DRIVER_NAME "lwis-test"
+static int lwis_test_device_enable(struct lwis_device *lwis_dev);
+static int lwis_test_device_disable(struct lwis_device *lwis_dev);
+static int lwis_test_register_io(struct lwis_device *lwis_dev, struct lwis_io_entry *entry,
+ int access_size);
+
static struct lwis_device_subclass_operations test_vops = {
- .register_io = NULL,
+ .register_io = lwis_test_register_io,
.register_io_barrier = NULL,
- .device_enable = NULL,
- .device_disable = NULL,
+ .device_enable = lwis_test_device_enable,
+ .device_disable = lwis_test_device_disable,
.event_enable = NULL,
.event_flags_updated = NULL,
.close = NULL,
@@ -43,6 +49,108 @@ static struct lwis_event_subscribe_operations test_subscribe_ops = {
.release = NULL,
};
+static int lwis_test_device_enable(struct lwis_device *lwis_dev)
+{
+ return 0;
+}
+
+static int lwis_test_device_disable(struct lwis_device *lwis_dev)
+{
+ return 0;
+}
+
+static int lwis_test_register_io(struct lwis_device *lwis_dev, struct lwis_io_entry *entry,
+ int access_size)
+{
+ struct lwis_test_device *test_dev =
+ container_of(lwis_dev, struct lwis_test_device, base_dev);
+ struct lwis_io_entry_rw_batch *rw_batch;
+ int i;
+ uint64_t reg_value;
+
+ if (!entry) {
+ dev_err(test_dev->base_dev.dev, "IO entry is NULL.\n");
+ return -EINVAL;
+ }
+
+ lwis_save_register_io_info(lwis_dev, entry, access_size);
+
+ if (entry->type == LWIS_IO_ENTRY_READ) {
+ if (entry->rw.offset >= SCRATCH_TEST_DEV_MEMORY_SIZE) {
+ dev_err(test_dev->base_dev.dev, "Offset (%llu) must be < %d\n",
+ entry->rw.offset, SCRATCH_TEST_DEV_MEMORY_SIZE);
+ return -EINVAL;
+ }
+ entry->rw.val = test_dev->scratch_mem[entry->rw.offset];
+ } else if (entry->type == LWIS_IO_ENTRY_READ_BATCH) {
+ rw_batch = &entry->rw_batch;
+ if (rw_batch->offset >= SCRATCH_TEST_DEV_MEMORY_SIZE ||
+ SCRATCH_TEST_DEV_MEMORY_SIZE - rw_batch->offset < rw_batch->size_in_bytes) {
+ dev_err(test_dev->base_dev.dev,
+ "Read range[offset(%llu) + size_in_bytes(%zu)] exceeds scratch memory (%d)\n",
+ rw_batch->offset, rw_batch->size_in_bytes,
+ SCRATCH_TEST_DEV_MEMORY_SIZE);
+ return -EINVAL;
+ }
+ for (i = 0; i < rw_batch->size_in_bytes; ++i) {
+ rw_batch->buf[i] = test_dev->scratch_mem[rw_batch->offset + i];
+ }
+ } else if (entry->type == LWIS_IO_ENTRY_WRITE) {
+ if (entry->rw.offset >= SCRATCH_TEST_DEV_MEMORY_SIZE) {
+ dev_err(test_dev->base_dev.dev, "Offset (%llu) must be < %d\n",
+ entry->rw.offset, SCRATCH_TEST_DEV_MEMORY_SIZE);
+ return -EINVAL;
+ }
+ test_dev->scratch_mem[entry->rw.offset] = entry->rw.val;
+ } else if (entry->type == LWIS_IO_ENTRY_WRITE_BATCH) {
+ rw_batch = &entry->rw_batch;
+ if (rw_batch->offset >= SCRATCH_TEST_DEV_MEMORY_SIZE ||
+ SCRATCH_TEST_DEV_MEMORY_SIZE - rw_batch->offset < rw_batch->size_in_bytes) {
+ dev_err(test_dev->base_dev.dev,
+ "Write range[offset(%llu) + size_in_bytes(%zu)] exceeds scratch memory (%d)\n",
+ rw_batch->offset, rw_batch->size_in_bytes,
+ SCRATCH_TEST_DEV_MEMORY_SIZE);
+ return -EINVAL;
+ }
+ for (i = 0; i < rw_batch->size_in_bytes; ++i) {
+ test_dev->scratch_mem[rw_batch->offset + i] = rw_batch->buf[i];
+ }
+ } else if (entry->type == LWIS_IO_ENTRY_MODIFY) {
+ if (entry->mod.offset >= SCRATCH_TEST_DEV_MEMORY_SIZE) {
+ dev_err(test_dev->base_dev.dev, "Offset (%llu) must be < %d\n",
+ entry->mod.offset, SCRATCH_TEST_DEV_MEMORY_SIZE);
+ return -EINVAL;
+ }
+ reg_value = test_dev->scratch_mem[entry->mod.offset];
+ reg_value &= ~entry->mod.val_mask;
+ reg_value |= entry->mod.val_mask & entry->mod.val;
+ test_dev->scratch_mem[entry->rw.offset] = reg_value;
+ } else {
+ dev_err(test_dev->base_dev.dev, "Invalid IO entry type: %d\n", entry->type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lwis_test_device_setup(struct lwis_test_device *test_dev)
+{
+ int ret = 0;
+
+#ifdef CONFIG_OF
+ /* Parse device tree for device configurations */
+ ret = lwis_test_device_parse_dt(test_dev);
+ if (ret) {
+ dev_err(test_dev->base_dev.dev, "Failed to parse device tree\n");
+ }
+#else
+ /* Non-device-tree init: Save for future implementation */
+ ret = -ENOSYS;
+#endif
+
+ return ret;
+}
+
static int lwis_test_device_probe(struct platform_device *plat_dev)
{
int ret = 0;
@@ -52,7 +160,7 @@ static int lwis_test_device_probe(struct platform_device *plat_dev)
/* Allocate test device specific data construct */
test_dev = devm_kzalloc(dev, sizeof(struct lwis_test_device), GFP_KERNEL);
if (!test_dev) {
- dev_err(dev, "Failed to allocate test device structure\n");
+ dev_err(dev, "Failed to allocate TEST device structure\n");
return -ENOMEM;
}
@@ -63,9 +171,23 @@ static int lwis_test_device_probe(struct platform_device *plat_dev)
/* Call the base device probe function */
ret = lwis_base_probe(&test_dev->base_dev, plat_dev);
if (ret) {
- dev_err(dev, "Error in lwis base probe, ret: %d\n", ret);
+ dev_err(dev, "TEST device: Error in lwis base probe: %d\n", ret);
+ goto error_probe;
+ }
+
+ /* Call TEST device specific setup function */
+ ret = lwis_test_device_setup(test_dev);
+ if (ret) {
+ dev_err(test_dev->base_dev.dev, "Error in TEST device initialization\n");
+ lwis_base_unprobe(&test_dev->base_dev);
+ goto error_probe;
}
+ dev_info(test_dev->base_dev.dev, "TEST Device Probe: Success\n");
+
+ return 0;
+
+error_probe:
return ret;
}
@@ -111,6 +233,8 @@ int __init lwis_test_device_init(void)
{
int ret = 0;
+ pr_info("TEST device initialization\n");
+
ret = platform_driver_register(&lwis_driver);
if (ret)
pr_err("platform_driver_register failed: %d\n", ret);