Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #! /bin/sh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) # Copyright (c) 2020, Google LLC. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Author: Saravana Kannan <saravanak@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) function help() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 	cat << EOF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) Usage: $(basename $0) [-c|-d|-m|-f] [filter options] <list of devices>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) This script needs to be run on the target device once it has booted to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) shell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) The script takes as input a list of one or more device directories under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) /sys/devices and then lists the probe dependency chain (suppliers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) parents) of these devices. It does a breadth first search of the dependency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) chain, so the last entry in the output is close to the root of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) dependency chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) By default it lists the full path to the devices under /sys/devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) It also takes an optional modifier flag as the first parameter to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) what information is listed in the output. If the requested information is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) not available, the device name is printed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)   -c	lists the compatible string of the dependencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)   -d	lists the driver name of the dependencies that have probed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)   -m	lists the module name of the dependencies that have a module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)   -f	list the firmware node path of the dependencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)   -g	list the dependencies as edges and nodes for graphviz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)   -t	list the dependencies as edges for tsort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) The filter options provide a way to filter out some dependencies:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)   --allow-no-driver	By default dependencies that don't have a driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 			attached are ignored. This is to avoid following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 			device links to "class" devices that are created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 			when the consumer probes (as in, not a probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 			dependency). If you want to follow these links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			anyway, use this flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)   --exclude-devlinks	Don't follow device links when tracking probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 			dependencies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)   --exclude-parents	Don't follow parent devices when tracking probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			dependencies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) EOF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) function dev_to_detail() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	local i=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	while [ $i -lt ${#OUT_LIST[@]} ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		local C=${OUT_LIST[i]}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		local S=${OUT_LIST[i+1]}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		local D="'$(detail_chosen $C $S)'"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		if [ ! -z "$D" ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			# This weirdness is needed to work with toybox when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			# using the -t option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			printf '%05u\t%s\n' ${i} "$D" | tr -d \'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		i=$((i+2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) function already_seen() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	local i=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	while [ $i -lt ${#OUT_LIST[@]} ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		if [ "$1" = "${OUT_LIST[$i]}" ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			# if-statement treats 0 (no-error) as true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		i=$(($i+2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	# if-statement treats 1 (error) as false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) # Return 0 (no-error/true) if parent was added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) function add_parent() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if [ ${ALLOW_PARENTS} -eq 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	local CON=$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	# $CON could be a symlink path. So, we need to find the real path and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	# then go up one level to find the real parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	local PARENT=$(realpath $CON/..)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	while [ ! -e ${PARENT}/driver ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if [ "$PARENT" = "/sys/devices" ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		PARENT=$(realpath $PARENT/..)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	CONSUMERS+=($PARENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	OUT_LIST+=(${CON} ${PARENT})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) # Return 0 (no-error/true) if one or more suppliers were added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) function add_suppliers() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	local CON=$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	local RET=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if [ ${ALLOW_DEVLINKS} -eq 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	SUPPLIER_LINKS=$(ls -1d $CON/supplier:* 2>/dev/null)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	for SL in $SUPPLIER_LINKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		SYNC_STATE=$(cat $SL/sync_state_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		# sync_state_only links are proxy dependencies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		# They can also have cycles. So, don't follow them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		if [ "$SYNC_STATE" != '0' ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		SUPPLIER=$(realpath $SL/supplier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		if [ ! -e $SUPPLIER/driver -a ${ALLOW_NO_DRIVER} -eq 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		CONSUMERS+=($SUPPLIER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		OUT_LIST+=(${CON} ${SUPPLIER})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		RET=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return $RET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) function detail_compat() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	f=$1/of_node/compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if [ -e $f ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		echo -n $(cat $f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		echo -n $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) function detail_module() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	f=$1/driver/module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if [ -e $f ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		echo -n $(basename $(realpath $f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		echo -n $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) function detail_driver() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	f=$1/driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if [ -e $f ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		echo -n $(basename $(realpath $f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		echo -n $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) function detail_fwnode() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	f=$1/firmware_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if [ ! -e $f ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		f=$1/of_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if [ -e $f ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		echo -n $(realpath $f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		echo -n $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) function detail_graphviz() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if [ "$2" != "ROOT" ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		echo -n "\"$(basename $2)\"->\"$(basename $1)\""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		echo -n "\"$(basename $1)\""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) function detail_tsort() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	echo -n "\"$2\" \"$1\""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) function detail_device() { echo -n $1; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) alias detail=detail_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ALLOW_NO_DRIVER=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ALLOW_DEVLINKS=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ALLOW_PARENTS=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) while [ $# -gt 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	ARG=$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	case $ARG in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		--help)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			exit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		-c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			alias detail=detail_compat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		-m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			alias detail=detail_module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		-d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			alias detail=detail_driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		-f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			alias detail=detail_fwnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		-g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			alias detail=detail_graphviz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		-t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			alias detail=detail_tsort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		--allow-no-driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			ALLOW_NO_DRIVER=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		--exclude-devlinks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			ALLOW_DEVLINKS=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		--exclude-parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			ALLOW_PARENTS=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			# Stop at the first argument that's not an option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	esac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) function detail_chosen() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	detail $1 $2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if [ $# -eq 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	exit 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) CONSUMERS=($@)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) OUT_LIST=()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) # Do a breadth first, non-recursive tracking of suppliers. The parent is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) # considered a "supplier" as a device can't probe without its parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) i=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) while [ $i -lt ${#CONSUMERS[@]} ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	CONSUMER=$(realpath ${CONSUMERS[$i]})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	i=$(($i+1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if already_seen ${CONSUMER}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	# If this is not a device with a driver, we don't care about its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	# suppliers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if [ ! -e ${CONSUMER}/driver -a ${ALLOW_NO_DRIVER} -eq 0 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	ROOT=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	# Add suppliers to CONSUMERS list and output the consumer details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	# We don't need to worry about a cycle in the dependency chain causing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	# infinite loops. That's because the kernel doesn't allow cycles in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	# device links unless it's a sync_state_only device link. And we ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	# sync_state_only device links inside add_suppliers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if add_suppliers ${CONSUMER}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		ROOT=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if add_parent ${CONSUMER}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		ROOT=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if [ $ROOT -eq 1 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		OUT_LIST+=(${CONSUMER} "ROOT")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) # Can NOT combine sort and uniq using sort -suk2 because stable sort in toybox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) # isn't really stable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_to_detail | sort -k2 -k1 | uniq -f 1 | sort | cut -f2-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) exit 0