18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2019 NXP
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#include <kunit/test.h>
68c2ecf20Sopenharmony_ci#include <linux/pm_qos.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/* Basic test for aggregating two "min" requests */
98c2ecf20Sopenharmony_cistatic void freq_qos_test_min(struct kunit *test)
108c2ecf20Sopenharmony_ci{
118c2ecf20Sopenharmony_ci	struct freq_constraints	qos;
128c2ecf20Sopenharmony_ci	struct freq_qos_request	req1, req2;
138c2ecf20Sopenharmony_ci	int ret;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	freq_constraints_init(&qos);
168c2ecf20Sopenharmony_ci	memset(&req1, 0, sizeof(req1));
178c2ecf20Sopenharmony_ci	memset(&req2, 0, sizeof(req2));
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MIN, 1000);
208c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
218c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MIN, 2000);
228c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	ret = freq_qos_remove_request(&req2);
278c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
288c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	ret = freq_qos_remove_request(&req1);
318c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
328c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
338c2ecf20Sopenharmony_ci			FREQ_QOS_MIN_DEFAULT_VALUE);
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* Test that requests for MAX_DEFAULT_VALUE have no effect */
378c2ecf20Sopenharmony_cistatic void freq_qos_test_maxdef(struct kunit *test)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	struct freq_constraints	qos;
408c2ecf20Sopenharmony_ci	struct freq_qos_request	req1, req2;
418c2ecf20Sopenharmony_ci	int ret;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	freq_constraints_init(&qos);
448c2ecf20Sopenharmony_ci	memset(&req1, 0, sizeof(req1));
458c2ecf20Sopenharmony_ci	memset(&req2, 0, sizeof(req2));
468c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX),
478c2ecf20Sopenharmony_ci			FREQ_QOS_MAX_DEFAULT_VALUE);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MAX,
508c2ecf20Sopenharmony_ci			FREQ_QOS_MAX_DEFAULT_VALUE);
518c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 0);
528c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MAX,
538c2ecf20Sopenharmony_ci			FREQ_QOS_MAX_DEFAULT_VALUE);
548c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 0);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	/* Add max 1000 */
578c2ecf20Sopenharmony_ci	ret = freq_qos_update_request(&req1, 1000);
588c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
598c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	/* Add max 2000, no impact */
628c2ecf20Sopenharmony_ci	ret = freq_qos_update_request(&req2, 2000);
638c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 0);
648c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* Remove max 1000, new max 2000 */
678c2ecf20Sopenharmony_ci	ret = freq_qos_remove_request(&req1);
688c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
698c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 2000);
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/*
738c2ecf20Sopenharmony_ci * Test that a freq_qos_request can be added again after removal
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * This issue was solved by commit 05ff1ba412fd ("PM: QoS: Invalidate frequency
768c2ecf20Sopenharmony_ci * QoS requests after removal")
778c2ecf20Sopenharmony_ci */
788c2ecf20Sopenharmony_cistatic void freq_qos_test_readd(struct kunit *test)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	struct freq_constraints	qos;
818c2ecf20Sopenharmony_ci	struct freq_qos_request	req;
828c2ecf20Sopenharmony_ci	int ret;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	freq_constraints_init(&qos);
858c2ecf20Sopenharmony_ci	memset(&req, 0, sizeof(req));
868c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
878c2ecf20Sopenharmony_ci			FREQ_QOS_MIN_DEFAULT_VALUE);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/* Add */
908c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 1000);
918c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
928c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* Remove */
958c2ecf20Sopenharmony_ci	ret = freq_qos_remove_request(&req);
968c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
978c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
988c2ecf20Sopenharmony_ci			FREQ_QOS_MIN_DEFAULT_VALUE);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	/* Add again */
1018c2ecf20Sopenharmony_ci	ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 2000);
1028c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 1);
1038c2ecf20Sopenharmony_ci	KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
1048c2ecf20Sopenharmony_ci}
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic struct kunit_case pm_qos_test_cases[] = {
1078c2ecf20Sopenharmony_ci	KUNIT_CASE(freq_qos_test_min),
1088c2ecf20Sopenharmony_ci	KUNIT_CASE(freq_qos_test_maxdef),
1098c2ecf20Sopenharmony_ci	KUNIT_CASE(freq_qos_test_readd),
1108c2ecf20Sopenharmony_ci	{},
1118c2ecf20Sopenharmony_ci};
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_cistatic struct kunit_suite pm_qos_test_module = {
1148c2ecf20Sopenharmony_ci	.name = "qos-kunit-test",
1158c2ecf20Sopenharmony_ci	.test_cases = pm_qos_test_cases,
1168c2ecf20Sopenharmony_ci};
1178c2ecf20Sopenharmony_cikunit_test_suites(&pm_qos_test_module);
118