diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 8 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 19 |
2 files changed, 19 insertions, 8 deletions
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 3be4d492ccc2..a14e7de19846 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -491,16 +491,9 @@ static int __init shpcd_init(void) | |||
491 | shpchp_poll_mode = 1; | 491 | shpchp_poll_mode = 1; |
492 | #endif | 492 | #endif |
493 | 493 | ||
494 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | ||
495 | if (!shpchp_wq) | ||
496 | return -ENOMEM; | ||
497 | |||
498 | retval = pci_register_driver(&shpc_driver); | 494 | retval = pci_register_driver(&shpc_driver); |
499 | dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); | 495 | dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); |
500 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 496 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
501 | if (retval) { | ||
502 | destroy_workqueue(shpchp_wq); | ||
503 | } | ||
504 | return retval; | 497 | return retval; |
505 | } | 498 | } |
506 | 499 | ||
@@ -508,7 +501,6 @@ static void __exit shpcd_cleanup(void) | |||
508 | { | 501 | { |
509 | dbg("unload_shpchpd()\n"); | 502 | dbg("unload_shpchpd()\n"); |
510 | pci_unregister_driver(&shpc_driver); | 503 | pci_unregister_driver(&shpc_driver); |
511 | destroy_workqueue(shpchp_wq); | ||
512 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); | 504 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); |
513 | } | 505 | } |
514 | 506 | ||
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 8b63f772a6f2..5e8f589d0b64 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -216,6 +216,8 @@ static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ | |||
216 | static int ctlr_seq_num = 0; /* Controller sequenc # */ | 216 | static int ctlr_seq_num = 0; /* Controller sequenc # */ |
217 | static spinlock_t list_lock; | 217 | static spinlock_t list_lock; |
218 | 218 | ||
219 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); | ||
220 | |||
219 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); | 221 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); |
220 | 222 | ||
221 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); | 223 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); |
@@ -866,6 +868,13 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
866 | 868 | ||
867 | kfree(php_ctlr); | 869 | kfree(php_ctlr); |
868 | 870 | ||
871 | /* | ||
872 | * If this is the last controller to be released, destroy the | ||
873 | * shpchpd work queue | ||
874 | */ | ||
875 | if (atomic_dec_and_test(&shpchp_num_controllers)) | ||
876 | destroy_workqueue(shpchp_wq); | ||
877 | |||
869 | DBG_LEAVE_ROUTINE | 878 | DBG_LEAVE_ROUTINE |
870 | 879 | ||
871 | } | 880 | } |
@@ -1461,6 +1470,16 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1461 | ctlr_seq_num++; | 1470 | ctlr_seq_num++; |
1462 | 1471 | ||
1463 | /* | 1472 | /* |
1473 | * If this is the first controller to be initialized, | ||
1474 | * initialize the shpchpd work queue | ||
1475 | */ | ||
1476 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { | ||
1477 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | ||
1478 | if (!shpchp_wq) | ||
1479 | return -ENOMEM; | ||
1480 | } | ||
1481 | |||
1482 | /* | ||
1464 | * Unmask all event interrupts of all slots | 1483 | * Unmask all event interrupts of all slots |
1465 | */ | 1484 | */ |
1466 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1485 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { |