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