diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index d5f993d2f5f359c223553034ac8084643f67aeaf..b6274e58f95d9f8ee056dec90e3005c18114f056 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -145,8 +145,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) { struct slot *p_slot = container_of(work, struct slot, work.work); struct controller *ctrl = p_slot->ctrl; - int events = atomic_long_read(&work->data) & (PCI_EXP_SLTSTA_PDC | - PCI_EXP_SLTSTA_DLLSC | DISABLE_SLOT); + int events = p_slot->work.data; mutex_lock(&p_slot->lock); switch (p_slot->state) { @@ -188,7 +187,7 @@ void pciehp_handle_button_press(struct slot *p_slot) /* blink green LED and turn off amber */ pciehp_green_led_blink(p_slot); pciehp_set_attention_status(p_slot, 0); - atomic_long_set(&p_slot->work.work.data, 0); + p_slot->work.data = 0; schedule_delayed_work(&p_slot->work, 5 * HZ); break; case BLINKINGOFF_STATE: diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index a8298b483e9c03c41329a86b374ed3376f01adf2..43bb78122795a9de7df5488886746b1a5f660fe8 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -693,18 +693,22 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) slot->state == BLINKINGON_STATE) pciehp_handle_disable_request(slot); else { + ctrl_info(ctrl, "Slot(%s): DISABLE_SLOT event in remove or rescan process!\n", + slot_name(slot)); /* * we use the work_struct private data to store * the event type */ - atomic_long_set(&slot->work.work.data, - DISABLE_SLOT); + slot->work.data = DISABLE_SLOT; /* * If 'work.timer' is pending, schedule the work will * cause BUG_ON(). */ if (!timer_pending(&slot->work.timer)) schedule_delayed_work(&slot->work, 3 * HZ); + else + ctrl_info(ctrl, "Slot(%s): Didn't schedule delayed_work because timer is pending!\n", + slot_name(slot)); } } } else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) { @@ -723,11 +727,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) */ ctrl_info(ctrl, "Slot(%s): Surprise link down/up in remove or rescan process!\n", slot_name(slot)); - atomic_long_set(&slot->work.work.data, - events & (PCI_EXP_SLTSTA_PDC | - PCI_EXP_SLTSTA_DLLSC)); + slot->work.data = events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC); if (!timer_pending(&slot->work.timer)) schedule_delayed_work(&slot->work, 3 * HZ); + else + ctrl_info(ctrl, "Slot(%s): Didn't schedule delayed_work because timer is pending!\n", + slot_name(slot)); } } } diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index cd9ae7672203b55daafe96b4f3c195b8ff5a0fd5..59bc6b302997789acceb7ae67615d852c781d0ce 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -125,6 +125,8 @@ struct delayed_work { /* target workqueue and CPU ->timer uses to queue ->work */ struct workqueue_struct *wq; int cpu; + /* delayed_work private data, only used in pciehp now */ + unsigned long data; KABI_RESERVE(1) KABI_RESERVE(2)