[RFC,2/2] kselftest: Add test to detect unprobed devices on ACPI platforms
Commit Message
Add new kselftest that tests whether devices declared in the ACPI
namespace and supported by the kernel are correctly bound
to a driver.
The test runs the acpi-extract-ids script to generate a list
of all the ACPI device IDs present in the kernel sources.
The list is then used as a reference to determine which of the
devices declared in the ACPI namespace are supported by the kernel
and therefore expected to bind to a driver.
Signed-off-by: Laura Nao <laura.nao@collabora.com>
---
MAINTAINERS | 1 +
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/acpi/.gitignore | 2 +
tools/testing/selftests/acpi/Makefile | 23 ++++++
.../selftests/acpi/test_unprobed_devices.sh | 75 +++++++++++++++++++
5 files changed, 102 insertions(+)
create mode 100644 tools/testing/selftests/acpi/.gitignore
create mode 100644 tools/testing/selftests/acpi/Makefile
create mode 100755 tools/testing/selftests/acpi/test_unprobed_devices.sh
@@ -295,6 +295,7 @@ F: include/acpi/
F: include/linux/acpi.h
F: include/linux/fwnode.h
F: scripts/acpi/acpi-extract-ids
+F: tools/testing/selftests/acpi/
F: tools/power/acpi/
ACPI APEI
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
+TARGETS += acpi
TARGETS += alsa
TARGETS += amd-pstate
TARGETS += arm64
new file mode 100644
@@ -0,0 +1,2 @@
+supported_id_list
+ktap_helpers.sh
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,23 @@
+PY3 = $(shell which python3 2>/dev/null)
+
+ifneq ($(PY3),)
+
+TEST_PROGS := test_unprobed_devices.sh
+TEST_GEN_FILES := supported_id_list ktap_helpers.sh
+
+include ../lib.mk
+
+$(OUTPUT)/supported_id_list:
+ $(top_srcdir)/scripts/acpi/acpi-extract-ids $(top_srcdir) > $@
+
+$(OUTPUT)/ktap_helpers.sh:
+ cp $(top_srcdir)/tools/testing/selftests/dt/ktap_helpers.sh $@
+
+else
+
+all: no_py3_warning
+
+no_py3_warning:
+ @echo "Missing python3. This test will be skipped."
+
+endif
\ No newline at end of file
new file mode 100755
@@ -0,0 +1,75 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2023 Collabora Ltd
+#
+# Inspired by the tools/testing/selftests/dt/test_unprobed_devices.sh
+# script, adapted for the ACPI use case.
+#
+# This script checks whether devices declared in the ACPI namespace
+# and supported by the kernel are correctly bound to a driver.
+#
+# A list of all the ACPI device IDs present in the kernel sources
+# is used as reference to determine which of the devices declared
+# in the ACPI tables are supported.
+#
+
+DIR="$(dirname "$(readlink -f "$0")")"
+
+source "${DIR}"/ktap_helpers.sh
+
+ACPI_SYSTEM_DIR="/sys/devices/LNXSYSTM:00"
+SUPPORTED_ID_LIST="${DIR}"/supported_id_list
+
+KSFT_PASS=0
+KSFT_FAIL=1
+KSFT_SKIP=4
+
+ktap_print_header
+
+if [[ ! -d "${ACPI_SYSTEM_DIR}" ]]; then
+ ktap_skip_all "${ACPI_SYSTEM_DIR} doesn't exist."
+ exit "${KSFT_SKIP}"
+fi
+
+# The ACPI specification mandates that ACPI objects representing devices on
+# non-enumerable and enumerable busses contain a _HID or an _ADR identification
+# object respectively.
+# Get a list of devices of both types, by searching the ACPI sysfs subtree for
+# directories containing a hid or adr attribute.
+supp_dev_paths=$(while IFS=$'\n' read -r dev_path; do
+ if [ ! -f "${dev_path}"/hid ] && [ ! -f "${dev_path}"/adr ]; then
+ continue
+ fi
+
+ if [ -f "${dev_path}"/hid ]; then
+ if ! grep -x -q -i "$(cat "${dev_path}"/hid)" "${SUPPORTED_ID_LIST}"; then
+ continue
+ fi
+ fi
+
+ echo "${dev_path}"
+done < <(find ${ACPI_SYSTEM_DIR} -name uevent -exec dirname {} \;))
+
+supp_dev_paths_num=$(echo "${supp_dev_paths}" | wc -w)
+ktap_set_plan "${supp_dev_paths_num}"
+
+ret="${KSFT_PASS}"
+for dev_path in ${supp_dev_paths}; do
+ desc="$(cat "${dev_path}"/path)"
+ [ -f "${dev_path}"/hid ] && desc+=" $(cat "${dev_path}"/hid)"
+
+ # ACPI device objects might be linked to other objects in the device
+ # hierarchy (e.g. devices on the PCI bus).
+ # In these cases, the driver folder will be in the companion object's sysfs
+ # directory, linked by physical_node.
+ if [ -d "${dev_path}"/physical_node/driver ] || [ -d "${dev_path}"/driver ]; then
+ ktap_test_pass "${desc}"
+ else
+ ret="${KSFT_FAIL}"
+ ktap_test_fail "${desc}"
+ fi
+done
+
+ktap_print_totals
+exit "${ret}"