aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/hotplug/pciehp_core.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2007-03-06 15:02:26 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2007-05-02 19:02:34 -0700
commit5d386e1ac4025b4bcc6bad6811e771cb76064dfe (patch)
treed673b9686ed60aa43c1c0f43abc8bc54d19b6649 /drivers/pci/hotplug/pciehp_core.c
parentf7bdd12d234d9064bd0aa1b5610508959120a9b4 (diff)
pciehp: Event handling rework
The event handler of PCIEHP driver is unnecessarily very complex. In addition, current event handler can only a fixed number of events at the same time, and some of events would be lost if several number of events happened at the same time. This patch simplify the event handler using 'work queue', and it also fix the above-mentioned issue. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_core.c')
-rw-r--r--drivers/pci/hotplug/pciehp_core.c44
1 files changed, 8 insertions, 36 deletions
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index a92eda6e02f6..749227ecdb04 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -41,6 +41,7 @@ int pciehp_debug;
int pciehp_poll_mode;
int pciehp_poll_time;
int pciehp_force;
+struct workqueue_struct *pciehp_wq;
struct controller *pciehp_ctrl_list;
#define DRIVER_VERSION "0.4"
@@ -62,7 +63,6 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"
#define PCIE_MODULE_NAME "pciehp"
-static int pcie_start_thread (void);
static int set_attention_status (struct hotplug_slot *slot, u8 value);
static int enable_slot (struct hotplug_slot *slot);
static int disable_slot (struct hotplug_slot *slot);
@@ -229,6 +229,8 @@ static int init_slots(struct controller *ctrl)
slot->device = ctrl->slot_device_offset + i;
slot->hpc_ops = ctrl->hpc_ops;
slot->number = ctrl->first_slot;
+ mutex_init(&slot->lock);
+ INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
/* register this slot with the hotplug pci core */
hotplug_slot->private = slot;
@@ -286,6 +288,9 @@ static void cleanup_slots(struct controller *ctrl)
if (EMI(ctrl->ctrlcap))
sysfs_remove_file(&slot->hotplug_slot->kobj,
&hotplug_slot_attr_lock.attr);
+ cancel_delayed_work(&slot->work);
+ flush_scheduled_work();
+ flush_workqueue(pciehp_wq);
pci_hp_deregister(slot->hotplug_slot);
}
}
@@ -314,7 +319,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
- return pciehp_enable_slot(slot);
+ return pciehp_sysfs_enable_slot(slot);
}
@@ -324,7 +329,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
- return pciehp_disable_slot(slot);
+ return pciehp_sysfs_disable_slot(slot);
}
static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
@@ -466,9 +471,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
- /* Finish setting up the hot plug ctrl device */
- ctrl->next_event = 0;
-
if (!pciehp_ctrl_list) {
pciehp_ctrl_list = ctrl;
ctrl->next = NULL;
@@ -496,22 +498,6 @@ err_out_none:
return -ENODEV;
}
-
-static int pcie_start_thread(void)
-{
- int retval = 0;
-
- dbg("Initialize + Start the notification/polling mechanism \n");
-
- retval = pciehp_event_start_thread();
- if (retval) {
- dbg("pciehp_event_start_thread() failed\n");
- return retval;
- }
-
- return retval;
-}
-
static void __exit unload_pciehpd(void)
{
struct controller *ctrl;
@@ -529,10 +515,6 @@ static void __exit unload_pciehpd(void)
kfree(tctrl);
}
-
- /* Stop the notification mechanism */
- pciehp_event_stop_thread();
-
}
static void pciehp_remove (struct pcie_device *device)
@@ -585,21 +567,11 @@ static int __init pcied_init(void)
pciehp_poll_mode = 1;
#endif
- retval = pcie_start_thread();
- if (retval)
- goto error_hpc_init;
-
retval = pcie_port_service_register(&hpdriver_portdrv);
dbg("pcie_port_service_register = %d\n", retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
if (retval)
dbg("%s: Failure to register service\n", __FUNCTION__);
-
-error_hpc_init:
- if (retval) {
- pciehp_event_stop_thread();
- };
-
return retval;
}