Re: [PATCH 1/2] checks: add I2C bus checks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Thu, Jul 26, 2018 at 09:19:31PM -0600, Rob Herring wrote:
> Add I2C bus type detection and checks. The node name is used to find I2C
> buses as there is no common compatible or property which can be used to
> identify I2C controllers/buses. There are some common I2C properties,
> but they are not used frequently enough to match on.
> 
> Signed-off-by: Rob Herring <robh@xxxxxxxxxx>

Applied series, thanks.

> ---
>  checks.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/checks.c b/checks.c
> index a2cc1036c915..f0b9f87e8132 100644
> --- a/checks.c
> +++ b/checks.c
> @@ -962,6 +962,73 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
>  }
>  WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
>  
> +static const struct bus_type i2c_bus = {
> +	.name = "i2c-bus",
> +};
> +
> +static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
> +{
> +	if (strprefixeq(node->name, node->basenamelen, "i2c-bus") ||
> +	    strprefixeq(node->name, node->basenamelen, "i2c-arb")) {
> +		node->bus = &i2c_bus;
> +	} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
> +		struct node *child;
> +		for_each_child(node, child) {
> +			if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
> +				return;
> +		}
> +		node->bus = &i2c_bus;
> +	} else
> +		return;
> +
> +	if (!node->children)
> +		return;
> +
> +	if (node_addr_cells(node) != 1)
> +		FAIL(c, dti, node, "incorrect #address-cells for I2C bus");
> +	if (node_size_cells(node) != 0)
> +		FAIL(c, dti, node, "incorrect #size-cells for I2C bus");
> +
> +}
> +WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells);
> +
> +static void check_i2c_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];
> +	uint32_t reg = 0;
> +	int len;
> +	cell_t *cells = NULL;
> +
> +	if (!node->parent || (node->parent->bus != &i2c_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, "I2C bus unit address format error, expected \"%s\"",
> +		     unit_addr);
> +
> +	for (len = prop->val.len; len > 0; len -= 4) {
> +		reg = fdt32_to_cpu(*(cells++));
> +		if (reg > 0x3ff)
> +			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
> +				  reg);
> +
> +	}
> +}
> +WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
> +
>  static void check_unit_address_format(struct check *c, struct dt_info *dti,
>  				      struct node *node)
>  {
> @@ -1582,6 +1649,9 @@ static struct check *check_table[] = {
>  	&simple_bus_bridge,
>  	&simple_bus_reg,
>  
> +	&i2c_bus_bridge,
> +	&i2c_bus_reg,
> +
>  	&avoid_default_addr_size,
>  	&avoid_unnecessary_addr_size,
>  	&unique_unit_address,

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux