"Das U-Boot" Source Tree
at master 184 lines 5.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Tests for the devres ( 4 * 5 * Copyright 2019 Google LLC 6 */ 7 8#include <errno.h> 9#include <dm.h> 10#include <log.h> 11#include <malloc.h> 12#include <dm/device-internal.h> 13#include <dm/devres.h> 14#include <dm/test.h> 15#include <dm/uclass-internal.h> 16#include <test/ut.h> 17 18/* Test that devm_kmalloc() allocates memory, free when device is removed */ 19static int dm_test_devres_alloc(struct unit_test_state *uts) 20{ 21 ulong mem_start, mem_dev, mem_kmalloc; 22 struct udevice *dev; 23 void *ptr; 24 25 mem_start = ut_check_delta(0); 26 ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev)); 27 mem_dev = ut_check_delta(mem_start); 28 ut_assert(mem_dev > 0); 29 30 /* This should increase allocated memory */ 31 ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE, 0); 32 ut_assert(ptr != NULL); 33 mem_kmalloc = ut_check_delta(mem_dev); 34 ut_assert(mem_kmalloc > 0); 35 36 /* Check that ptr is freed */ 37 device_remove(dev, DM_REMOVE_NORMAL); 38 ut_asserteq(0, ut_check_delta(mem_start)); 39 40 return 0; 41} 42DM_TEST(dm_test_devres_alloc, UTF_SCAN_PDATA); 43 44/* Test devm_kfree() can be used to free memory too */ 45static int dm_test_devres_free(struct unit_test_state *uts) 46{ 47 ulong mem_start, mem_dev, mem_kmalloc; 48 struct udevice *dev; 49 void *ptr; 50 51 mem_start = ut_check_delta(0); 52 ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev)); 53 mem_dev = ut_check_delta(mem_start); 54 ut_assert(mem_dev > 0); 55 56 ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE, 0); 57 ut_assert(ptr != NULL); 58 mem_kmalloc = ut_check_delta(mem_dev); 59 ut_assert(mem_kmalloc > 0); 60 61 /* Free the ptr and check that memory usage goes down */ 62 devm_kfree(dev, ptr); 63 ut_assert(ut_check_delta(mem_kmalloc) < 0); 64 65 device_remove(dev, DM_REMOVE_NORMAL); 66 ut_asserteq(0, ut_check_delta(mem_start)); 67 68 return 0; 69} 70DM_TEST(dm_test_devres_free, UTF_SCAN_PDATA); 71 72/* Test that kzalloc() returns memory that is zeroed */ 73static int dm_test_devres_kzalloc(struct unit_test_state *uts) 74{ 75 struct udevice *dev; 76 u8 *ptr, val; 77 int i; 78 79 ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev)); 80 81 ptr = devm_kzalloc(dev, TEST_DEVRES_SIZE, 0); 82 ut_assert(ptr != NULL); 83 for (val = 0, i = 0; i < TEST_DEVRES_SIZE; i++) 84 val |= *ptr; 85 ut_asserteq(0, val); 86 87 return 0; 88} 89DM_TEST(dm_test_devres_kzalloc, UTF_SCAN_PDATA); 90 91/* Test that devm_kmalloc_array() allocates an array that can be set */ 92static int dm_test_devres_kmalloc_array(struct unit_test_state *uts) 93{ 94 ulong mem_start, mem_dev; 95 struct udevice *dev; 96 u8 *ptr; 97 98 mem_start = ut_check_delta(0); 99 ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev)); 100 mem_dev = ut_check_delta(mem_start); 101 102 ptr = devm_kmalloc_array(dev, TEST_DEVRES_COUNT, TEST_DEVRES_SIZE, 0); 103 ut_assert(ptr != NULL); 104 memset(ptr, '\xff', TEST_DEVRES_TOTAL); 105 ut_assert(ut_check_delta(mem_dev) > 0); 106 107 device_remove(dev, DM_REMOVE_NORMAL); 108 ut_asserteq(0, ut_check_delta(mem_start)); 109 110 return 0; 111} 112DM_TEST(dm_test_devres_kmalloc_array, UTF_SCAN_PDATA); 113 114/* Test that devm_kcalloc() allocates a zeroed array */ 115static int dm_test_devres_kcalloc(struct unit_test_state *uts) 116{ 117 ulong mem_start, mem_dev; 118 struct udevice *dev; 119 u8 *ptr, val; 120 int i; 121 122 mem_start = ut_check_delta(0); 123 ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev)); 124 mem_dev = ut_check_delta(mem_start); 125 ut_assert(mem_dev > 0); 126 127 /* This should increase allocated memory */ 128 ptr = devm_kcalloc(dev, TEST_DEVRES_SIZE, TEST_DEVRES_COUNT, 0); 129 ut_assert(ptr != NULL); 130 ut_assert(ut_check_delta(mem_dev) > 0); 131 for (val = 0, i = 0; i < TEST_DEVRES_TOTAL; i++) 132 val |= *ptr; 133 ut_asserteq(0, val); 134 135 /* Check that ptr is freed */ 136 device_remove(dev, DM_REMOVE_NORMAL); 137 ut_asserteq(0, ut_check_delta(mem_start)); 138 139 return 0; 140} 141DM_TEST(dm_test_devres_kcalloc, UTF_SCAN_PDATA); 142 143/* Test devres releases resources automatically as expected */ 144static int dm_test_devres_phase(struct unit_test_state *uts) 145{ 146 struct devres_stats stats; 147 struct udevice *dev; 148 149 /* 150 * The device is bound already, so find it and check that it has the 151 * allocation created in the bind() method. 152 */ 153 ut_assertok(uclass_find_first_device(UCLASS_TEST_DEVRES, &dev)); 154 ut_assertnonnull(dev); 155 devres_get_stats(dev, &stats); 156 ut_asserteq(1, stats.allocs); 157 ut_asserteq(TEST_DEVRES_SIZE, stats.total_size); 158 159 /* Getting plat should add one allocation */ 160 ut_assertok(device_of_to_plat(dev)); 161 devres_get_stats(dev, &stats); 162 ut_asserteq(2, stats.allocs); 163 ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE3, stats.total_size); 164 165 /* Probing the device should add one allocation */ 166 ut_assertok(uclass_first_device_err(UCLASS_TEST_DEVRES, &dev)); 167 ut_assertnonnull(dev); 168 devres_get_stats(dev, &stats); 169 ut_asserteq(3, stats.allocs); 170 ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE2 + TEST_DEVRES_SIZE3, 171 stats.total_size); 172 173 /* Removing the device should drop both those allocations */ 174 device_remove(dev, DM_REMOVE_NORMAL); 175 devres_get_stats(dev, &stats); 176 ut_asserteq(1, stats.allocs); 177 ut_asserteq(TEST_DEVRES_SIZE, stats.total_size); 178 179 /* Unbinding removes the other. */ 180 device_unbind(dev); 181 182 return 0; 183} 184DM_TEST(dm_test_devres_phase, UTF_SCAN_PDATA | UTF_SCAN_FDT);