@@ -255,7 +255,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data)
255
255
}
256
256
257
257
unsigned int cxl_map_irq (struct cxl * adapter , irq_hw_number_t hwirq ,
258
- irq_handler_t handler , void * cookie )
258
+ irq_handler_t handler , void * cookie , const char * name )
259
259
{
260
260
unsigned int virq ;
261
261
int result ;
@@ -271,7 +271,7 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
271
271
272
272
pr_devel ("hwirq %#lx mapped to virq %u\n" , hwirq , virq );
273
273
274
- result = request_irq (virq , handler , 0 , "cxl" , cookie );
274
+ result = request_irq (virq , handler , 0 , name , cookie );
275
275
if (result ) {
276
276
dev_warn (& adapter -> dev , "cxl_map_irq: request_irq failed: %i\n" , result );
277
277
return 0 ;
@@ -290,14 +290,15 @@ static int cxl_register_one_irq(struct cxl *adapter,
290
290
irq_handler_t handler ,
291
291
void * cookie ,
292
292
irq_hw_number_t * dest_hwirq ,
293
- unsigned int * dest_virq )
293
+ unsigned int * dest_virq ,
294
+ const char * name )
294
295
{
295
296
int hwirq , virq ;
296
297
297
298
if ((hwirq = cxl_alloc_one_irq (adapter )) < 0 )
298
299
return hwirq ;
299
300
300
- if (!(virq = cxl_map_irq (adapter , hwirq , handler , cookie )))
301
+ if (!(virq = cxl_map_irq (adapter , hwirq , handler , cookie , name )))
301
302
goto err ;
302
303
303
304
* dest_hwirq = hwirq ;
@@ -314,10 +315,19 @@ int cxl_register_psl_err_irq(struct cxl *adapter)
314
315
{
315
316
int rc ;
316
317
318
+ adapter -> irq_name = kasprintf (GFP_KERNEL , "cxl-%s-err" ,
319
+ dev_name (& adapter -> dev ));
320
+ if (!adapter -> irq_name )
321
+ return - ENOMEM ;
322
+
317
323
if ((rc = cxl_register_one_irq (adapter , cxl_irq_err , adapter ,
318
324
& adapter -> err_hwirq ,
319
- & adapter -> err_virq )))
325
+ & adapter -> err_virq ,
326
+ adapter -> irq_name ))) {
327
+ kfree (adapter -> irq_name );
328
+ adapter -> irq_name = NULL ;
320
329
return rc ;
330
+ }
321
331
322
332
cxl_p1_write (adapter , CXL_PSL_ErrIVTE , adapter -> err_hwirq & 0xffff );
323
333
@@ -329,17 +339,26 @@ void cxl_release_psl_err_irq(struct cxl *adapter)
329
339
cxl_p1_write (adapter , CXL_PSL_ErrIVTE , 0x0000000000000000 );
330
340
cxl_unmap_irq (adapter -> err_virq , adapter );
331
341
cxl_release_one_irq (adapter , adapter -> err_hwirq );
342
+ kfree (adapter -> irq_name );
332
343
}
333
344
334
345
int cxl_register_serr_irq (struct cxl_afu * afu )
335
346
{
336
347
u64 serr ;
337
348
int rc ;
338
349
350
+ afu -> err_irq_name = kasprintf (GFP_KERNEL , "cxl-%s-err" ,
351
+ dev_name (& afu -> dev ));
352
+ if (!afu -> err_irq_name )
353
+ return - ENOMEM ;
354
+
339
355
if ((rc = cxl_register_one_irq (afu -> adapter , cxl_slice_irq_err , afu ,
340
356
& afu -> serr_hwirq ,
341
- & afu -> serr_virq )))
357
+ & afu -> serr_virq , afu -> err_irq_name ))) {
358
+ kfree (afu -> err_irq_name );
359
+ afu -> err_irq_name = NULL ;
342
360
return rc ;
361
+ }
343
362
344
363
serr = cxl_p1n_read (afu , CXL_PSL_SERR_An );
345
364
serr = (serr & 0x00ffffffffff0000ULL ) | (afu -> serr_hwirq & 0xffff );
@@ -353,24 +372,50 @@ void cxl_release_serr_irq(struct cxl_afu *afu)
353
372
cxl_p1n_write (afu , CXL_PSL_SERR_An , 0x0000000000000000 );
354
373
cxl_unmap_irq (afu -> serr_virq , afu );
355
374
cxl_release_one_irq (afu -> adapter , afu -> serr_hwirq );
375
+ kfree (afu -> err_irq_name );
356
376
}
357
377
358
378
int cxl_register_psl_irq (struct cxl_afu * afu )
359
379
{
360
- return cxl_register_one_irq (afu -> adapter , cxl_irq_multiplexed , afu ,
361
- & afu -> psl_hwirq , & afu -> psl_virq );
380
+ int rc ;
381
+
382
+ afu -> psl_irq_name = kasprintf (GFP_KERNEL , "cxl-%s" ,
383
+ dev_name (& afu -> dev ));
384
+ if (!afu -> psl_irq_name )
385
+ return - ENOMEM ;
386
+
387
+ if ((rc = cxl_register_one_irq (afu -> adapter , cxl_irq_multiplexed , afu ,
388
+ & afu -> psl_hwirq , & afu -> psl_virq ,
389
+ afu -> psl_irq_name ))) {
390
+ kfree (afu -> psl_irq_name );
391
+ afu -> psl_irq_name = NULL ;
392
+ }
393
+ return rc ;
362
394
}
363
395
364
396
void cxl_release_psl_irq (struct cxl_afu * afu )
365
397
{
366
398
cxl_unmap_irq (afu -> psl_virq , afu );
367
399
cxl_release_one_irq (afu -> adapter , afu -> psl_hwirq );
400
+ kfree (afu -> psl_irq_name );
401
+ }
402
+
403
+ void afu_irq_name_free (struct cxl_context * ctx )
404
+ {
405
+ struct cxl_irq_name * irq_name , * tmp ;
406
+
407
+ list_for_each_entry_safe (irq_name , tmp , & ctx -> irq_names , list ) {
408
+ kfree (irq_name -> name );
409
+ list_del (& irq_name -> list );
410
+ kfree (irq_name );
411
+ }
368
412
}
369
413
370
414
int afu_register_irqs (struct cxl_context * ctx , u32 count )
371
415
{
372
416
irq_hw_number_t hwirq ;
373
- int rc , r , i ;
417
+ int rc , r , i , j = 1 ;
418
+ struct cxl_irq_name * irq_name ;
374
419
375
420
if ((rc = cxl_alloc_irq_ranges (& ctx -> irqs , ctx -> afu -> adapter , count )))
376
421
return rc ;
@@ -384,15 +429,47 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
384
429
sizeof (* ctx -> irq_bitmap ), GFP_KERNEL );
385
430
if (!ctx -> irq_bitmap )
386
431
return - ENOMEM ;
432
+
433
+ /*
434
+ * Allocate names first. If any fail, bail out before allocating
435
+ * actual hardware IRQs.
436
+ */
437
+ INIT_LIST_HEAD (& ctx -> irq_names );
438
+ for (r = 1 ; r < CXL_IRQ_RANGES ; r ++ ) {
439
+ for (i = 0 ; i < ctx -> irqs .range [r ]; hwirq ++ , i ++ ) {
440
+ irq_name = kmalloc (sizeof (struct cxl_irq_name ),
441
+ GFP_KERNEL );
442
+ if (!irq_name )
443
+ goto out ;
444
+ irq_name -> name = kasprintf (GFP_KERNEL , "cxl-%s-pe%i-%i" ,
445
+ dev_name (& ctx -> afu -> dev ),
446
+ ctx -> pe , j );
447
+ if (!irq_name -> name ) {
448
+ kfree (irq_name );
449
+ goto out ;
450
+ }
451
+ /* Add to tail so next look get the correct order */
452
+ list_add_tail (& irq_name -> list , & ctx -> irq_names );
453
+ j ++ ;
454
+ }
455
+ }
456
+
457
+ /* We've allocated all memory now, so let's do the irq allocations */
458
+ irq_name = list_first_entry (& ctx -> irq_names , struct cxl_irq_name , list );
387
459
for (r = 1 ; r < CXL_IRQ_RANGES ; r ++ ) {
388
460
hwirq = ctx -> irqs .offset [r ];
389
461
for (i = 0 ; i < ctx -> irqs .range [r ]; hwirq ++ , i ++ ) {
390
462
cxl_map_irq (ctx -> afu -> adapter , hwirq ,
391
- cxl_irq_afu , ctx );
463
+ cxl_irq_afu , ctx , irq_name -> name );
464
+ irq_name = list_next_entry (irq_name , list );
392
465
}
393
466
}
394
467
395
468
return 0 ;
469
+
470
+ out :
471
+ afu_irq_name_free (ctx );
472
+ return - ENOMEM ;
396
473
}
397
474
398
475
void afu_release_irqs (struct cxl_context * ctx )
@@ -410,5 +487,6 @@ void afu_release_irqs(struct cxl_context *ctx)
410
487
}
411
488
}
412
489
490
+ afu_irq_name_free (ctx );
413
491
cxl_release_irq_ranges (& ctx -> irqs , ctx -> afu -> adapter );
414
492
}
0 commit comments