1010
1111#include <linux/bitops.h>
1212#include <linux/delay.h>
13+ #include <linux/devm-helpers.h>
1314#include <linux/dma-mapping.h>
1415#include <linux/dmi.h>
1516#include <linux/interrupt.h>
@@ -329,6 +330,48 @@ static const struct dmi_system_id dmi_nodevs[] = {
329330 { }
330331};
331332
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+
332375static int amd_mp2_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
333376{
334377 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
367410
368411 privdata -> sfh1_1_ops = (const struct amd_sfh1_1_ops * )id -> driver_data ;
369412 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 );
371414 if (rc )
372415 return rc ;
373- goto init_done ;
416+
417+ schedule_work (& privdata -> work );
418+ return 0 ;
374419 }
375420
376421 mp2_select_ops (privdata );
@@ -381,33 +426,34 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
381426 return rc ;
382427 }
383428
384- rc = amd_sfh_hid_client_init ( privdata );
429+ rc = devm_work_autocancel ( & pdev -> dev , & privdata -> work , sfh_init_work );
385430 if (rc ) {
386431 amd_sfh_clear_intr (privdata );
387- if (rc != - EOPNOTSUPP )
388- dev_err (& pdev -> dev , "amd_sfh_hid_client_init failed\n" );
389432 return rc ;
390433 }
391434
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 ;
396437}
397438
398439static void amd_sfh_shutdown (struct pci_dev * pdev )
399440{
400441 struct amd_mp2_dev * mp2 = pci_get_drvdata (pdev );
401442
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+ }
404448}
405449
406450static int __maybe_unused amd_mp2_pci_resume (struct device * dev )
407451{
408452 struct amd_mp2_dev * mp2 = dev_get_drvdata (dev );
409453
410- mp2 -> mp2_ops -> resume (mp2 );
454+ flush_work (& mp2 -> work );
455+ if (mp2 -> init_done )
456+ mp2 -> mp2_ops -> resume (mp2 );
411457
412458 return 0 ;
413459}
@@ -416,7 +462,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
416462{
417463 struct amd_mp2_dev * mp2 = dev_get_drvdata (dev );
418464
419- mp2 -> mp2_ops -> suspend (mp2 );
465+ flush_work (& mp2 -> work );
466+ if (mp2 -> init_done )
467+ mp2 -> mp2_ops -> suspend (mp2 );
420468
421469 return 0 ;
422470}
@@ -438,6 +486,7 @@ static struct pci_driver amd_mp2_pci_driver = {
438486 .probe = amd_mp2_pci_probe ,
439487 .driver .pm = & amd_mp2_pm_ops ,
440488 .shutdown = amd_sfh_shutdown ,
489+ .remove = amd_sfh_remove ,
441490};
442491module_pci_driver (amd_mp2_pci_driver );
443492
0 commit comments