aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index b418e3b09aa4..3e40ec0f7da1 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -276,6 +276,9 @@ static int remove_board(struct slot *p_slot)
276struct power_work_info { 276struct power_work_info {
277 struct slot *p_slot; 277 struct slot *p_slot;
278 struct work_struct work; 278 struct work_struct work;
279 unsigned int req;
280#define DISABLE_REQ 0
281#define ENABLE_REQ 1
279}; 282};
280 283
281/** 284/**
@@ -291,10 +294,8 @@ static void pciehp_power_thread(struct work_struct *work)
291 container_of(work, struct power_work_info, work); 294 container_of(work, struct power_work_info, work);
292 struct slot *p_slot = info->p_slot; 295 struct slot *p_slot = info->p_slot;
293 296
294 mutex_lock(&p_slot->lock); 297 switch (info->req) {
295 switch (p_slot->state) { 298 case DISABLE_REQ:
296 case POWEROFF_STATE:
297 mutex_unlock(&p_slot->lock);
298 ctrl_dbg(p_slot->ctrl, 299 ctrl_dbg(p_slot->ctrl,
299 "Disabling domain:bus:device=%04x:%02x:00\n", 300 "Disabling domain:bus:device=%04x:%02x:00\n",
300 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), 301 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
@@ -302,18 +303,22 @@ static void pciehp_power_thread(struct work_struct *work)
302 pciehp_disable_slot(p_slot); 303 pciehp_disable_slot(p_slot);
303 mutex_lock(&p_slot->lock); 304 mutex_lock(&p_slot->lock);
304 p_slot->state = STATIC_STATE; 305 p_slot->state = STATIC_STATE;
305 break;
306 case POWERON_STATE:
307 mutex_unlock(&p_slot->lock); 306 mutex_unlock(&p_slot->lock);
307 break;
308 case ENABLE_REQ:
309 ctrl_dbg(p_slot->ctrl,
310 "Enabling domain:bus:device=%04x:%02x:00\n",
311 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
312 p_slot->ctrl->pcie->port->subordinate->number);
308 if (pciehp_enable_slot(p_slot)) 313 if (pciehp_enable_slot(p_slot))
309 pciehp_green_led_off(p_slot); 314 pciehp_green_led_off(p_slot);
310 mutex_lock(&p_slot->lock); 315 mutex_lock(&p_slot->lock);
311 p_slot->state = STATIC_STATE; 316 p_slot->state = STATIC_STATE;
317 mutex_unlock(&p_slot->lock);
312 break; 318 break;
313 default: 319 default:
314 break; 320 break;
315 } 321 }
316 mutex_unlock(&p_slot->lock);
317 322
318 kfree(info); 323 kfree(info);
319} 324}
@@ -336,9 +341,11 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
336 switch (p_slot->state) { 341 switch (p_slot->state) {
337 case BLINKINGOFF_STATE: 342 case BLINKINGOFF_STATE:
338 p_slot->state = POWEROFF_STATE; 343 p_slot->state = POWEROFF_STATE;
344 info->req = DISABLE_REQ;
339 break; 345 break;
340 case BLINKINGON_STATE: 346 case BLINKINGON_STATE:
341 p_slot->state = POWERON_STATE; 347 p_slot->state = POWERON_STATE;
348 info->req = ENABLE_REQ;
342 break; 349 break;
343 default: 350 default:
344 kfree(info); 351 kfree(info);
@@ -428,10 +435,13 @@ static void handle_surprise_event(struct slot *p_slot)
428 INIT_WORK(&info->work, pciehp_power_thread); 435 INIT_WORK(&info->work, pciehp_power_thread);
429 436
430 pciehp_get_adapter_status(p_slot, &getstatus); 437 pciehp_get_adapter_status(p_slot, &getstatus);
431 if (!getstatus) 438 if (!getstatus) {
432 p_slot->state = POWEROFF_STATE; 439 p_slot->state = POWEROFF_STATE;
433 else 440 info->req = DISABLE_REQ;
441 } else {
434 p_slot->state = POWERON_STATE; 442 p_slot->state = POWERON_STATE;
443 info->req = ENABLE_REQ;
444 }
435 445
436 queue_work(p_slot->wq, &info->work); 446 queue_work(p_slot->wq, &info->work);
437} 447}
@@ -451,6 +461,7 @@ static void handle_link_event(struct slot *p_slot, u32 event)
451 return; 461 return;
452 } 462 }
453 info->p_slot = p_slot; 463 info->p_slot = p_slot;
464 info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ;
454 INIT_WORK(&info->work, pciehp_power_thread); 465 INIT_WORK(&info->work, pciehp_power_thread);
455 466
456 switch (p_slot->state) { 467 switch (p_slot->state) {