Skip to content

Commit 5988589

Browse files
Demon000Wolfram Sang
authored andcommitted
i2c: atr: split up i2c_atr_get_mapping_by_addr()
The i2c_atr_get_mapping_by_addr() function handles three separate usecases: finding an existing mapping, creating a new mapping, or replacing an existing mapping if a new mapping cannot be created because there aren't enough aliases available. Split up the function into three different functions handling its individual usecases to prepare for better usage of each one. Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
1 parent 42a70dc commit 5988589

File tree

1 file changed

+81
-35
lines changed

1 file changed

+81
-35
lines changed

drivers/i2c/i2c-atr.c

Lines changed: 81 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -239,56 +239,40 @@ static void i2c_atr_release_alias(struct i2c_atr_alias_pool *alias_pool, u16 ali
239239
spin_unlock(&alias_pool->lock);
240240
}
241241

242-
/* Must be called with alias_pairs_lock held */
243242
static struct i2c_atr_alias_pair *
244-
i2c_atr_get_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
243+
i2c_atr_find_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
245244
{
246-
struct i2c_atr *atr = chan->atr;
247245
struct i2c_atr_alias_pair *c2a;
248-
struct list_head *alias_pairs;
249-
bool found = false;
250-
u16 alias;
251-
int ret;
252246

253247
lockdep_assert_held(&chan->alias_pairs_lock);
254248

255-
alias_pairs = &chan->alias_pairs;
256-
257-
list_for_each_entry(c2a, alias_pairs, node) {
249+
list_for_each_entry(c2a, &chan->alias_pairs, node) {
258250
if (c2a->addr == addr)
259251
return c2a;
260252
}
261253

262-
ret = i2c_atr_reserve_alias(chan->alias_pool);
263-
if (ret < 0) {
264-
// If no free aliases are left, replace an existing one
265-
if (unlikely(list_empty(alias_pairs)))
266-
return NULL;
267-
268-
list_for_each_entry_reverse(c2a, alias_pairs, node) {
269-
if (!c2a->fixed) {
270-
found = true;
271-
break;
272-
}
273-
}
254+
return NULL;
255+
}
274256

275-
if (!found)
276-
return NULL;
257+
static struct i2c_atr_alias_pair *
258+
i2c_atr_create_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
259+
{
260+
struct i2c_atr *atr = chan->atr;
261+
struct i2c_atr_alias_pair *c2a;
262+
u16 alias;
263+
int ret;
277264

278-
atr->ops->detach_addr(atr, chan->chan_id, c2a->addr);
279-
c2a->addr = addr;
265+
lockdep_assert_held(&chan->alias_pairs_lock);
280266

281-
// Move updated entry to beginning of list
282-
list_move(&c2a->node, alias_pairs);
267+
ret = i2c_atr_reserve_alias(chan->alias_pool);
268+
if (ret < 0)
269+
return NULL;
283270

284-
alias = c2a->alias;
285-
} else {
286-
alias = ret;
271+
alias = ret;
287272

288-
c2a = i2c_atr_create_c2a(chan, alias, addr);
289-
if (!c2a)
290-
goto err_release_alias;
291-
}
273+
c2a = i2c_atr_create_c2a(chan, alias, addr);
274+
if (!c2a)
275+
goto err_release_alias;
292276

293277
ret = atr->ops->attach_addr(atr, chan->chan_id, c2a->addr, c2a->alias);
294278
if (ret) {
@@ -306,6 +290,68 @@ i2c_atr_get_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
306290
return NULL;
307291
}
308292

293+
static struct i2c_atr_alias_pair *
294+
i2c_atr_replace_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
295+
{
296+
struct i2c_atr *atr = chan->atr;
297+
struct i2c_atr_alias_pair *c2a;
298+
struct list_head *alias_pairs;
299+
bool found = false;
300+
u16 alias;
301+
int ret;
302+
303+
lockdep_assert_held(&chan->alias_pairs_lock);
304+
305+
alias_pairs = &chan->alias_pairs;
306+
307+
if (unlikely(list_empty(alias_pairs)))
308+
return NULL;
309+
310+
list_for_each_entry_reverse(c2a, alias_pairs, node) {
311+
if (!c2a->fixed) {
312+
found = true;
313+
break;
314+
}
315+
}
316+
317+
if (!found)
318+
return NULL;
319+
320+
atr->ops->detach_addr(atr, chan->chan_id, c2a->addr);
321+
c2a->addr = addr;
322+
323+
list_move(&c2a->node, alias_pairs);
324+
325+
alias = c2a->alias;
326+
327+
ret = atr->ops->attach_addr(atr, chan->chan_id, c2a->addr, c2a->alias);
328+
if (ret) {
329+
dev_err(atr->dev, "failed to attach 0x%02x on channel %d: err %d\n",
330+
addr, chan->chan_id, ret);
331+
i2c_atr_destroy_c2a(&c2a);
332+
i2c_atr_release_alias(chan->alias_pool, alias);
333+
return NULL;
334+
}
335+
336+
return c2a;
337+
}
338+
339+
static struct i2c_atr_alias_pair *
340+
i2c_atr_get_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
341+
{
342+
struct i2c_atr_alias_pair *c2a;
343+
344+
c2a = i2c_atr_find_mapping_by_addr(chan, addr);
345+
if (c2a)
346+
return c2a;
347+
348+
c2a = i2c_atr_create_mapping_by_addr(chan, addr);
349+
if (c2a)
350+
return c2a;
351+
352+
return i2c_atr_replace_mapping_by_addr(chan, addr);
353+
}
354+
309355
/*
310356
* Replace all message addresses with their aliases, saving the original
311357
* addresses.

0 commit comments

Comments
 (0)