162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2020 Intel Corporation
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/printk.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* a tiny module only meant to test
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci *   set/clear_bit
1562306a36Sopenharmony_ci *   get_count_order/long
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* use an enum because that's the most common BITMAP usage */
1962306a36Sopenharmony_cienum bitops_fun {
2062306a36Sopenharmony_ci	BITOPS_4 = 4,
2162306a36Sopenharmony_ci	BITOPS_7 = 7,
2262306a36Sopenharmony_ci	BITOPS_11 = 11,
2362306a36Sopenharmony_ci	BITOPS_31 = 31,
2462306a36Sopenharmony_ci	BITOPS_88 = 88,
2562306a36Sopenharmony_ci	BITOPS_LAST = 255,
2662306a36Sopenharmony_ci	BITOPS_LENGTH = 256
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic DECLARE_BITMAP(g_bitmap, BITOPS_LENGTH);
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic unsigned int order_comb[][2] = {
3262306a36Sopenharmony_ci	{0x00000003,  2},
3362306a36Sopenharmony_ci	{0x00000004,  2},
3462306a36Sopenharmony_ci	{0x00001fff, 13},
3562306a36Sopenharmony_ci	{0x00002000, 13},
3662306a36Sopenharmony_ci	{0x50000000, 31},
3762306a36Sopenharmony_ci	{0x80000000, 31},
3862306a36Sopenharmony_ci	{0x80003000, 32},
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#ifdef CONFIG_64BIT
4262306a36Sopenharmony_cistatic unsigned long order_comb_long[][2] = {
4362306a36Sopenharmony_ci	{0x0000000300000000, 34},
4462306a36Sopenharmony_ci	{0x0000000400000000, 34},
4562306a36Sopenharmony_ci	{0x00001fff00000000, 45},
4662306a36Sopenharmony_ci	{0x0000200000000000, 45},
4762306a36Sopenharmony_ci	{0x5000000000000000, 63},
4862306a36Sopenharmony_ci	{0x8000000000000000, 63},
4962306a36Sopenharmony_ci	{0x8000300000000000, 64},
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci#endif
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic int __init test_bitops_startup(void)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	int i, bit_set;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	pr_info("Starting bitops test\n");
5862306a36Sopenharmony_ci	set_bit(BITOPS_4, g_bitmap);
5962306a36Sopenharmony_ci	set_bit(BITOPS_7, g_bitmap);
6062306a36Sopenharmony_ci	set_bit(BITOPS_11, g_bitmap);
6162306a36Sopenharmony_ci	set_bit(BITOPS_31, g_bitmap);
6262306a36Sopenharmony_ci	set_bit(BITOPS_88, g_bitmap);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(order_comb); i++) {
6562306a36Sopenharmony_ci		if (order_comb[i][1] != get_count_order(order_comb[i][0]))
6662306a36Sopenharmony_ci			pr_warn("get_count_order wrong for %x\n",
6762306a36Sopenharmony_ci				       order_comb[i][0]);
6862306a36Sopenharmony_ci	}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(order_comb); i++) {
7162306a36Sopenharmony_ci		if (order_comb[i][1] != get_count_order_long(order_comb[i][0]))
7262306a36Sopenharmony_ci			pr_warn("get_count_order_long wrong for %x\n",
7362306a36Sopenharmony_ci				       order_comb[i][0]);
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#ifdef CONFIG_64BIT
7762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(order_comb_long); i++) {
7862306a36Sopenharmony_ci		if (order_comb_long[i][1] !=
7962306a36Sopenharmony_ci			       get_count_order_long(order_comb_long[i][0]))
8062306a36Sopenharmony_ci			pr_warn("get_count_order_long wrong for %lx\n",
8162306a36Sopenharmony_ci				       order_comb_long[i][0]);
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci#endif
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	barrier();
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	clear_bit(BITOPS_4, g_bitmap);
8862306a36Sopenharmony_ci	clear_bit(BITOPS_7, g_bitmap);
8962306a36Sopenharmony_ci	clear_bit(BITOPS_11, g_bitmap);
9062306a36Sopenharmony_ci	clear_bit(BITOPS_31, g_bitmap);
9162306a36Sopenharmony_ci	clear_bit(BITOPS_88, g_bitmap);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	bit_set = find_first_bit(g_bitmap, BITOPS_LAST);
9462306a36Sopenharmony_ci	if (bit_set != BITOPS_LAST)
9562306a36Sopenharmony_ci		pr_err("ERROR: FOUND SET BIT %d\n", bit_set);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	pr_info("Completed bitops test\n");
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	return 0;
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic void __exit test_bitops_unstartup(void)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cimodule_init(test_bitops_startup);
10762306a36Sopenharmony_cimodule_exit(test_bitops_unstartup);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciMODULE_AUTHOR("Jesse Brandeburg <jesse.brandeburg@intel.com>, Wei Yang <richard.weiyang@gmail.com>");
11062306a36Sopenharmony_ciMODULE_LICENSE("GPL");
11162306a36Sopenharmony_ciMODULE_DESCRIPTION("Bit testing module");
112