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