Skip to content

Commit

Permalink
scripts: extract_dts_includes.py: refactor for better maintenance
Browse files Browse the repository at this point in the history
Refactor for better maintenance and to ease future enhancements.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
  • Loading branch information
b0661 authored and galak committed Jul 3, 2018
1 parent ad15056 commit 08216f5
Show file tree
Hide file tree
Showing 8 changed files with 709 additions and 170 deletions.
150 changes: 150 additions & 0 deletions scripts/dts/extract/clocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#
# Copyright (c) 2018 Bobby Noelte
#
# SPDX-License-Identifier: Apache-2.0
#

from extract.globals import *
from extract.directive import DTDirective

##
# @brief Manage clocks related directives.
#
# Handles:
# - clocks
# directives.
#
class DTClocks(DTDirective):

def __init__(self):
pass

def _extract_consumer(self, node_address, yaml, clocks, names, defs, def_label):

clock_consumer = reduced[node_address]
clock_consumer_compat = get_compat(node_address)
clock_consumer_bindings = yaml[clock_consumer_compat]
clock_consumer_label = self.get_node_label_string(node_address)

clock_index = 0
clock_cell_index = 0
nr_clock_cells = 0
clock_provider_node_address = ''
clock_provider = {}
for cell in clocks:
if clock_cell_index == 0:
if cell not in phandles:
raise Exception(
("Could not find the clock provider node {} for clocks"
" = {} in clock consumer node {}. Did you activate"
" the clock node?. Last clock provider: {}.")
.format(str(cell), str(clocks), node_address,
str(clock_provider)))
clock_provider_node_address = phandles[cell]
clock_provider = reduced[clock_provider_node_address]
clock_provider_compat = get_compat(clock_provider_node_address)
clock_provider_bindings = yaml[clock_provider_compat]
clock_provider_label = self.get_node_label_string( \
clock_provider_node_address)
nr_clock_cells = int(clock_provider['props'].get(
'#clock-cells', 0))
clock_cells_string = clock_provider_bindings.get(
'cell_string', 'CLOCK')
clock_cells_names = clock_provider_bindings.get(
'#cells', ['ID', 'CELL1', "CELL2", "CELL3"])
clock_cells = []
else:
clock_cells.append(cell)
clock_cell_index += 1
if clock_cell_index > nr_clock_cells:
# clock consumer device - clocks info
#####################################
prop_def = {}
prop_alias = {}

# Legacy clocks definitions by extract_cells
for i, cell in enumerate(clock_cells):
if i >= len(clock_cells_names):
clock_cell_name = 'CELL{}'.format(i)
else:
clock_cell_name = clock_cells_names[i]
if clock_cells_string == clock_cell_name:
clock_label = self.get_label_string([
clock_consumer_label, clock_cells_string,
str(clock_index)])
else:
clock_label = self.get_label_string([
clock_consumer_label, clock_cells_string,
clock_cell_name, str(clock_index)])
prop_def[clock_label] = str(cell)
# alias
if i < nr_clock_cells:
# clocks info for first clock
clock_alias_label = self.get_label_string([
clock_consumer_label, clock_cells_string,
clock_cell_name])
prop_alias[clock_alias_label] = clock_label
# Legacy clocks definitions by extract_controller
clock_provider_label_str = clock_provider['props'].get('label',
None)
if clock_provider_label_str is not None:
try:
generation = clock_consumer_bindings['properties'][
'clocks']['generation']
except:
generation = ''
if 'use-prop-name' in generation:
clock_cell_name = 'CLOCKS_CONTROLLER'
else:
clock_cell_name = 'CLOCK_CONTROLLER'
if clock_index == 0 and \
len(clocks) == (len(clock_cells) + 1):
index = ''
else:
index = str(clock_index)
clock_label = self.get_label_string([clock_consumer_label,
clock_cell_name,
index])
prop_def[clock_label] = '"' + clock_provider_label_str + '"'
if node_address in aliases:
for alias in aliases[node_address]:
clock_alias_label = self.get_label_string([
alias, clock_cell_name, index])
prop_alias[clock_alias_label] = clock_label

insert_defs(node_address, defs, prop_def, prop_alias)

clock_cell_index = 0
clock_index += 1

##
# @brief Extract clocks related directives
#
# @param node_address Address of node owning the clockxxx definition.
# @param yaml YAML definition for the owning node.
# @param prop clockxxx property name
# @param names (unused)
# @param[out] defs Property definitions for each node address
# @param def_label Define label string of node owning the directive.
#
def extract(self, node_address, yaml, prop, names, defs, def_label):

properties = reduced[node_address]['props'][prop]

prop_list = []
if not isinstance(properties, list):
prop_list.append(properties)
else:
prop_list = list(properties)

if prop == 'clocks':
# indicator for clock consumers
self._extract_consumer(node_address, yaml, prop_list, names, defs, def_label)
else:
raise Exception(
"DTClocks.extract called with unexpected directive ({})."
.format(prop))

##
# @brief Management information for clocks.
clocks = DTClocks()
62 changes: 62 additions & 0 deletions scripts/dts/extract/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#
# Copyright (c) 2018 Bobby Noelte
#
# SPDX-License-Identifier: Apache-2.0
#

from extract.globals import *
from extract.directive import DTDirective

##
# @brief Manage directives in a default way.
#
class DTDefault(DTDirective):

def __init__(self):
pass

##
# @brief Extract directives in a default way
#
# @param node_address Address of node owning the clockxxx definition.
# @param yaml YAML definition for the owning node.
# @param prop property name
# @param names (unused)
# @param[out] defs Property definitions for each node address
# @param def_label Define label string of node owning the directive.
#
def extract(self, node_address, yaml, prop, names, defs, def_label):
prop_def = {}
prop_alias = {}
prop_values = reduced[node_address]['props'][prop]

if isinstance(prop_values, list):
for i, prop_value in enumerate(prop_values):
prop_name = convert_string_to_label(prop)
label = def_label + '_' + prop_name
if isinstance(prop_value, str):
prop_value = "\"" + prop_value + "\""
prop_def[label + '_' + str(i)] = prop_value
else:
prop_name = convert_string_to_label(prop)
label = def_label + '_' + prop_name

if prop_values == 'parent-label':
prop_values = find_parent_prop(node_address, 'label')

if isinstance(prop_values, str):
prop_values = "\"" + prop_values + "\""
prop_def[label] = prop_values

# generate defs for node aliases
if node_address in aliases:
for i in aliases[node_address]:
alias_label = convert_string_to_label(i)
alias = alias_label + '_' + prop_name
prop_alias[alias] = label

insert_defs(node_address, defs, prop_def, prop_alias)

##
# @brief Management information for directives handled by default.
default = DTDefault()
65 changes: 65 additions & 0 deletions scripts/dts/extract/directive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#
# Copyright (c) 2018 Bobby Noelte
#
# SPDX-License-Identifier: Apache-2.0
#

from .globals import *

##
# @brief Base class for device tree directives
#
class DTDirective(object):

##
# @brief Get a label string for a list of label sub-strings.
#
# Label sub-strings are concatenated by '_'.
#
# @param label List of label sub-strings
# @return label string
#
@staticmethod
def get_label_string(label):
return convert_string_to_label(
'_'.join(x.strip() for x in label if x.strip()))


##
# @brief Get label string for a node by address
#
# @param node_address Address of node
# @return label string
#
@staticmethod
def get_node_label_string(node_address):
node = reduced[node_address]
node_compat = get_compat(node_address)
if node_compat is None:
raise Exception(
"No compatible property for node address {}."
.format(node_address))
label = convert_string_to_label(node_compat.upper())
if '@' in node_address:
label += '_' + node_address.split('@')[-1].upper()
elif 'reg' in node['props']:
label += '_' + hex(node['props']['reg'][0])[2:].zfill(8)
else:
label += convert_string_to_label(node_address.upper())
return label

def __init__():
pass

##
# @brief Extract directive information.
#
# @param node_address Address of node issueuing the directive.
# @param yaml YAML definition for the node.
# @param prop Directive property name
# @param names Names assigned to directive.
# @param[out] defs Property definitions for each node address
# @param def_label Define label string of node owning the directive.
#
def extract(self, node_address, yaml, prop, names, defs, def_label):
pass
Loading

0 comments on commit 08216f5

Please sign in to comment.