linux/drivers/of/unittest.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Self tests for device tree subsystem
 */

#define pr_fmt(fmt)

#include <linux/memblock.h>
#include <linux/clk.h>
#include <linux/dma-direct.h> /* to test phys_to_dma/dma_to_phys */
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/hashtable.h>
#include <linux/libfdt.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/kernel.h>

#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/gpio/driver.h>

#include <linux/bitops.h>

#include "of_private.h"

static struct unittest_results {} unittest_results;

#define unittest(result, fmt, ...)

#ifdef CONFIG_OF_KOBJ
#define OF_KREF_READ(NODE)
#else
#define OF_KREF_READ
#endif

/*
 * Expected message may have a message level other than KERN_INFO.
 * Print the expected message only if the current loglevel will allow
 * the actual message to print.
 *
 * Do not use EXPECT_BEGIN(), EXPECT_END(), EXPECT_NOT_BEGIN(), or
 * EXPECT_NOT_END() to report messages expected to be reported or not
 * reported by pr_debug().
 */
#define EXPECT_BEGIN(level, fmt, ...)

#define EXPECT_END(level, fmt, ...)

#define EXPECT_NOT_BEGIN(level, fmt, ...)

#define EXPECT_NOT_END(level, fmt, ...)

static void __init of_unittest_find_node_by_name(void)
{}

static void __init of_unittest_dynamic(void)
{}

static int __init of_unittest_check_node_linkage(struct device_node *np)
{}

static void __init of_unittest_check_tree_linkage(void)
{}

static void __init of_unittest_printf_one(struct device_node *np, const char *fmt,
					  const char *expected)
{}

static void __init of_unittest_printf(void)
{}

struct node_hash {};

static DEFINE_HASHTABLE(phandle_ht, 8);
static void __init of_unittest_check_phandles(void)
{}

static void __init of_unittest_parse_phandle_with_args(void)
{}

static void __init of_unittest_parse_phandle_with_args_map(void)
{}

static void __init of_unittest_property_string(void)
{}

#define propcmp(p1, p2)
static void __init of_unittest_property_copy(void)
{}

static void __init of_unittest_changeset(void)
{}

static void __init __maybe_unused changeset_check_string(struct device_node *np,
							 const char *prop_name,
							 const char *expected_str)
{}

static void __init __maybe_unused changeset_check_string_array(struct device_node *np,
							       const char *prop_name,
							       const char * const *expected_array,
							       unsigned int count)
{}

static void __init __maybe_unused changeset_check_u32(struct device_node *np,
						      const char *prop_name,
						      u32 expected_u32)
{}

static void __init __maybe_unused changeset_check_u32_array(struct device_node *np,
							    const char *prop_name,
							    const u32 *expected_array,
							    unsigned int count)
{}

static void __init __maybe_unused changeset_check_bool(struct device_node *np,
						       const char *prop_name)
{}

static void __init of_unittest_changeset_prop(void)
{}

static void __init of_unittest_dma_get_max_cpu_address(void)
{}

static void __init of_unittest_dma_ranges_one(const char *path,
		u64 expect_dma_addr, u64 expect_paddr)
{}

static void __init of_unittest_parse_dma_ranges(void)
{}

static void __init of_unittest_pci_dma_ranges(void)
{}

static void __init of_unittest_bus_ranges(void)
{}

static void __init of_unittest_bus_3cell_ranges(void)
{}

static void __init of_unittest_reg(void)
{}

struct of_unittest_expected_res {};

static void __init of_unittest_check_addr(const char *node_path,
					  const struct of_unittest_expected_res *tab_exp,
					  unsigned int tab_exp_count)
{}

static const struct of_unittest_expected_res of_unittest_reg_2cell_expected_res[] =;

static const struct of_unittest_expected_res of_unittest_reg_3cell_expected_res[] =;

static const struct of_unittest_expected_res of_unittest_reg_pci_expected_res[] =;

static void __init of_unittest_translate_addr(void)
{}

static void __init of_unittest_parse_interrupts(void)
{}

static void __init of_unittest_parse_interrupts_extended(void)
{}

static const struct of_device_id match_node_table[] =;

static struct {} match_node_tests[] =;

static void __init of_unittest_match_node(void)
{}

static struct resource test_bus_res =;
static const struct platform_device_info test_bus_info =;
static void __init of_unittest_platform_populate(void)
{}

/**
 *	update_node_properties - adds the properties
 *	of np into dup node (present in live tree) and
 *	updates parent of children of np to dup.
 *
 *	@np:	node whose properties are being added to the live tree
 *	@dup:	node present in live tree to be updated
 */
static void update_node_properties(struct device_node *np,
					struct device_node *dup)
{}

/**
 *	attach_node_and_children - attaches nodes
 *	and its children to live tree.
 *	CAUTION: misleading function name - if node @np already exists in
 *	the live tree then children of @np are *not* attached to the live
 *	tree.  This works for the current test devicetree nodes because such
 *	nodes do not have child nodes.
 *
 *	@np:	Node to attach to live tree
 */
static void attach_node_and_children(struct device_node *np)
{}

/**
 *	unittest_data_add - Reads, copies data from
 *	linked tree and attaches it to the live tree
 */
static int __init unittest_data_add(void)
{}

#ifdef CONFIG_OF_OVERLAY
static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id);

static int unittest_probe(struct platform_device *pdev)
{}

static void unittest_remove(struct platform_device *pdev)
{}

static const struct of_device_id unittest_match[] =;

static struct platform_driver unittest_driver =;

/* get the platform device instantiated at the path */
static struct platform_device *of_path_to_platform_device(const char *path)
{}

/* find out if a platform device exists at that path */
static int of_path_platform_device_exists(const char *path)
{}

#ifdef CONFIG_OF_GPIO

struct unittest_gpio_dev {};

static int unittest_gpio_chip_request_count;
static int unittest_gpio_probe_count;
static int unittest_gpio_probe_pass_count;

static int unittest_gpio_chip_request(struct gpio_chip *chip, unsigned int offset)
{}

static int unittest_gpio_probe(struct platform_device *pdev)
{}

static void unittest_gpio_remove(struct platform_device *pdev)
{}

static const struct of_device_id unittest_gpio_id[] =;

static struct platform_driver unittest_gpio_driver =;

static void __init of_unittest_overlay_gpio(void)
{}

#else

static void __init of_unittest_overlay_gpio(void)
{
	/* skip tests */
}

#endif

#if IS_BUILTIN(CONFIG_I2C)

/* get the i2c client device instantiated at the path */
static struct i2c_client *of_path_to_i2c_client(const char *path)
{}

/* find out if a i2c client device exists at that path */
static int of_path_i2c_client_exists(const char *path)
{}
#else
static int of_path_i2c_client_exists(const char *path)
{
	return 0;
}
#endif

enum overlay_type {};

static int of_path_device_type_exists(const char *path,
		enum overlay_type ovtype)
{}

static const char *unittest_path(int nr, enum overlay_type ovtype)
{}

static int of_unittest_device_exists(int unittest_nr, enum overlay_type ovtype)
{}

static const char *overlay_name_from_nr(int nr)
{}

static const char *bus_path =;

#define MAX_TRACK_OVCS_IDS

static int track_ovcs_id[MAX_TRACK_OVCS_IDS];
static int track_ovcs_id_overlay_nr[MAX_TRACK_OVCS_IDS];
static int track_ovcs_id_cnt;

static void of_unittest_track_overlay(int ovcs_id, int overlay_nr)
{}

static void of_unittest_untrack_overlay(int ovcs_id)
{}

static void of_unittest_remove_tracked_overlays(void)
{}

static int __init of_unittest_apply_overlay(int overlay_nr, int *ovcs_id)
{}

static int __init __of_unittest_apply_overlay_check(int overlay_nr,
		int unittest_nr, int before, int after,
		enum overlay_type ovtype)
{}

/* apply an overlay while checking before and after states */
static int __init of_unittest_apply_overlay_check(int overlay_nr,
		int unittest_nr, int before, int after,
		enum overlay_type ovtype)
{}

/* apply an overlay and then revert it while checking before, after states */
static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
		int unittest_nr, int before, int after,
		enum overlay_type ovtype)
{}

/* test activation of device */
static void __init of_unittest_overlay_0(void)
{}

/* test deactivation of device */
static void __init of_unittest_overlay_1(void)
{}

/* test activation of device */
static void __init of_unittest_overlay_2(void)
{}

/* test deactivation of device */
static void __init of_unittest_overlay_3(void)
{}

/* test activation of a full device node */
static void __init of_unittest_overlay_4(void)
{}

/* test overlay apply/revert sequence */
static void __init of_unittest_overlay_5(void)
{}

/* test overlay application in sequence */
static void __init of_unittest_overlay_6(void)
{}

/* test overlay application in sequence */
static void __init of_unittest_overlay_8(void)
{}

/* test insertion of a bus with parent devices */
static void __init of_unittest_overlay_10(void)
{}

/* test insertion of a bus with parent devices (and revert) */
static void __init of_unittest_overlay_11(void)
{}

#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)

struct unittest_i2c_bus_data {};

static int unittest_i2c_master_xfer(struct i2c_adapter *adap,
		struct i2c_msg *msgs, int num)
{}

static u32 unittest_i2c_functionality(struct i2c_adapter *adap)
{}

static const struct i2c_algorithm unittest_i2c_algo =;

static int unittest_i2c_bus_probe(struct platform_device *pdev)
{}

static void unittest_i2c_bus_remove(struct platform_device *pdev)
{}

static const struct of_device_id unittest_i2c_bus_match[] =;

static struct platform_driver unittest_i2c_bus_driver =;

static int unittest_i2c_dev_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device_node *np = client->dev.of_node;

	if (!np) {
		dev_err(dev, "No OF node\n");
		return -EINVAL;
	}

	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);

	return 0;
};

static void unittest_i2c_dev_remove(struct i2c_client *client)
{}

static const struct i2c_device_id unittest_i2c_dev_id[] =;

static struct i2c_driver unittest_i2c_dev_driver =;

#if IS_BUILTIN(CONFIG_I2C_MUX)

static int unittest_i2c_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
{}

static int unittest_i2c_mux_probe(struct i2c_client *client)
{
	int i, nchans;
	struct device *dev = &client->dev;
	struct i2c_adapter *adap = client->adapter;
	struct device_node *np = client->dev.of_node, *child;
	struct i2c_mux_core *muxc;
	u32 reg, max_reg;

	dev_dbg(dev, "%s for node @%pOF\n", __func__, np);

	if (!np) {
		dev_err(dev, "No OF node\n");
		return -EINVAL;
	}

	max_reg = (u32)-1;
	for_each_child_of_node(np, child) {
		if (of_property_read_u32(child, "reg", &reg))
			continue;
		if (max_reg == (u32)-1 || reg > max_reg)
			max_reg = reg;
	}
	nchans = max_reg == (u32)-1 ? 0 : max_reg + 1;
	if (nchans == 0) {
		dev_err(dev, "No channels\n");
		return -EINVAL;
	}

	muxc = i2c_mux_alloc(adap, dev, nchans, 0, 0,
			     unittest_i2c_mux_select_chan, NULL);
	if (!muxc)
		return -ENOMEM;
	for (i = 0; i < nchans; i++) {
		if (i2c_mux_add_adapter(muxc, 0, i)) {
			dev_err(dev, "Failed to register mux #%d\n", i);
			i2c_mux_del_adapters(muxc);
			return -ENODEV;
		}
	}

	i2c_set_clientdata(client, muxc);

	return 0;
};

static void unittest_i2c_mux_remove(struct i2c_client *client)
{}

static const struct i2c_device_id unittest_i2c_mux_id[] =;

static struct i2c_driver unittest_i2c_mux_driver =;

#endif

static int of_unittest_overlay_i2c_init(void)
{}

static void of_unittest_overlay_i2c_cleanup(void)
{}

static void __init of_unittest_overlay_i2c_12(void)
{}

/* test deactivation of device */
static void __init of_unittest_overlay_i2c_13(void)
{}

/* just check for i2c mux existence */
static void of_unittest_overlay_i2c_14(void)
{}

static void __init of_unittest_overlay_i2c_15(void)
{}

#else

static inline void of_unittest_overlay_i2c_14(void) { }
static inline void of_unittest_overlay_i2c_15(void) { }

#endif

static int of_notify(struct notifier_block *nb, unsigned long action,
		     void *arg)
{}

static struct notifier_block of_nb =;

static void __init of_unittest_overlay_notify(void)
{}

static void __init of_unittest_overlay(void)
{}

#else
static inline void __init of_unittest_overlay(void) { }
#endif

static void __init of_unittest_lifecycle(void)
{}

#ifdef CONFIG_OF_OVERLAY

/*
 * __dtbo_##overlay_name##_begin[] and __dtbo_##overlay_name##_end[] are
 * created by cmd_dt_S_dtbo in scripts/Makefile.lib
 */

#define OVERLAY_INFO_EXTERN(overlay_name)

#define OVERLAY_INFO(overlay_name, expected, expected_remove)

struct overlay_info {};

OVERLAY_INFO_EXTERN(overlay_base);
OVERLAY_INFO_EXTERN(overlay);
OVERLAY_INFO_EXTERN(overlay_0);
OVERLAY_INFO_EXTERN(overlay_1);
OVERLAY_INFO_EXTERN(overlay_2);
OVERLAY_INFO_EXTERN(overlay_3);
OVERLAY_INFO_EXTERN(overlay_4);
OVERLAY_INFO_EXTERN(overlay_5);
OVERLAY_INFO_EXTERN(overlay_6);
OVERLAY_INFO_EXTERN(overlay_7);
OVERLAY_INFO_EXTERN(overlay_8);
OVERLAY_INFO_EXTERN(overlay_9);
OVERLAY_INFO_EXTERN(overlay_10);
OVERLAY_INFO_EXTERN(overlay_11);
OVERLAY_INFO_EXTERN(overlay_12);
OVERLAY_INFO_EXTERN(overlay_13);
OVERLAY_INFO_EXTERN(overlay_15);
OVERLAY_INFO_EXTERN(overlay_16);
OVERLAY_INFO_EXTERN(overlay_17);
OVERLAY_INFO_EXTERN(overlay_18);
OVERLAY_INFO_EXTERN(overlay_19);
OVERLAY_INFO_EXTERN(overlay_20);
OVERLAY_INFO_EXTERN(overlay_gpio_01);
OVERLAY_INFO_EXTERN(overlay_gpio_02a);
OVERLAY_INFO_EXTERN(overlay_gpio_02b);
OVERLAY_INFO_EXTERN(overlay_gpio_03);
OVERLAY_INFO_EXTERN(overlay_gpio_04a);
OVERLAY_INFO_EXTERN(overlay_gpio_04b);
OVERLAY_INFO_EXTERN(overlay_pci_node);
OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node);
OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop);
OVERLAY_INFO_EXTERN(overlay_bad_phandle);
OVERLAY_INFO_EXTERN(overlay_bad_symbol);
OVERLAY_INFO_EXTERN(overlay_bad_unresolved);

/* entries found by name */
static struct overlay_info overlays[] =;

static struct device_node *overlay_base_root;

static void * __init dt_alloc_memory(u64 size, u64 align)
{}

/*
 * Create base device tree for the overlay unittest.
 *
 * This is called from very early boot code.
 *
 * Do as much as possible the same way as done in __unflatten_device_tree
 * and other early boot steps for the normal FDT so that the overlay base
 * unflattened tree will have the same characteristics as the real tree
 * (such as having memory allocated by the early allocator).  The goal
 * is to test "the real thing" as much as possible, and test "test setup
 * code" as little as possible.
 *
 * Have to stop before resolving phandles, because that uses kmalloc.
 */
void __init unittest_unflatten_overlay_base(void)
{}

/*
 * The purpose of of_unittest_overlay_data_add is to add an
 * overlay in the normal fashion.  This is a test of the whole
 * picture, instead of testing individual elements.
 *
 * A secondary purpose is to be able to verify that the contents of
 * /proc/device-tree/ contains the updated structure and values from
 * the overlay.  That must be verified separately in user space.
 *
 * Return 0 on unexpected error.
 */
static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id)
{}

/*
 * The purpose of of_unittest_overlay_high_level is to add an overlay
 * in the normal fashion.  This is a test of the whole picture,
 * instead of individual elements.
 *
 * The first part of the function is _not_ normal overlay usage; it is
 * finishing splicing the base overlay device tree into the live tree.
 */
static __init void of_unittest_overlay_high_level(void)
{}

static int of_unittest_pci_dev_num;
static int of_unittest_pci_child_num;

/*
 * PCI device tree node test driver
 */
static const struct pci_device_id testdrv_pci_ids[] =;

static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{}

static void testdrv_remove(struct pci_dev *pdev)
{}

static struct pci_driver testdrv_driver =;

static int unittest_pci_probe(struct platform_device *pdev)
{}

static const struct of_device_id unittest_pci_of_match[] =;

static struct platform_driver unittest_pci_driver =;

static int of_unittest_pci_node_verify(struct pci_dev *pdev, bool add)
{}

static void __init of_unittest_pci_node(void)
{}
#else

static inline __init void of_unittest_overlay_high_level(void) {}
static inline __init void of_unittest_pci_node(void) { }

#endif

static int __init of_unittest(void)
{}
late_initcall(of_unittest);