diff mbox series

[1/7] i2c: mux: add the ability to share mux-address with child nodes

Message ID 20240426-dev-mule-i2c-mux-v1-1-045a482f6ffb@theobroma-systems.com (mailing list archive)
State New
Headers show
Series Add Mule I2C multiplexer support | expand

Commit Message

Farouk Bouabid April 26, 2024, 4:49 p.m. UTC
Allow the mux to have the same address as a child device. This is useful
when the mux can only use an i2c-address that is used by a child device
because no other addresses are free to use. eg. the mux can only use
address 0x18 which is used by amc6821 connected to the mux.

Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
---
 drivers/i2c/i2c-mux.c   | 10 +++++++++-
 include/linux/i2c-mux.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

Comments

Peter Rosin April 29, 2024, 3:46 p.m. UTC | #1
Hi!

2024-04-26 at 18:49, Farouk Bouabid wrote:
> Allow the mux to have the same address as a child device. This is useful
> when the mux can only use an i2c-address that is used by a child device
> because no other addresses are free to use. eg. the mux can only use
> address 0x18 which is used by amc6821 connected to the mux.
> 
> Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
> ---
>  drivers/i2c/i2c-mux.c   | 10 +++++++++-
>  include/linux/i2c-mux.h |  1 +
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
> index 57ff09f18c37..f5357dff8cc5 100644
> --- a/drivers/i2c/i2c-mux.c
> +++ b/drivers/i2c/i2c-mux.c
> @@ -331,7 +331,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>  	priv->adap.owner = THIS_MODULE;
>  	priv->adap.algo = &priv->algo;
>  	priv->adap.algo_data = priv;
> -	priv->adap.dev.parent = &parent->dev;
>  	priv->adap.retries = parent->retries;
>  	priv->adap.timeout = parent->timeout;
>  	priv->adap.quirks = parent->quirks;
> @@ -348,6 +347,15 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>  	else
>  		priv->adap.class = class;
>  
> +	/*
> +	 * When creating the adapter, the node devices are checked for i2c address
> +	 * match with other devices on the parent adapter, among which is the mux itself.
> +	 * If a match is found the node device is not probed successfully.
> +	 * Allow the mux to have the same address as a child device by skipping this check.
> +	 */
> +	if (!(muxc->share_addr_with_children))
> +		priv->adap.dev.parent = &parent->dev;

This is a dirty hack that will not generally do the right thing.

The adapter device parent is not there solely for the purpose of
detecting address clashes, so the above has other implications
that are not desirable.

Therefore, NACK on this approach. It simply needs to be more involved.
Sorry.

Cheers,
Peter

> +
>  	/*
>  	 * Try to populate the mux adapter's of_node, expands to
>  	 * nothing if !CONFIG_OF.
> diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
> index 98ef73b7c8fd..17ac68bf1703 100644
> --- a/include/linux/i2c-mux.h
> +++ b/include/linux/i2c-mux.h
> @@ -21,6 +21,7 @@ struct i2c_mux_core {
>  	unsigned int mux_locked:1;
>  	unsigned int arbitrator:1;
>  	unsigned int gate:1;
> +	unsigned int share_addr_with_children:1;
>  
>  	void *priv;
>  
>
Farouk Bouabid May 2, 2024, 3:01 p.m. UTC | #2
Hi Peter,

On 29.04.24 17:46, Peter Rosin wrote:
> Hi!
>
> 2024-04-26 at 18:49, Farouk Bouabid wrote:
>> Allow the mux to have the same address as a child device. This is useful
>> when the mux can only use an i2c-address that is used by a child device
>> because no other addresses are free to use. eg. the mux can only use
>> address 0x18 which is used by amc6821 connected to the mux.
>>
>> Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
>> ---
>>   drivers/i2c/i2c-mux.c   | 10 +++++++++-
>>   include/linux/i2c-mux.h |  1 +
>>   2 files changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
>> index 57ff09f18c37..f5357dff8cc5 100644
>> --- a/drivers/i2c/i2c-mux.c
>> +++ b/drivers/i2c/i2c-mux.c
>> @@ -331,7 +331,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>   	priv->adap.owner = THIS_MODULE;
>>   	priv->adap.algo = &priv->algo;
>>   	priv->adap.algo_data = priv;
>> -	priv->adap.dev.parent = &parent->dev;
>>   	priv->adap.retries = parent->retries;
>>   	priv->adap.timeout = parent->timeout;
>>   	priv->adap.quirks = parent->quirks;
>> @@ -348,6 +347,15 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>   	else
>>   		priv->adap.class = class;
>>   
>> +	/*
>> +	 * When creating the adapter, the node devices are checked for i2c address
>> +	 * match with other devices on the parent adapter, among which is the mux itself.
>> +	 * If a match is found the node device is not probed successfully.
>> +	 * Allow the mux to have the same address as a child device by skipping this check.
>> +	 */
>> +	if (!(muxc->share_addr_with_children))
>> +		priv->adap.dev.parent = &parent->dev;
> This is a dirty hack that will not generally do the right thing.
>
> The adapter device parent is not there solely for the purpose of
> detecting address clashes, so the above has other implications
> that are not desirable.
>
> Therefore, NACK on this approach. It simply needs to be more involved.
> Sorry.
>
> Cheers,
> Peter
>

Another way to approach this is by implementing this flag as a quirk for 
the added adapter:

(tested but not cleaned up)

"""

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index ff5c486a1dbb..6a0237f750db 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -821,9 +821,21 @@ static int i2c_check_mux_children(struct device 
*dev, void *addrp)
  static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
  {
         struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+       bool skip_check = false;
         int result = 0;

-       if (parent)
+       if (adapter->quirks) {
+                if (adapter->quirks->flags & I2C_AQ_SHARE_ADDR) {
+                       struct i2c_client *client = 
of_find_i2c_device_by_node(adapter->dev.of_node->parent);
+
+                       if (client) {
+                               skip_check = client->addr == addr;
+                               put_device(&client->dev);
+                       }
+                }
+       }
+
+       if (parent && !skip_check)
                 result = i2c_check_mux_parents(parent, addr);

         if (!result)
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 57ff09f18c37..e87cb0e43725 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -334,7 +334,26 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
         priv->adap.dev.parent = &parent->dev;
         priv->adap.retries = parent->retries;
         priv->adap.timeout = parent->timeout;
-       priv->adap.quirks = parent->quirks;
+       /*
+        * When creating the adapter, the node devices are checked for 
i2c address
+        * match with other devices on the parent adapter, among which 
is the mux itself.
+        * If a match is found the node device is not probed successfully.
+        * Allow the mux to have the same address as a child device by 
skipping this check.
+        */
+       if (!muxc->share_addr_with_children)
+               priv->adap.quirks = parent->quirks;
+       else {
+               struct i2c_adapter_quirks *quirks = 
kzalloc(sizeof(*quirks), GFP_KERNEL);
+               if (!quirks)
+                       return -ENOMEM;
+
+               if (parent->quirks)
+                       *quirks = *(parent->quirks); // @fixme memcpy
+
+               quirks->flags |= I2C_AQ_SHARE_ADDR;
+               priv->adap.quirks = quirks;
+       }
+
         if (muxc->mux_locked)
                 priv->adap.lock_ops = &i2c_mux_lock_ops;
         else
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index 98ef73b7c8fd..17ac68bf1703 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -21,6 +21,7 @@ struct i2c_mux_core {
         unsigned int mux_locked:1;
         unsigned int arbitrator:1;
         unsigned int gate:1;
+       unsigned int share_addr_with_children:1;

         void *priv;

diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 5e6cd43a6dbd..2ebac9e672ef 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -711,6 +711,8 @@ struct i2c_adapter_quirks {
  #define I2C_AQ_NO_ZERO_LEN             (I2C_AQ_NO_ZERO_LEN_READ | 
I2C_AQ_NO_ZERO_LEN_WRITE)
  /* adapter cannot do repeated START */
  #define I2C_AQ_NO_REP_START            BIT(7)
+/* @fixme document and find proper name */
+#define I2C_AQ_SHARE_ADDR              BIT(8)

  /*
   * i2c_adapter is the structure used to identify a physical i2c bus along

"""

This works, however this only supports device-tree because of 
of_find_i2c_device_by_node. If we want to support acpi then we can either:


1. Get the Mule i2c device address from fwnode_get_next_parent_dev but 
this is static since v6.9-rcx.

2. Pass the Mule i2c device address as a new member of  struct 
i2c_adapter_quirks.


I would go for 2. Do you suggest something else?

Best regards

Farouk
Peter Rosin May 3, 2024, 5:30 a.m. UTC | #3
Hi!

2024-05-02 at 17:01, Farouk Bouabid wrote:
> Hi Peter,
> 
> On 29.04.24 17:46, Peter Rosin wrote:
>> Hi!
>>
>> 2024-04-26 at 18:49, Farouk Bouabid wrote:
>>> Allow the mux to have the same address as a child device. This is useful
>>> when the mux can only use an i2c-address that is used by a child device
>>> because no other addresses are free to use. eg. the mux can only use
>>> address 0x18 which is used by amc6821 connected to the mux.
>>>
>>> Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
>>> ---
>>>   drivers/i2c/i2c-mux.c   | 10 +++++++++-
>>>   include/linux/i2c-mux.h |  1 +
>>>   2 files changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
>>> index 57ff09f18c37..f5357dff8cc5 100644
>>> --- a/drivers/i2c/i2c-mux.c
>>> +++ b/drivers/i2c/i2c-mux.c
>>> @@ -331,7 +331,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>>       priv->adap.owner = THIS_MODULE;
>>>       priv->adap.algo = &priv->algo;
>>>       priv->adap.algo_data = priv;
>>> -    priv->adap.dev.parent = &parent->dev;
>>>       priv->adap.retries = parent->retries;
>>>       priv->adap.timeout = parent->timeout;
>>>       priv->adap.quirks = parent->quirks;
>>> @@ -348,6 +347,15 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>>       else
>>>           priv->adap.class = class;
>>>   +    /*
>>> +     * When creating the adapter, the node devices are checked for i2c address
>>> +     * match with other devices on the parent adapter, among which is the mux itself.
>>> +     * If a match is found the node device is not probed successfully.
>>> +     * Allow the mux to have the same address as a child device by skipping this check.
>>> +     */
>>> +    if (!(muxc->share_addr_with_children))
>>> +        priv->adap.dev.parent = &parent->dev;
>> This is a dirty hack that will not generally do the right thing.
>>
>> The adapter device parent is not there solely for the purpose of
>> detecting address clashes, so the above has other implications
>> that are not desirable.
>>
>> Therefore, NACK on this approach. It simply needs to be more involved.
>> Sorry.
>>
>> Cheers,
>> Peter
>>
> 
> Another way to approach this is by implementing this flag as a quirk for the added adapter:
> 
> (tested but not cleaned up)

Yes, good idea, this is much more targeted and generally feels a lot
better.

> 
> """
> 
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index ff5c486a1dbb..6a0237f750db 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -821,9 +821,21 @@ static int i2c_check_mux_children(struct device *dev, void *addrp)
>  static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
>  {
>         struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
> +       bool skip_check = false;
>         int result = 0;
> 
> -       if (parent)
> +       if (adapter->quirks) {
> +                if (adapter->quirks->flags & I2C_AQ_SHARE_ADDR) {
> +                       struct i2c_client *client = of_find_i2c_device_by_node(adapter->dev.of_node->parent);
> +
> +                       if (client) {
> +                               skip_check = client->addr == addr;
> +                               put_device(&client->dev);
> +                       }
> +                }
> +       }
> +
> +       if (parent && !skip_check)
>                 result = i2c_check_mux_parents(parent, addr);
> 
>         if (!result)
> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
> index 57ff09f18c37..e87cb0e43725 100644
> --- a/drivers/i2c/i2c-mux.c
> +++ b/drivers/i2c/i2c-mux.c
> @@ -334,7 +334,26 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>         priv->adap.dev.parent = &parent->dev;
>         priv->adap.retries = parent->retries;
>         priv->adap.timeout = parent->timeout;
> -       priv->adap.quirks = parent->quirks;
> +       /*
> +        * When creating the adapter, the node devices are checked for i2c address
> +        * match with other devices on the parent adapter, among which is the mux itself.
> +        * If a match is found the node device is not probed successfully.
> +        * Allow the mux to have the same address as a child device by skipping this check.
> +        */
> +       if (!muxc->share_addr_with_children)
> +               priv->adap.quirks = parent->quirks;
> +       else {
> +               struct i2c_adapter_quirks *quirks = kzalloc(sizeof(*quirks), GFP_KERNEL);

This leaks, dev_kzalloc?

> +               if (!quirks)
> +                       return -ENOMEM;
> +
> +               if (parent->quirks)
> +                       *quirks = *(parent->quirks); // @fixme memcpy
> +
> +               quirks->flags |= I2C_AQ_SHARE_ADDR;
> +               priv->adap.quirks = quirks;
> +       }
> +
>         if (muxc->mux_locked)
>                 priv->adap.lock_ops = &i2c_mux_lock_ops;
>         else
> diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
> index 98ef73b7c8fd..17ac68bf1703 100644
> --- a/include/linux/i2c-mux.h
> +++ b/include/linux/i2c-mux.h
> @@ -21,6 +21,7 @@ struct i2c_mux_core {
>         unsigned int mux_locked:1;
>         unsigned int arbitrator:1;
>         unsigned int gate:1;
> +       unsigned int share_addr_with_children:1;
> 
>         void *priv;
> 
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 5e6cd43a6dbd..2ebac9e672ef 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -711,6 +711,8 @@ struct i2c_adapter_quirks {
>  #define I2C_AQ_NO_ZERO_LEN             (I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_NO_ZERO_LEN_WRITE)
>  /* adapter cannot do repeated START */
>  #define I2C_AQ_NO_REP_START            BIT(7)
> +/* @fixme document and find proper name */
> +#define I2C_AQ_SHARE_ADDR              BIT(8)
> 
>  /*
>   * i2c_adapter is the structure used to identify a physical i2c bus along
> 
> """
> 
> This works, however this only supports device-tree because of of_find_i2c_device_by_node. If we want to support acpi then we can either:
> 
> 
> 1. Get the Mule i2c device address from fwnode_get_next_parent_dev but this is static since v6.9-rcx.
> 
> 2. Pass the Mule i2c device address as a new member of  struct i2c_adapter_quirks.
> 
> 
> I would go for 2. Do you suggest something else?

Yes, 2 is definitely neater.

Thanks!

Cheers,
Peter
Quentin Schulz May 3, 2024, 4:20 p.m. UTC | #4
Hi Peter,

On 5/3/24 7:30 AM, Peter Rosin wrote:
> Hi!
> 
> 2024-05-02 at 17:01, Farouk Bouabid wrote:
>> Hi Peter,
>>
>> On 29.04.24 17:46, Peter Rosin wrote:
>>> Hi!
>>>
>>> 2024-04-26 at 18:49, Farouk Bouabid wrote:
>>>> Allow the mux to have the same address as a child device. This is useful
>>>> when the mux can only use an i2c-address that is used by a child device
>>>> because no other addresses are free to use. eg. the mux can only use
>>>> address 0x18 which is used by amc6821 connected to the mux.
>>>>
>>>> Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
>>>> ---
>>>>    drivers/i2c/i2c-mux.c   | 10 +++++++++-
>>>>    include/linux/i2c-mux.h |  1 +
>>>>    2 files changed, 10 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
>>>> index 57ff09f18c37..f5357dff8cc5 100644
>>>> --- a/drivers/i2c/i2c-mux.c
>>>> +++ b/drivers/i2c/i2c-mux.c
>>>> @@ -331,7 +331,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>>>        priv->adap.owner = THIS_MODULE;
>>>>        priv->adap.algo = &priv->algo;
>>>>        priv->adap.algo_data = priv;
>>>> -    priv->adap.dev.parent = &parent->dev;
>>>>        priv->adap.retries = parent->retries;
>>>>        priv->adap.timeout = parent->timeout;
>>>>        priv->adap.quirks = parent->quirks;
>>>> @@ -348,6 +347,15 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>>>        else
>>>>            priv->adap.class = class;
>>>>    +    /*
>>>> +     * When creating the adapter, the node devices are checked for i2c address
>>>> +     * match with other devices on the parent adapter, among which is the mux itself.
>>>> +     * If a match is found the node device is not probed successfully.
>>>> +     * Allow the mux to have the same address as a child device by skipping this check.
>>>> +     */
>>>> +    if (!(muxc->share_addr_with_children))
>>>> +        priv->adap.dev.parent = &parent->dev;
>>> This is a dirty hack that will not generally do the right thing.
>>>
>>> The adapter device parent is not there solely for the purpose of
>>> detecting address clashes, so the above has other implications
>>> that are not desirable.
>>>
>>> Therefore, NACK on this approach. It simply needs to be more involved.
>>> Sorry.
>>>
>>> Cheers,
>>> Peter
>>>
>>
>> Another way to approach this is by implementing this flag as a quirk for the added adapter:
>>
>> (tested but not cleaned up)
> 
> Yes, good idea, this is much more targeted and generally feels a lot
> better.
> 
>>
>> """
>>
>> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
>> index ff5c486a1dbb..6a0237f750db 100644
>> --- a/drivers/i2c/i2c-core-base.c
>> +++ b/drivers/i2c/i2c-core-base.c
>> @@ -821,9 +821,21 @@ static int i2c_check_mux_children(struct device *dev, void *addrp)
>>   static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
>>   {
>>          struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
>> +       bool skip_check = false;
>>          int result = 0;
>>
>> -       if (parent)
>> +       if (adapter->quirks) {
>> +                if (adapter->quirks->flags & I2C_AQ_SHARE_ADDR) {
>> +                       struct i2c_client *client = of_find_i2c_device_by_node(adapter->dev.of_node->parent);
>> +
>> +                       if (client) {
>> +                               skip_check = client->addr == addr;
>> +                               put_device(&client->dev);
>> +                       }
>> +                }
>> +       }
>> +
>> +       if (parent && !skip_check)
>>                  result = i2c_check_mux_parents(parent, addr);
>>
>>          if (!result)
>> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
>> index 57ff09f18c37..e87cb0e43725 100644
>> --- a/drivers/i2c/i2c-mux.c
>> +++ b/drivers/i2c/i2c-mux.c
>> @@ -334,7 +334,26 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>>          priv->adap.dev.parent = &parent->dev;
>>          priv->adap.retries = parent->retries;
>>          priv->adap.timeout = parent->timeout;
>> -       priv->adap.quirks = parent->quirks;
>> +       /*
>> +        * When creating the adapter, the node devices are checked for i2c address
>> +        * match with other devices on the parent adapter, among which is the mux itself.
>> +        * If a match is found the node device is not probed successfully.
>> +        * Allow the mux to have the same address as a child device by skipping this check.
>> +        */
>> +       if (!muxc->share_addr_with_children)
>> +               priv->adap.quirks = parent->quirks;
>> +       else {
>> +               struct i2c_adapter_quirks *quirks = kzalloc(sizeof(*quirks), GFP_KERNEL);
> 
> This leaks, dev_kzalloc?
> 

Quick questions about this though.

priv is allocated with kzalloc and not devm_kzalloc and is then manually 
kfree'd either as part of the error path or in i2c_del_mux_adapters. Is 
there a reason for this? Shouldn't we migrate this to devm allocation as 
well?

Similarly, I was wondering if we couldn't add a devm_add_action_or_reset 
for i2c_del_mux_adapters in i2c_add_mux_adapter? Is there something that 
prevents us from doing this?

Cheers,
Quentin
diff mbox series

Patch

diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 57ff09f18c37..f5357dff8cc5 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -331,7 +331,6 @@  int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 	priv->adap.owner = THIS_MODULE;
 	priv->adap.algo = &priv->algo;
 	priv->adap.algo_data = priv;
-	priv->adap.dev.parent = &parent->dev;
 	priv->adap.retries = parent->retries;
 	priv->adap.timeout = parent->timeout;
 	priv->adap.quirks = parent->quirks;
@@ -348,6 +347,15 @@  int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 	else
 		priv->adap.class = class;
 
+	/*
+	 * When creating the adapter, the node devices are checked for i2c address
+	 * match with other devices on the parent adapter, among which is the mux itself.
+	 * If a match is found the node device is not probed successfully.
+	 * Allow the mux to have the same address as a child device by skipping this check.
+	 */
+	if (!(muxc->share_addr_with_children))
+		priv->adap.dev.parent = &parent->dev;
+
 	/*
 	 * Try to populate the mux adapter's of_node, expands to
 	 * nothing if !CONFIG_OF.
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index 98ef73b7c8fd..17ac68bf1703 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -21,6 +21,7 @@  struct i2c_mux_core {
 	unsigned int mux_locked:1;
 	unsigned int arbitrator:1;
 	unsigned int gate:1;
+	unsigned int share_addr_with_children:1;
 
 	void *priv;