diff options
Diffstat (limited to 'drivers/i2c/i2c-mux.c')
| -rw-r--r-- | drivers/i2c/i2c-mux.c | 22 | 
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 1038c381aea..d94e0ce7827 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -88,9 +88,23 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)  	return parent->algo->functionality(parent);  } +/* Return all parent classes, merged */ +static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent) +{ +	unsigned int class = 0; + +	do { +		class |= parent->class; +		parent = i2c_parent_is_i2c_adapter(parent); +	} while (parent); + +	return class; +} +  struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,  				struct device *mux_dev,  				void *mux_priv, u32 force_nr, u32 chan_id, +				unsigned int class,  				int (*select) (struct i2c_adapter *,  					       void *, u32),  				int (*deselect) (struct i2c_adapter *, @@ -127,6 +141,14 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,  	priv->adap.algo_data = priv;  	priv->adap.dev.parent = &parent->dev; +	/* Sanity check on class */ +	if (i2c_mux_parent_classes(parent) & class) +		dev_err(&parent->dev, +			"Segment %d behind mux can't share classes with ancestors\n", +			chan_id); +	else +		priv->adap.class = class; +  	/*  	 * Try to populate the mux adapter's of_node, expands to  	 * nothing if !CONFIG_OF.  |