blob: 0b7e535842e975a5f672a9fa04ac6cad8d07a45e [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2024 Google LLC. All Rights Reserved.
*
* aoc service to monitor unit test status
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include "aoc.h"
#include "aoc-interface.h"
#define AOC_UNIT_TEST_SERVICE_DEV_NAME "aoc_unit_test_dev"
#define AOC_SERVICE_NAME "unit_test"
enum AOC_UNIT_TEST_STATUS {
AOC_UNIT_TEST_RUNNING,
AOC_UNIT_TEST_FAILED,
AOC_UNIT_TEST_PASSED
};
static struct aoc_service_dev *aoc_unit_test_service = NULL;
static const char * const service_names[] = {
AOC_SERVICE_NAME,
NULL,
};
static enum AOC_UNIT_TEST_STATUS unit_test_status = AOC_UNIT_TEST_RUNNING;
static ssize_t unit_test_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
static const char *status[3] = { "RUNNING", "FAILED", "PASSED" };
return scnprintf(buf, sizeof(status[unit_test_status]), "%s\n", status[unit_test_status]);
}
static DEVICE_ATTR_RO(unit_test_status);
static ssize_t unit_test_reset_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
unit_test_status = AOC_UNIT_TEST_RUNNING;
return 1;
}
static DEVICE_ATTR_WO(unit_test_reset);
static struct attribute *aoc_unit_test_attrs[] = {
&dev_attr_unit_test_status.attr,
&dev_attr_unit_test_reset.attr,
NULL
};
ATTRIBUTE_GROUPS(aoc_unit_test);
static void handle_aoc_msg(struct aoc_service_dev *dev)
{
char buf[64];
int ret;
ret = aoc_service_read(dev, buf, 64, true);
if (ret < 0) {
dev_err(&dev->dev, "Read failed with %d\n", ret);
return;
}
if (strcmp(buf, "PASSED") == 0) {
unit_test_status = AOC_UNIT_TEST_PASSED;
dev_info(&dev->dev, "Unit tests passed!\n");
} else if (strcmp(buf, "FAILED") == 0) {
unit_test_status = AOC_UNIT_TEST_FAILED;
dev_info(&dev->dev, "Unit tests failed!\n");
}
return;
}
static int aoc_unit_test_service_probe(struct aoc_service_dev *sd)
{
struct device *dev = &sd->dev;
int ret;
aoc_unit_test_service = sd;
ret = device_add_groups(dev, aoc_unit_test_groups);
if (ret)
dev_err(dev, "Failed to add unit test attributes device groups\n");
sd->handler = handle_aoc_msg;
return 0;
}
static int aoc_unit_test_service_remove(struct aoc_service_dev *sd)
{
struct device *dev = &sd->dev;
aoc_unit_test_service = NULL;
device_remove_groups(dev, aoc_unit_test_groups);
return 0;
}
static struct aoc_driver aoc_unit_test_sdev = {
.drv = {
.name = AOC_UNIT_TEST_SERVICE_DEV_NAME,
},
.service_names = service_names,
.probe = aoc_unit_test_service_probe,
.remove = aoc_unit_test_service_remove,
};
static int __init aoc_unit_test_service_init(void)
{
aoc_driver_register(&aoc_unit_test_sdev);
return 0;
}
static void __exit aoc_unit_test_service_exit(void)
{
aoc_driver_unregister(&aoc_unit_test_sdev);
}
module_init(aoc_unit_test_service_init);
module_exit(aoc_unit_test_service_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AoC Unit Test Driver");
MODULE_AUTHOR("Alex Iacobucci <alexiacobucci@google.com>");