1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 4import os.path 5import pytest 6import re 7 8def in_tree(response, name, uclass, drv, depth, last_child): 9 lines = [x.strip() for x in response.splitlines()] 10 leaf = ' ' * 4 * depth; 11 if not last_child: 12 leaf = leaf + '\|' 13 else: 14 leaf = leaf + '`' 15 leaf = leaf + '-- ' + name 16 line = ' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'.format(uclass, drv, leaf) 17 prog = re.compile(line) 18 for l in lines: 19 if prog.match(l): 20 return True 21 return False 22 23 24@pytest.mark.buildconfigspec('cmd_bind') 25def test_bind_unbind_with_node(u_boot_console): 26 27 #bind /bind-test. Device should come up as well as its children 28 response = u_boot_console.run_command('bind /bind-test generic_simple_bus') 29 assert response == '' 30 tree = u_boot_console.run_command('dm tree') 31 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 32 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 33 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 34 35 #Unbind child #1. No error expected and all devices should be there except for bind-test-child1 36 response = u_boot_console.run_command('unbind /bind-test/bind-test-child1') 37 assert response == '' 38 tree = u_boot_console.run_command('dm tree') 39 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 40 assert 'bind-test-child1' not in tree 41 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 42 43 #bind child #1. No error expected and all devices should be there 44 response = u_boot_console.run_command('bind /bind-test/bind-test-child1 phy_sandbox') 45 assert response == '' 46 tree = u_boot_console.run_command('dm tree') 47 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 48 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 49 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, False) 50 51 #Unbind child #2. No error expected and all devices should be there except for bind-test-child2 52 response = u_boot_console.run_command('unbind /bind-test/bind-test-child2') 53 assert response == '' 54 tree = u_boot_console.run_command('dm tree') 55 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 56 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 57 assert 'bind-test-child2' not in tree 58 59 60 #Bind child #2. No error expected and all devices should be there 61 response = u_boot_console.run_command('bind /bind-test/bind-test-child2 generic_simple_bus') 62 assert response == '' 63 tree = u_boot_console.run_command('dm tree') 64 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 65 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 66 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 67 68 #Unbind parent. No error expected. All devices should be removed and unbound 69 response = u_boot_console.run_command('unbind /bind-test') 70 assert response == '' 71 tree = u_boot_console.run_command('dm tree') 72 assert 'bind-test' not in tree 73 assert 'bind-test-child1' not in tree 74 assert 'bind-test-child2' not in tree 75 76 #try binding invalid node with valid driver 77 response = u_boot_console.run_command('bind /not-a-valid-node generic_simple_bus') 78 assert response != '' 79 tree = u_boot_console.run_command('dm tree') 80 assert 'not-a-valid-node' not in tree 81 82 #try binding valid node with invalid driver 83 response = u_boot_console.run_command('bind /bind-test not_a_driver') 84 assert response != '' 85 tree = u_boot_console.run_command('dm tree') 86 assert 'bind-test' not in tree 87 88 #bind /bind-test. Device should come up as well as its children 89 response = u_boot_console.run_command('bind /bind-test generic_simple_bus') 90 assert response == '' 91 tree = u_boot_console.run_command('dm tree') 92 assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True) 93 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 94 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 95 96 response = u_boot_console.run_command('unbind /bind-test') 97 assert response == '' 98 99def get_next_line(tree, name): 100 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 101 child_line = '' 102 for idx, line in enumerate(treelines): 103 if ('-- ' + name) in line: 104 try: 105 child_line = treelines[idx+1] 106 except: 107 pass 108 break 109 return child_line 110 111@pytest.mark.buildconfigspec('cmd_bind') 112def test_bind_unbind_with_uclass(u_boot_console): 113 #bind /bind-test 114 response = u_boot_console.run_command('bind /bind-test generic_simple_bus') 115 assert response == '' 116 117 #make sure bind-test-child2 is there and get its uclass/index pair 118 tree = u_boot_console.run_command('dm tree') 119 child2_line = [x.strip() for x in tree.splitlines() if '-- bind-test-child2' in x] 120 assert len(child2_line) == 1 121 122 child2_uclass = child2_line[0].split()[0] 123 child2_index = int(child2_line[0].split()[1]) 124 125 #bind generic_simple_bus as a child of bind-test-child2 126 response = u_boot_console.run_command('bind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus')) 127 128 #check that the child is there and its uclass/index pair is right 129 tree = u_boot_console.run_command('dm tree') 130 131 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 132 assert child_of_child2_line 133 child_of_child2_index = int(child_of_child2_line.split()[1]) 134 assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True) 135 assert child_of_child2_index == child2_index + 1 136 137 #unbind the child and check it has been removed 138 response = u_boot_console.run_command('unbind simple_bus {}'.format(child_of_child2_index)) 139 assert response == '' 140 tree = u_boot_console.run_command('dm tree') 141 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 142 assert not in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True) 143 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 144 assert child_of_child2_line == '' 145 146 #bind generic_simple_bus as a child of bind-test-child2 147 response = u_boot_console.run_command('bind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus')) 148 149 #check that the child is there and its uclass/index pair is right 150 tree = u_boot_console.run_command('dm tree') 151 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 152 153 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 154 assert child_of_child2_line 155 child_of_child2_index = int(child_of_child2_line.split()[1]) 156 assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True) 157 assert child_of_child2_index == child2_index + 1 158 159 #unbind the child and check it has been removed 160 response = u_boot_console.run_command('unbind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus')) 161 assert response == '' 162 163 tree = u_boot_console.run_command('dm tree') 164 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True) 165 166 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 167 assert child_of_child2_line == '' 168 169 #unbind the child again and check it doesn't change the tree 170 tree_old = u_boot_console.run_command('dm tree') 171 response = u_boot_console.run_command('unbind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus')) 172 tree_new = u_boot_console.run_command('dm tree') 173 174 assert response == '' 175 assert tree_old == tree_new 176 177 response = u_boot_console.run_command('unbind /bind-test') 178 assert response == '' 179