From 760071a0be8ae4820b3325db591254bca04a9a4f Mon Sep 17 00:00:00 2001 From: Ciro Nishiguchi Date: Wed, 13 Jan 2021 17:54:12 -0600 Subject: mpm: add helper for symbol lookup Add a helper that can lookup a device via a device tree symbol. Co-authored-by: Lars Amsel Co-authored-by: Michael Auchter --- mpm/python/usrp_mpm/sys_utils/udev.py | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'mpm/python') diff --git a/mpm/python/usrp_mpm/sys_utils/udev.py b/mpm/python/usrp_mpm/sys_utils/udev.py index 70b3bcb65..ef79ed747 100644 --- a/mpm/python/usrp_mpm/sys_utils/udev.py +++ b/mpm/python/usrp_mpm/sys_utils/udev.py @@ -8,7 +8,65 @@ Utilities for udev lookups """ import os +import glob import pyudev +from pathlib import Path + +DT_BASE = "/proc/device-tree" + +def get_eeprom_paths_by_symbol(symbol_name_glob): + """ + Searches for EEPROM file locaction of symbol names under + /proc/device-tree/__symbols__. + args: symbol_name_glob: symbol name(s) to search (allows glob expressions) + returns: dictionary with name found under __symbols__ as key + and corresponding nvmem file path as value. + The dictionary keys are sorted alphabetically. + raises: FileNotFoundExcepiton: in case a symbol file could not be read. + """ + symbol_base = os.path.join(DT_BASE, "__symbols__") + context = pyudev.Context() + devices = context.list_devices(subsystem="nvmem") + of_nodes = [os.path.join(dev.sys_path, "of_node") for dev in devices] + + def read_symbol_file(symbol_file): + with open(symbol_file) as f: + symbol_path = f.read() + # remove leading slash and trailing terminating char before + # building the full path for symbol + symbol_path = os.path.join(DT_BASE, symbol_path[1:-1]) + return symbol_path + + def find_device_path(path): + for dev in of_nodes: + if not os.path.exists(dev): + # not all nvmem devices have an of_node + continue + elif os.path.samefile(dev, path): + return os.path.join(os.path.dirname(dev), "nvmem") + return None + + eeproms = glob.glob(os.path.join(symbol_base, symbol_name_glob)) + paths = {os.path.basename(eeprom): read_symbol_file(eeprom) + for eeprom in eeproms} + return {name: find_device_path(path) + for name, path in sorted(paths.items())} + + +def get_device_from_dt_symbol(symbol, subsystem=None, context=None): + """ + Return the device associated with the device tree symbol, which usually + is a label on a specific node of interest + """ + symfile = Path(DT_BASE) / '__symbols__' / symbol + fullname = symfile.read_text() + if context is None: + context = pyudev.Context() + devices = list(context.list_devices(OF_FULLNAME=fullname, subsystem=subsystem)) + if not devices: + return None + return devices[0] + def get_eeprom_paths(address): """ @@ -41,3 +99,26 @@ def get_spidev_nodes(spi_master): for device in context.list_devices(parent=parent, subsystem="spidev") ] +def get_device_from_symbol(symbol, subsystems): + """ + Find the first device and return its name where the parent device the DT + symbol name matches and the hierarchy of subsystems (e.g. ['spi', 'spidev']) + match + """ + assert isinstance(subsystems,list) + context = pyudev.Context() + device = get_device_from_dt_symbol(symbol, subsystem=subsystems.pop(0), context=context) + if device is None: + return None + for subsystem in subsystems: + devices = list(context.list_devices(parent=device, subsystem=subsystem)) + if not devices: + return None + device = devices[0] + return device.properties.get('DEVNAME') + +def dt_symbol_get_spidev(symbol): + """ + Return spidev associated with the given device tree symbol + """ + return get_device_from_symbol(symbol, ['spi', 'spidev']) -- cgit v1.2.3