Skip to content

Commit 1835530

Browse files
Demon000Wolfram Sang
authored andcommitted
i2c: atr: add static flag
Some I2C ATRs do not support dynamic remapping, only static mapping of direct children. Mappings will only be added or removed as a result of devices being added or removed from a child bus. The ATR pool will have to be big enough to accommodate all devices expected to be added to the child buses. Add a new flag that prevents old mappings to be replaced or new mappings to be created in the alias finding code paths. That mens adding a flags parameter to i2c_atr_new() and an i2c_atr_flags enum. Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Reviewed-by: Romain Gantois <romain.gantois@bootlin.com> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
1 parent b09d8a9 commit 1835530

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

drivers/i2c/i2c-atr.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct i2c_atr_chan {
106106
* @lock: Lock for the I2C bus segment (see &struct i2c_lock_operations)
107107
* @lock_key: Lock key for @lock
108108
* @max_adapters: Maximum number of adapters this I2C ATR can have
109+
* @flags: Flags for ATR
109110
* @alias_pool: Optional common pool of available client aliases
110111
* @i2c_nb: Notifier for remote client add & del events
111112
* @adapter: Array of adapters
@@ -122,6 +123,7 @@ struct i2c_atr {
122123
struct mutex lock;
123124
struct lock_class_key lock_key;
124125
int max_adapters;
126+
u32 flags;
125127

126128
struct i2c_atr_alias_pool *alias_pool;
127129

@@ -339,12 +341,16 @@ i2c_atr_replace_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
339341
static struct i2c_atr_alias_pair *
340342
i2c_atr_get_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
341343
{
344+
struct i2c_atr *atr = chan->atr;
342345
struct i2c_atr_alias_pair *c2a;
343346

344347
c2a = i2c_atr_find_mapping_by_addr(chan, addr);
345348
if (c2a)
346349
return c2a;
347350

351+
if (atr->flags & I2C_ATR_F_STATIC)
352+
return NULL;
353+
348354
c2a = i2c_atr_create_mapping_by_addr(chan, addr);
349355
if (c2a)
350356
return c2a;
@@ -543,7 +549,7 @@ static int i2c_atr_attach_addr(struct i2c_adapter *adapter,
543549
mutex_lock(&chan->alias_pairs_lock);
544550

545551
c2a = i2c_atr_create_mapping_by_addr(chan, addr);
546-
if (!c2a)
552+
if (!c2a && !(atr->flags & I2C_ATR_F_STATIC))
547553
c2a = i2c_atr_replace_mapping_by_addr(chan, addr);
548554

549555
if (!c2a) {
@@ -703,7 +709,8 @@ static int i2c_atr_parse_alias_pool(struct i2c_atr *atr)
703709
}
704710

705711
struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
706-
const struct i2c_atr_ops *ops, int max_adapters)
712+
const struct i2c_atr_ops *ops, int max_adapters,
713+
u32 flags)
707714
{
708715
struct i2c_atr *atr;
709716
int ret;
@@ -725,6 +732,7 @@ struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
725732
atr->dev = dev;
726733
atr->ops = ops;
727734
atr->max_adapters = max_adapters;
735+
atr->flags = flags;
728736

729737
if (parent->algo->master_xfer)
730738
atr->algo.master_xfer = i2c_atr_master_xfer;

drivers/media/i2c/ds90ub960.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ static int ub960_init_atr(struct ub960_data *priv)
11221122
struct i2c_adapter *parent_adap = priv->client->adapter;
11231123

11241124
priv->atr = i2c_atr_new(parent_adap, dev, &ub960_atr_ops,
1125-
priv->hw_data->num_rxports);
1125+
priv->hw_data->num_rxports, 0);
11261126
if (IS_ERR(priv->atr))
11271127
return PTR_ERR(priv->atr);
11281128

drivers/misc/ti_fpc202.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static int fpc202_probe(struct i2c_client *client)
349349
goto disable_gpio;
350350
}
351351

352-
priv->atr = i2c_atr_new(client->adapter, dev, &fpc202_atr_ops, 2);
352+
priv->atr = i2c_atr_new(client->adapter, dev, &fpc202_atr_ops, 2, 0);
353353
if (IS_ERR(priv->atr)) {
354354
ret = PTR_ERR(priv->atr);
355355
dev_err(dev, "failed to create i2c atr err %d\n", ret);

include/linux/i2c-atr.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ struct device;
1818
struct fwnode_handle;
1919
struct i2c_atr;
2020

21+
/**
22+
* enum i2c_atr_flags - Flags for an I2C ATR driver
23+
*
24+
* @I2C_ATR_F_STATIC: ATR does not support dynamic mapping, use static mapping.
25+
* Mappings will only be added or removed as a result of
26+
* devices being added or removed from a child bus.
27+
* The ATR pool will have to be big enough to accomodate all
28+
* devices expected to be added to the child buses.
29+
*/
30+
enum i2c_atr_flags {
31+
I2C_ATR_F_STATIC = BIT(0),
32+
};
33+
2134
/**
2235
* struct i2c_atr_ops - Callbacks from ATR to the device driver.
2336
* @attach_addr: Notify the driver of a new device connected on a child
@@ -65,6 +78,7 @@ struct i2c_atr_adap_desc {
6578
* @dev: The device acting as an ATR
6679
* @ops: Driver-specific callbacks
6780
* @max_adapters: Maximum number of child adapters
81+
* @flags: Flags for ATR
6882
*
6983
* The new ATR helper is connected to the parent adapter but has no child
7084
* adapters. Call i2c_atr_add_adapter() to add some.
@@ -74,7 +88,8 @@ struct i2c_atr_adap_desc {
7488
* Return: pointer to the new ATR helper object, or ERR_PTR
7589
*/
7690
struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
77-
const struct i2c_atr_ops *ops, int max_adapters);
91+
const struct i2c_atr_ops *ops, int max_adapters,
92+
u32 flags);
7893

7994
/**
8095
* i2c_atr_delete - Delete an I2C ATR helper.

0 commit comments

Comments
 (0)