diff options
Diffstat (limited to 'scripts/dtc/checks.c')
| -rw-r--r-- | scripts/dtc/checks.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index a2cc1036c915..9c9b0c328af6 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c | |||
| @@ -962,6 +962,143 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no | |||
| 962 | } | 962 | } |
| 963 | WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); | 963 | WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); |
| 964 | 964 | ||
| 965 | static const struct bus_type i2c_bus = { | ||
| 966 | .name = "i2c-bus", | ||
| 967 | }; | ||
| 968 | |||
| 969 | static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) | ||
| 970 | { | ||
| 971 | if (strprefixeq(node->name, node->basenamelen, "i2c-bus") || | ||
| 972 | strprefixeq(node->name, node->basenamelen, "i2c-arb")) { | ||
| 973 | node->bus = &i2c_bus; | ||
| 974 | } else if (strprefixeq(node->name, node->basenamelen, "i2c")) { | ||
| 975 | struct node *child; | ||
| 976 | for_each_child(node, child) { | ||
| 977 | if (strprefixeq(child->name, node->basenamelen, "i2c-bus")) | ||
| 978 | return; | ||
| 979 | } | ||
| 980 | node->bus = &i2c_bus; | ||
| 981 | } else | ||
| 982 | return; | ||
| 983 | |||
| 984 | if (!node->children) | ||
| 985 | return; | ||
| 986 | |||
| 987 | if (node_addr_cells(node) != 1) | ||
| 988 | FAIL(c, dti, node, "incorrect #address-cells for I2C bus"); | ||
| 989 | if (node_size_cells(node) != 0) | ||
| 990 | FAIL(c, dti, node, "incorrect #size-cells for I2C bus"); | ||
| 991 | |||
| 992 | } | ||
| 993 | WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells); | ||
| 994 | |||
| 995 | static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node) | ||
| 996 | { | ||
| 997 | struct property *prop; | ||
| 998 | const char *unitname = get_unitname(node); | ||
| 999 | char unit_addr[17]; | ||
| 1000 | uint32_t reg = 0; | ||
| 1001 | int len; | ||
| 1002 | cell_t *cells = NULL; | ||
| 1003 | |||
| 1004 | if (!node->parent || (node->parent->bus != &i2c_bus)) | ||
| 1005 | return; | ||
| 1006 | |||
| 1007 | prop = get_property(node, "reg"); | ||
| 1008 | if (prop) | ||
| 1009 | cells = (cell_t *)prop->val.val; | ||
| 1010 | |||
| 1011 | if (!cells) { | ||
| 1012 | FAIL(c, dti, node, "missing or empty reg property"); | ||
| 1013 | return; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | reg = fdt32_to_cpu(*cells); | ||
| 1017 | snprintf(unit_addr, sizeof(unit_addr), "%x", reg); | ||
| 1018 | if (!streq(unitname, unit_addr)) | ||
| 1019 | FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"", | ||
| 1020 | unit_addr); | ||
| 1021 | |||
| 1022 | for (len = prop->val.len; len > 0; len -= 4) { | ||
| 1023 | reg = fdt32_to_cpu(*(cells++)); | ||
| 1024 | if (reg > 0x3ff) | ||
| 1025 | FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", | ||
| 1026 | reg); | ||
| 1027 | |||
| 1028 | } | ||
| 1029 | } | ||
| 1030 | WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, ®_format, &i2c_bus_bridge); | ||
| 1031 | |||
| 1032 | static const struct bus_type spi_bus = { | ||
| 1033 | .name = "spi-bus", | ||
| 1034 | }; | ||
| 1035 | |||
| 1036 | static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) | ||
| 1037 | { | ||
| 1038 | |||
| 1039 | if (strprefixeq(node->name, node->basenamelen, "spi")) { | ||
| 1040 | node->bus = &spi_bus; | ||
| 1041 | } else { | ||
| 1042 | /* Try to detect SPI buses which don't have proper node name */ | ||
| 1043 | struct node *child; | ||
| 1044 | |||
| 1045 | if (node_addr_cells(node) != 1 || node_size_cells(node) != 0) | ||
| 1046 | return; | ||
| 1047 | |||
| 1048 | for_each_child(node, child) { | ||
| 1049 | struct property *prop; | ||
| 1050 | for_each_property(child, prop) { | ||
| 1051 | if (strprefixeq(prop->name, 4, "spi-")) { | ||
| 1052 | node->bus = &spi_bus; | ||
| 1053 | break; | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | if (node->bus == &spi_bus) | ||
| 1057 | break; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | if (node->bus == &spi_bus && get_property(node, "reg")) | ||
| 1061 | FAIL(c, dti, node, "node name for SPI buses should be 'spi'"); | ||
| 1062 | } | ||
| 1063 | if (node->bus != &spi_bus || !node->children) | ||
| 1064 | return; | ||
| 1065 | |||
| 1066 | if (node_addr_cells(node) != 1) | ||
| 1067 | FAIL(c, dti, node, "incorrect #address-cells for SPI bus"); | ||
| 1068 | if (node_size_cells(node) != 0) | ||
| 1069 | FAIL(c, dti, node, "incorrect #size-cells for SPI bus"); | ||
| 1070 | |||
| 1071 | } | ||
| 1072 | WARNING(spi_bus_bridge, check_spi_bus_bridge, NULL, &addr_size_cells); | ||
| 1073 | |||
| 1074 | static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node) | ||
| 1075 | { | ||
| 1076 | struct property *prop; | ||
| 1077 | const char *unitname = get_unitname(node); | ||
| 1078 | char unit_addr[9]; | ||
| 1079 | uint32_t reg = 0; | ||
| 1080 | cell_t *cells = NULL; | ||
| 1081 | |||
| 1082 | if (!node->parent || (node->parent->bus != &spi_bus)) | ||
| 1083 | return; | ||
| 1084 | |||
| 1085 | prop = get_property(node, "reg"); | ||
| 1086 | if (prop) | ||
| 1087 | cells = (cell_t *)prop->val.val; | ||
| 1088 | |||
| 1089 | if (!cells) { | ||
| 1090 | FAIL(c, dti, node, "missing or empty reg property"); | ||
| 1091 | return; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | reg = fdt32_to_cpu(*cells); | ||
| 1095 | snprintf(unit_addr, sizeof(unit_addr), "%x", reg); | ||
| 1096 | if (!streq(unitname, unit_addr)) | ||
| 1097 | FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"", | ||
| 1098 | unit_addr); | ||
| 1099 | } | ||
| 1100 | WARNING(spi_bus_reg, check_spi_bus_reg, NULL, ®_format, &spi_bus_bridge); | ||
| 1101 | |||
| 965 | static void check_unit_address_format(struct check *c, struct dt_info *dti, | 1102 | static void check_unit_address_format(struct check *c, struct dt_info *dti, |
| 966 | struct node *node) | 1103 | struct node *node) |
| 967 | { | 1104 | { |
| @@ -1582,6 +1719,12 @@ static struct check *check_table[] = { | |||
| 1582 | &simple_bus_bridge, | 1719 | &simple_bus_bridge, |
| 1583 | &simple_bus_reg, | 1720 | &simple_bus_reg, |
| 1584 | 1721 | ||
| 1722 | &i2c_bus_bridge, | ||
| 1723 | &i2c_bus_reg, | ||
| 1724 | |||
| 1725 | &spi_bus_bridge, | ||
| 1726 | &spi_bus_reg, | ||
| 1727 | |||
| 1585 | &avoid_default_addr_size, | 1728 | &avoid_default_addr_size, |
| 1586 | &avoid_unnecessary_addr_size, | 1729 | &avoid_unnecessary_addr_size, |
| 1587 | &unique_unit_address, | 1730 | &unique_unit_address, |
