@@ -239,56 +239,40 @@ static void i2c_atr_release_alias(struct i2c_atr_alias_pool *alias_pool, u16 ali
239
239
spin_unlock (& alias_pool -> lock );
240
240
}
241
241
242
- /* Must be called with alias_pairs_lock held */
243
242
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 )
245
244
{
246
- struct i2c_atr * atr = chan -> atr ;
247
245
struct i2c_atr_alias_pair * c2a ;
248
- struct list_head * alias_pairs ;
249
- bool found = false;
250
- u16 alias ;
251
- int ret ;
252
246
253
247
lockdep_assert_held (& chan -> alias_pairs_lock );
254
248
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 ) {
258
250
if (c2a -> addr == addr )
259
251
return c2a ;
260
252
}
261
253
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
+ }
274
256
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 ;
277
264
278
- atr -> ops -> detach_addr (atr , chan -> chan_id , c2a -> addr );
279
- c2a -> addr = addr ;
265
+ lockdep_assert_held (& chan -> alias_pairs_lock );
280
266
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 ;
283
270
284
- alias = c2a -> alias ;
285
- } else {
286
- alias = ret ;
271
+ alias = ret ;
287
272
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 ;
292
276
293
277
ret = atr -> ops -> attach_addr (atr , chan -> chan_id , c2a -> addr , c2a -> alias );
294
278
if (ret ) {
@@ -306,6 +290,68 @@ i2c_atr_get_mapping_by_addr(struct i2c_atr_chan *chan, u16 addr)
306
290
return NULL ;
307
291
}
308
292
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
+
309
355
/*
310
356
* Replace all message addresses with their aliases, saving the original
311
357
* addresses.
0 commit comments