@@ -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 */
243242static 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