checks: Add bus checks for simple-bus buses
Add checks to identify simple-bus bus types and checks for child devices. Simple-bus type is generally identified by "simple-bus" compatible string. We also treat the root as a simple-bus, but only for child nodes with reg property. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>main
parent
33c3985226
commit
4c15d5da17
70
checks.c
70
checks.c
|
@ -813,6 +813,73 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no
|
|||
}
|
||||
WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge);
|
||||
|
||||
static const struct bus_type simple_bus = {
|
||||
.name = "simple-bus",
|
||||
};
|
||||
|
||||
static bool node_is_compatible(struct node *node, const char *compat)
|
||||
{
|
||||
struct property *prop;
|
||||
const char *str, *end;
|
||||
|
||||
prop = get_property(node, "compatible");
|
||||
if (!prop)
|
||||
return false;
|
||||
|
||||
for (str = prop->val.val, end = str + prop->val.len; str < end;
|
||||
str += strnlen(str, end - str) + 1) {
|
||||
if (strneq(str, compat, end - str))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
|
||||
{
|
||||
if (node_is_compatible(node, "simple-bus"))
|
||||
node->bus = &simple_bus;
|
||||
}
|
||||
WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
|
||||
|
||||
static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
|
||||
{
|
||||
struct property *prop;
|
||||
const char *unitname = get_unitname(node);
|
||||
char unit_addr[17];
|
||||
unsigned int size;
|
||||
uint64_t reg = 0;
|
||||
cell_t *cells = NULL;
|
||||
|
||||
if (!node->parent || (node->parent->bus != &simple_bus))
|
||||
return;
|
||||
|
||||
prop = get_property(node, "reg");
|
||||
if (prop)
|
||||
cells = (cell_t *)prop->val.val;
|
||||
else {
|
||||
prop = get_property(node, "ranges");
|
||||
if (prop && prop->val.len)
|
||||
/* skip of child address */
|
||||
cells = ((cell_t *)prop->val.val) + node_addr_cells(node);
|
||||
}
|
||||
|
||||
if (!cells) {
|
||||
if (node->parent->parent && !(node->bus == &simple_bus))
|
||||
FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
size = node_addr_cells(node->parent);
|
||||
while (size--)
|
||||
reg = (reg << 32) | fdt32_to_cpu(*(cells++));
|
||||
|
||||
snprintf(unit_addr, sizeof(unit_addr), "%lx", reg);
|
||||
if (!streq(unitname, unit_addr))
|
||||
FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
|
||||
node->fullpath, unit_addr);
|
||||
}
|
||||
WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge);
|
||||
|
||||
/*
|
||||
* Style checks
|
||||
*/
|
||||
|
@ -889,6 +956,9 @@ static struct check *check_table[] = {
|
|||
&pci_device_reg,
|
||||
&pci_device_bus_num,
|
||||
|
||||
&simple_bus_bridge,
|
||||
&simple_bus_reg,
|
||||
|
||||
&avoid_default_addr_size,
|
||||
&obsolete_chosen_interrupt_controller,
|
||||
|
||||
|
|
Loading…
Reference in New Issue