diff options
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 29 |
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) | |||
276 | struct power_work_info { | 276 | struct 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) { |