[PATCH] shpchp: Create shpchpd at controller probe time
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Wed, 3 May 2006 14:42:04 +0000 (23:42 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 19 Jun 2006 21:13:23 +0000 (14:13 -0700)
The workqueue thread of shpchp driver should be created only when SHPC
based hotplug slots are detected on the system.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Kristen Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_hpc.c

index 3be4d492ccc2cf0143125fb154b94a7d4d2e05d0..a14e7de1984621cd9281751df06cc0624fee5d87 100644 (file)
@@ -491,16 +491,9 @@ static int __init shpcd_init(void)
        shpchp_poll_mode = 1;
 #endif
 
-       shpchp_wq = create_singlethread_workqueue("shpchpd");
-       if (!shpchp_wq)
-               return -ENOMEM;
-
        retval = pci_register_driver(&shpc_driver);
        dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
        info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
-       if (retval) {
-               destroy_workqueue(shpchp_wq);
-       }
        return retval;
 }
 
@@ -508,7 +501,6 @@ static void __exit shpcd_cleanup(void)
 {
        dbg("unload_shpchpd()\n");
        pci_unregister_driver(&shpc_driver);
-       destroy_workqueue(shpchp_wq);
        info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
 }
 
index 8b63f772a6f2465bff8e06bbaae3ca3d6577ba7a..5e8f589d0b643ec850f1285ee2334167225cd9b9 100644 (file)
@@ -216,6 +216,8 @@ static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
 static int ctlr_seq_num = 0;   /* Controller sequenc # */
 static spinlock_t list_lock;
 
+static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
+
 static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
 
 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)
 
        kfree(php_ctlr);
 
+       /*
+        * If this is the last controller to be released, destroy the
+        * shpchpd work queue
+        */
+       if (atomic_dec_and_test(&shpchp_num_controllers))
+               destroy_workqueue(shpchp_wq);
+
 DBG_LEAVE_ROUTINE
                          
 }
@@ -1460,6 +1469,16 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
 
        ctlr_seq_num++;
 
+       /*
+        * If this is the first controller to be initialized,
+        * initialize the shpchpd work queue
+        */
+       if (atomic_add_return(1, &shpchp_num_controllers) == 1) {
+               shpchp_wq = create_singlethread_workqueue("shpchpd");
+               if (!shpchp_wq)
+                       return -ENOMEM;
+       }
+
        /*
         * Unmask all event interrupts of all slots
         */