summaryrefslogtreecommitdiff
path: root/checks.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2018-07-26 21:19:32 -0600
committerDavid Gibson <david@gibson.dropbear.id.au>2018-07-27 13:42:50 +1000
commit90a190eb04d926655b643328ae995336568b705b (patch)
tree0905e17b92ab1d90770403c4e24c4dfefd7ca6d5 /checks.c
parent53a1bd5469055af7049a0ddaf00524a56d21bca2 (diff)
downloaddevice-tree-compiler-90a190eb04d926655b643328ae995336568b705b.tar.gz
checks: add SPI bus checks
Add SPI bus type detection and checks. The node name is the preferred way to find SPI buses as there is no common compatible or property which can be used. There are a few common properties used in child nodes, so they can be used as a fallback detection method. This lets us warn if the SPI controller is not properly named 'spi@...'. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'checks.c')
-rw-r--r--checks.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/checks.c b/checks.c
index f0b9f87..9c9b0c3 100644
--- a/checks.c
+++ b/checks.c
@@ -1029,6 +1029,76 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
}
WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
+static const struct bus_type spi_bus = {
+ .name = "spi-bus",
+};
+
+static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
+{
+
+ if (strprefixeq(node->name, node->basenamelen, "spi")) {
+ node->bus = &spi_bus;
+ } else {
+ /* Try to detect SPI buses which don't have proper node name */
+ struct node *child;
+
+ if (node_addr_cells(node) != 1 || node_size_cells(node) != 0)
+ return;
+
+ for_each_child(node, child) {
+ struct property *prop;
+ for_each_property(child, prop) {
+ if (strprefixeq(prop->name, 4, "spi-")) {
+ node->bus = &spi_bus;
+ break;
+ }
+ }
+ if (node->bus == &spi_bus)
+ break;
+ }
+
+ if (node->bus == &spi_bus && get_property(node, "reg"))
+ FAIL(c, dti, node, "node name for SPI buses should be 'spi'");
+ }
+ if (node->bus != &spi_bus || !node->children)
+ return;
+
+ if (node_addr_cells(node) != 1)
+ FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
+ if (node_size_cells(node) != 0)
+ FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
+
+}
+WARNING(spi_bus_bridge, check_spi_bus_bridge, NULL, &addr_size_cells);
+
+static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct property *prop;
+ const char *unitname = get_unitname(node);
+ char unit_addr[9];
+ uint32_t reg = 0;
+ cell_t *cells = NULL;
+
+ if (!node->parent || (node->parent->bus != &spi_bus))
+ return;
+
+ prop = get_property(node, "reg");
+ if (prop)
+ cells = (cell_t *)prop->val.val;
+
+ if (!cells) {
+ FAIL(c, dti, node, "missing or empty reg property");
+ return;
+ }
+
+ reg = fdt32_to_cpu(*cells);
+ snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
+ if (!streq(unitname, unit_addr))
+ FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"",
+ unit_addr);
+}
+WARNING(spi_bus_reg, check_spi_bus_reg, NULL, &reg_format, &spi_bus_bridge);
+
static void check_unit_address_format(struct check *c, struct dt_info *dti,
struct node *node)
{
@@ -1652,6 +1722,9 @@ static struct check *check_table[] = {
&i2c_bus_bridge,
&i2c_bus_reg,
+ &spi_bus_bridge,
+ &spi_bus_reg,
+
&avoid_default_addr_size,
&avoid_unnecessary_addr_size,
&unique_unit_address,