From kaneshige.kenji@jp.fujitsu.com Wed May 3 07:45:10 2006 Message-ID: <4458C13C.9030306@jp.fujitsu.com> Date: Wed, 03 May 2006 23:42:04 +0900 From: Kenji Kaneshige To: Greg KH , Greg KH , Kristen Accardi Cc: Kenji Kaneshige Subject: shpchp: Create shpchpd at controller probe time 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 Cc: Kristen Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_core.c | 8 -------- drivers/pci/hotplug/shpchp_hpc.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) --- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c +++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c @@ -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"); } --- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c +++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c @@ -216,6 +216,8 @@ static struct php_ctlr_state_s *php_ctlr 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 cont 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 } @@ -1461,6 +1470,16 @@ int shpc_init(struct controller * ctrl, 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 */ for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {