10
10
11
11
#include <linux/bitops.h>
12
12
#include <linux/delay.h>
13
+ #include <linux/devm-helpers.h>
13
14
#include <linux/dma-mapping.h>
14
15
#include <linux/dmi.h>
15
16
#include <linux/interrupt.h>
@@ -329,6 +330,48 @@ static const struct dmi_system_id dmi_nodevs[] = {
329
330
{ }
330
331
};
331
332
333
+ static void sfh1_1_init_work (struct work_struct * work )
334
+ {
335
+ struct amd_mp2_dev * mp2 = container_of (work , struct amd_mp2_dev , work );
336
+ struct pci_dev * pdev = mp2 -> pdev ;
337
+ int rc ;
338
+
339
+ rc = mp2 -> sfh1_1_ops -> init (mp2 );
340
+ if (rc ) {
341
+ dev_err (& pdev -> dev , "sfh1_1_init failed err %d\n" , rc );
342
+ return ;
343
+ }
344
+
345
+ amd_sfh_clear_intr (mp2 );
346
+ mp2 -> init_done = 1 ;
347
+ }
348
+
349
+ static void sfh_init_work (struct work_struct * work )
350
+ {
351
+ struct amd_mp2_dev * mp2 = container_of (work , struct amd_mp2_dev , work );
352
+ struct pci_dev * pdev = mp2 -> pdev ;
353
+ int rc ;
354
+
355
+ rc = amd_sfh_hid_client_init (mp2 );
356
+ if (rc ) {
357
+ amd_sfh_clear_intr (mp2 );
358
+ dev_err (& pdev -> dev , "amd_sfh_hid_client_init failed err %d\n" , rc );
359
+ return ;
360
+ }
361
+
362
+ amd_sfh_clear_intr (mp2 );
363
+ mp2 -> init_done = 1 ;
364
+ }
365
+
366
+ static void amd_sfh_remove (struct pci_dev * pdev )
367
+ {
368
+ struct amd_mp2_dev * mp2 = pci_get_drvdata (pdev );
369
+
370
+ flush_work (& mp2 -> work );
371
+ if (mp2 -> init_done )
372
+ mp2 -> mp2_ops -> remove (mp2 );
373
+ }
374
+
332
375
static int amd_mp2_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
333
376
{
334
377
struct amd_mp2_dev * privdata ;
@@ -367,10 +410,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
367
410
368
411
privdata -> sfh1_1_ops = (const struct amd_sfh1_1_ops * )id -> driver_data ;
369
412
if (privdata -> sfh1_1_ops ) {
370
- rc = privdata -> sfh1_1_ops -> init ( privdata );
413
+ rc = devm_work_autocancel ( & pdev -> dev , & privdata -> work , sfh1_1_init_work );
371
414
if (rc )
372
415
return rc ;
373
- goto init_done ;
416
+
417
+ schedule_work (& privdata -> work );
418
+ return 0 ;
374
419
}
375
420
376
421
mp2_select_ops (privdata );
@@ -381,33 +426,34 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
381
426
return rc ;
382
427
}
383
428
384
- rc = amd_sfh_hid_client_init ( privdata );
429
+ rc = devm_work_autocancel ( & pdev -> dev , & privdata -> work , sfh_init_work );
385
430
if (rc ) {
386
431
amd_sfh_clear_intr (privdata );
387
- if (rc != - EOPNOTSUPP )
388
- dev_err (& pdev -> dev , "amd_sfh_hid_client_init failed\n" );
389
432
return rc ;
390
433
}
391
434
392
- init_done :
393
- amd_sfh_clear_intr (privdata );
394
-
395
- return devm_add_action_or_reset (& pdev -> dev , privdata -> mp2_ops -> remove , privdata );
435
+ schedule_work (& privdata -> work );
436
+ return 0 ;
396
437
}
397
438
398
439
static void amd_sfh_shutdown (struct pci_dev * pdev )
399
440
{
400
441
struct amd_mp2_dev * mp2 = pci_get_drvdata (pdev );
401
442
402
- if (mp2 && mp2 -> mp2_ops )
403
- mp2 -> mp2_ops -> stop_all (mp2 );
443
+ if (mp2 ) {
444
+ flush_work (& mp2 -> work );
445
+ if (mp2 -> init_done )
446
+ mp2 -> mp2_ops -> stop_all (mp2 );
447
+ }
404
448
}
405
449
406
450
static int __maybe_unused amd_mp2_pci_resume (struct device * dev )
407
451
{
408
452
struct amd_mp2_dev * mp2 = dev_get_drvdata (dev );
409
453
410
- mp2 -> mp2_ops -> resume (mp2 );
454
+ flush_work (& mp2 -> work );
455
+ if (mp2 -> init_done )
456
+ mp2 -> mp2_ops -> resume (mp2 );
411
457
412
458
return 0 ;
413
459
}
@@ -416,7 +462,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
416
462
{
417
463
struct amd_mp2_dev * mp2 = dev_get_drvdata (dev );
418
464
419
- mp2 -> mp2_ops -> suspend (mp2 );
465
+ flush_work (& mp2 -> work );
466
+ if (mp2 -> init_done )
467
+ mp2 -> mp2_ops -> suspend (mp2 );
420
468
421
469
return 0 ;
422
470
}
@@ -438,6 +486,7 @@ static struct pci_driver amd_mp2_pci_driver = {
438
486
.probe = amd_mp2_pci_probe ,
439
487
.driver .pm = & amd_mp2_pm_ops ,
440
488
.shutdown = amd_sfh_shutdown ,
489
+ .remove = amd_sfh_remove ,
441
490
};
442
491
module_pci_driver (amd_mp2_pci_driver );
443
492
0 commit comments