| # SPDX-License-Identifier: GPL-2.0 | |
| # | |
| # Copyright (c) NXP 2019 | |
| import gdb | |
| import sys | |
| from linux.utils import CachedType, gdb_eval_or_none | |
| from linux.lists import list_for_each_entry | |
| generic_pm_domain_type = CachedType('struct generic_pm_domain') | |
| pm_domain_data_type = CachedType('struct pm_domain_data') | |
| device_link_type = CachedType('struct device_link') | |
| def kobject_get_path(kobj): | |
| path = kobj['name'].string() | |
| parent = kobj['parent'] | |
| if parent: | |
| path = kobject_get_path(parent) + '/' + path | |
| return path | |
| def rtpm_status_str(dev): | |
| if dev['power']['runtime_error']: | |
| return 'error' | |
| if dev['power']['disable_depth']: | |
| return 'unsupported' | |
| _RPM_STATUS_LOOKUP = [ | |
| "active", | |
| "resuming", | |
| "suspended", | |
| "suspending" | |
| ] | |
| return _RPM_STATUS_LOOKUP[dev['power']['runtime_status']] | |
| class LxGenPDSummary(gdb.Command): | |
| '''Print genpd summary | |
| Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' | |
| def __init__(self): | |
| super(LxGenPDSummary, self).__init__('lx-genpd-summary', gdb.COMMAND_DATA) | |
| def summary_one(self, genpd): | |
| if genpd['status'] == 0: | |
| status_string = 'on' | |
| else: | |
| status_string = 'off-{}'.format(genpd['state_idx']) | |
| child_names = [] | |
| for link in list_for_each_entry( | |
| genpd['parent_links'], | |
| device_link_type.get_type().pointer(), | |
| 'parent_node'): | |
| child_names.append(link['child']['name']) | |
| gdb.write('%-30s %-15s %s\n' % ( | |
| genpd['name'].string(), | |
| status_string, | |
| ', '.join(child_names))) | |
| # Print devices in domain | |
| for pm_data in list_for_each_entry(genpd['dev_list'], | |
| pm_domain_data_type.get_type().pointer(), | |
| 'list_node'): | |
| dev = pm_data['dev'] | |
| kobj_path = kobject_get_path(dev['kobj']) | |
| gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev))) | |
| def invoke(self, arg, from_tty): | |
| if gdb_eval_or_none("&gpd_list") is None: | |
| raise gdb.GdbError("No power domain(s) registered") | |
| gdb.write('domain status children\n'); | |
| gdb.write(' /device runtime status\n'); | |
| gdb.write('----------------------------------------------------------------------\n'); | |
| for genpd in list_for_each_entry( | |
| gdb.parse_and_eval('&gpd_list'), | |
| generic_pm_domain_type.get_type().pointer(), | |
| 'gpd_list_node'): | |
| self.summary_one(genpd) | |
| LxGenPDSummary() |