aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_ctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_ctrl.c')
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c223
1 files changed, 55 insertions, 168 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 372c63e35aa9..4283ef56dbd9 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -48,9 +48,8 @@ static inline char *slot_name(struct slot *p_slot)
48 return p_slot->hotplug_slot->name; 48 return p_slot->hotplug_slot->name;
49} 49}
50 50
51u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) 51u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
52{ 52{
53 struct controller *ctrl = (struct controller *) inst_id;
54 struct slot *p_slot; 53 struct slot *p_slot;
55 u8 rc = 0; 54 u8 rc = 0;
56 u8 getstatus; 55 u8 getstatus;
@@ -101,9 +100,8 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
101 100
102} 101}
103 102
104u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) 103u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
105{ 104{
106 struct controller *ctrl = (struct controller *) inst_id;
107 struct slot *p_slot; 105 struct slot *p_slot;
108 u8 rc = 0; 106 u8 rc = 0;
109 u8 getstatus; 107 u8 getstatus;
@@ -143,9 +141,8 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
143 return rc; 141 return rc;
144} 142}
145 143
146u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) 144u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
147{ 145{
148 struct controller *ctrl = (struct controller *) inst_id;
149 struct slot *p_slot; 146 struct slot *p_slot;
150 u8 presence_save, rc = 0; 147 u8 presence_save, rc = 0;
151 struct event_info *taskInfo; 148 struct event_info *taskInfo;
@@ -187,9 +184,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
187 return rc; 184 return rc;
188} 185}
189 186
190u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) 187u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
191{ 188{
192 struct controller *ctrl = (struct controller *) inst_id;
193 struct slot *p_slot; 189 struct slot *p_slot;
194 u8 rc = 0; 190 u8 rc = 0;
195 struct event_info *taskInfo; 191 struct event_info *taskInfo;
@@ -233,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
233 229
234static void set_slot_off(struct controller *ctrl, struct slot * pslot) 230static void set_slot_off(struct controller *ctrl, struct slot * pslot)
235{ 231{
236 /* Wait for exclusive access to hardware */
237 mutex_lock(&ctrl->ctrl_lock);
238
239 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ 232 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
240 if (POWER_CTRL(ctrl->ctrlcap)) { 233 if (POWER_CTRL(ctrl->ctrlcap)) {
241 if (pslot->hpc_ops->power_off_slot(pslot)) { 234 if (pslot->hpc_ops->power_off_slot(pslot)) {
242 err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); 235 err("%s: Issue of Slot Power Off command failed\n",
243 mutex_unlock(&ctrl->ctrl_lock); 236 __FUNCTION__);
244 return; 237 return;
245 } 238 }
246 wait_for_ctrl_irq (ctrl);
247 } 239 }
248 240
249 if (PWR_LED(ctrl->ctrlcap)) { 241 if (PWR_LED(ctrl->ctrlcap))
250 pslot->hpc_ops->green_led_off(pslot); 242 pslot->hpc_ops->green_led_off(pslot);
251 wait_for_ctrl_irq (ctrl);
252 }
253 243
254 if (ATTN_LED(ctrl->ctrlcap)) { 244 if (ATTN_LED(ctrl->ctrlcap)) {
255 if (pslot->hpc_ops->set_attention_status(pslot, 1)) { 245 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
256 err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); 246 err("%s: Issue of Set Attention Led command failed\n",
257 mutex_unlock(&ctrl->ctrl_lock); 247 __FUNCTION__);
258 return; 248 return;
259 } 249 }
260 wait_for_ctrl_irq (ctrl);
261 } 250 }
262
263 /* Done with exclusive hardware access */
264 mutex_unlock(&ctrl->ctrl_lock);
265} 251}
266 252
267/** 253/**
@@ -274,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
274static int board_added(struct slot *p_slot) 260static int board_added(struct slot *p_slot)
275{ 261{
276 u8 hp_slot; 262 u8 hp_slot;
277 int rc = 0; 263 int retval = 0;
278 struct controller *ctrl = p_slot->ctrl; 264 struct controller *ctrl = p_slot->ctrl;
279 265
280 hp_slot = p_slot->device - ctrl->slot_device_offset; 266 hp_slot = p_slot->device - ctrl->slot_device_offset;
@@ -283,53 +269,38 @@ static int board_added(struct slot *p_slot)
283 __FUNCTION__, p_slot->device, 269 __FUNCTION__, p_slot->device,
284 ctrl->slot_device_offset, hp_slot); 270 ctrl->slot_device_offset, hp_slot);
285 271
286 /* Wait for exclusive access to hardware */
287 mutex_lock(&ctrl->ctrl_lock);
288
289 if (POWER_CTRL(ctrl->ctrlcap)) { 272 if (POWER_CTRL(ctrl->ctrlcap)) {
290 /* Power on slot */ 273 /* Power on slot */
291 rc = p_slot->hpc_ops->power_on_slot(p_slot); 274 retval = p_slot->hpc_ops->power_on_slot(p_slot);
292 if (rc) { 275 if (retval)
293 mutex_unlock(&ctrl->ctrl_lock); 276 return retval;
294 return -1;
295 }
296
297 /* Wait for the command to complete */
298 wait_for_ctrl_irq (ctrl);
299 } 277 }
300 278
301 if (PWR_LED(ctrl->ctrlcap)) { 279 if (PWR_LED(ctrl->ctrlcap))
302 p_slot->hpc_ops->green_led_blink(p_slot); 280 p_slot->hpc_ops->green_led_blink(p_slot);
303
304 /* Wait for the command to complete */
305 wait_for_ctrl_irq (ctrl);
306 }
307
308 /* Done with exclusive hardware access */
309 mutex_unlock(&ctrl->ctrl_lock);
310 281
311 /* Wait for ~1 second */ 282 /* Wait for ~1 second */
312 wait_for_ctrl_irq (ctrl); 283 msleep(1000);
313 284
314 /* Check link training status */ 285 /* Check link training status */
315 rc = p_slot->hpc_ops->check_lnk_status(ctrl); 286 retval = p_slot->hpc_ops->check_lnk_status(ctrl);
316 if (rc) { 287 if (retval) {
317 err("%s: Failed to check link status\n", __FUNCTION__); 288 err("%s: Failed to check link status\n", __FUNCTION__);
318 set_slot_off(ctrl, p_slot); 289 set_slot_off(ctrl, p_slot);
319 return rc; 290 return retval;
320 } 291 }
321 292
322 /* Check for a power fault */ 293 /* Check for a power fault */
323 if (p_slot->hpc_ops->query_power_fault(p_slot)) { 294 if (p_slot->hpc_ops->query_power_fault(p_slot)) {
324 dbg("%s: power fault detected\n", __FUNCTION__); 295 dbg("%s: power fault detected\n", __FUNCTION__);
325 rc = POWER_FAILURE; 296 retval = POWER_FAILURE;
326 goto err_exit; 297 goto err_exit;
327 } 298 }
328 299
329 rc = pciehp_configure_device(p_slot); 300 retval = pciehp_configure_device(p_slot);
330 if (rc) { 301 if (retval) {
331 err("Cannot add device 0x%x:%x\n", p_slot->bus, 302 err("Cannot add device 0x%x:%x\n", p_slot->bus,
332 p_slot->device); 303 p_slot->device);
333 goto err_exit; 304 goto err_exit;
334 } 305 }
335 306
@@ -338,26 +309,16 @@ static int board_added(struct slot *p_slot)
338 */ 309 */
339 if (pcie_mch_quirk) 310 if (pcie_mch_quirk)
340 pci_fixup_device(pci_fixup_final, ctrl->pci_dev); 311 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
341 if (PWR_LED(ctrl->ctrlcap)) { 312 if (PWR_LED(ctrl->ctrlcap))
342 /* Wait for exclusive access to hardware */
343 mutex_lock(&ctrl->ctrl_lock);
344
345 p_slot->hpc_ops->green_led_on(p_slot); 313 p_slot->hpc_ops->green_led_on(p_slot);
346 314
347 /* Wait for the command to complete */
348 wait_for_ctrl_irq (ctrl);
349
350 /* Done with exclusive hardware access */
351 mutex_unlock(&ctrl->ctrl_lock);
352 }
353 return 0; 315 return 0;
354 316
355err_exit: 317err_exit:
356 set_slot_off(ctrl, p_slot); 318 set_slot_off(ctrl, p_slot);
357 return -1; 319 return retval;
358} 320}
359 321
360
361/** 322/**
362 * remove_board - Turns off slot and LED's 323 * remove_board - Turns off slot and LED's
363 * 324 *
@@ -366,44 +327,32 @@ static int remove_board(struct slot *p_slot)
366{ 327{
367 u8 device; 328 u8 device;
368 u8 hp_slot; 329 u8 hp_slot;
369 int rc; 330 int retval = 0;
370 struct controller *ctrl = p_slot->ctrl; 331 struct controller *ctrl = p_slot->ctrl;
371 332
372 if (pciehp_unconfigure_device(p_slot)) 333 retval = pciehp_unconfigure_device(p_slot);
373 return 1; 334 if (retval)
335 return retval;
374 336
375 device = p_slot->device; 337 device = p_slot->device;
376
377 hp_slot = p_slot->device - ctrl->slot_device_offset; 338 hp_slot = p_slot->device - ctrl->slot_device_offset;
378 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 339 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
379 340
380 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); 341 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
381 342
382 /* Wait for exclusive access to hardware */
383 mutex_lock(&ctrl->ctrl_lock);
384
385 if (POWER_CTRL(ctrl->ctrlcap)) { 343 if (POWER_CTRL(ctrl->ctrlcap)) {
386 /* power off slot */ 344 /* power off slot */
387 rc = p_slot->hpc_ops->power_off_slot(p_slot); 345 retval = p_slot->hpc_ops->power_off_slot(p_slot);
388 if (rc) { 346 if (retval) {
389 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); 347 err("%s: Issue of Slot Disable command failed\n",
390 mutex_unlock(&ctrl->ctrl_lock); 348 __FUNCTION__);
391 return rc; 349 return retval;
392 } 350 }
393 /* Wait for the command to complete */
394 wait_for_ctrl_irq (ctrl);
395 } 351 }
396 352
397 if (PWR_LED(ctrl->ctrlcap)) { 353 if (PWR_LED(ctrl->ctrlcap))
398 /* turn off Green LED */ 354 /* turn off Green LED */
399 p_slot->hpc_ops->green_led_off(p_slot); 355 p_slot->hpc_ops->green_led_off(p_slot);
400
401 /* Wait for the command to complete */
402 wait_for_ctrl_irq (ctrl);
403 }
404
405 /* Done with exclusive hardware access */
406 mutex_unlock(&ctrl->ctrl_lock);
407 356
408 return 0; 357 return 0;
409} 358}
@@ -448,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot)
448 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, 397 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
449 p_slot->bus, p_slot->device); 398 p_slot->bus, p_slot->device);
450 399
451 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 400 if (pciehp_enable_slot(p_slot) &&
452 /* Wait for exclusive access to hardware */ 401 PWR_LED(p_slot->ctrl->ctrlcap))
453 mutex_lock(&p_slot->ctrl->ctrl_lock);
454
455 p_slot->hpc_ops->green_led_off(p_slot); 402 p_slot->hpc_ops->green_led_off(p_slot);
456 403
457 /* Wait for the command to complete */
458 wait_for_ctrl_irq (p_slot->ctrl);
459
460 /* Done with exclusive hardware access */
461 mutex_unlock(&p_slot->ctrl->ctrl_lock);
462 }
463 p_slot->state = STATIC_STATE; 404 p_slot->state = STATIC_STATE;
464 } 405 }
465 406
@@ -498,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
498 dbg("%s: adding bus:device(%x:%x)\n", 439 dbg("%s: adding bus:device(%x:%x)\n",
499 __FUNCTION__, p_slot->bus, p_slot->device); 440 __FUNCTION__, p_slot->bus, p_slot->device);
500 441
501 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 442 if (pciehp_enable_slot(p_slot) &&
502 /* Wait for exclusive access to hardware */ 443 PWR_LED(p_slot->ctrl->ctrlcap))
503 mutex_lock(&p_slot->ctrl->ctrl_lock);
504
505 p_slot->hpc_ops->green_led_off(p_slot); 444 p_slot->hpc_ops->green_led_off(p_slot);
506 445
507 /* Wait for the command to complete */
508 wait_for_ctrl_irq (p_slot->ctrl);
509
510 /* Done with exclusive hardware access */
511 mutex_unlock(&p_slot->ctrl->ctrl_lock);
512 }
513 p_slot->state = STATIC_STATE; 446 p_slot->state = STATIC_STATE;
514 } 447 }
515 448
@@ -620,46 +553,24 @@ static void interrupt_event_handler(struct controller *ctrl)
620 553
621 switch (p_slot->state) { 554 switch (p_slot->state) {
622 case BLINKINGOFF_STATE: 555 case BLINKINGOFF_STATE:
623 /* Wait for exclusive access to hardware */ 556 if (PWR_LED(ctrl->ctrlcap))
624 mutex_lock(&ctrl->ctrl_lock);
625
626 if (PWR_LED(ctrl->ctrlcap)) {
627 p_slot->hpc_ops->green_led_on(p_slot); 557 p_slot->hpc_ops->green_led_on(p_slot);
628 /* Wait for the command to complete */
629 wait_for_ctrl_irq (ctrl);
630 }
631 if (ATTN_LED(ctrl->ctrlcap)) {
632 p_slot->hpc_ops->set_attention_status(p_slot, 0);
633 558
634 /* Wait for the command to complete */ 559 if (ATTN_LED(ctrl->ctrlcap))
635 wait_for_ctrl_irq (ctrl); 560 p_slot->hpc_ops->set_attention_status(p_slot, 0);
636 }
637 /* Done with exclusive hardware access */
638 mutex_unlock(&ctrl->ctrl_lock);
639 break; 561 break;
640 case BLINKINGON_STATE: 562 case BLINKINGON_STATE:
641 /* Wait for exclusive access to hardware */ 563 if (PWR_LED(ctrl->ctrlcap))
642 mutex_lock(&ctrl->ctrl_lock);
643
644 if (PWR_LED(ctrl->ctrlcap)) {
645 p_slot->hpc_ops->green_led_off(p_slot); 564 p_slot->hpc_ops->green_led_off(p_slot);
646 /* Wait for the command to complete */
647 wait_for_ctrl_irq (ctrl);
648 }
649 if (ATTN_LED(ctrl->ctrlcap)){
650 p_slot->hpc_ops->set_attention_status(p_slot, 0);
651 /* Wait for the command to complete */
652 wait_for_ctrl_irq (ctrl);
653 }
654 /* Done with exclusive hardware access */
655 mutex_unlock(&ctrl->ctrl_lock);
656 565
566 if (ATTN_LED(ctrl->ctrlcap))
567 p_slot->hpc_ops->set_attention_status(p_slot, 0);
657 break; 568 break;
658 default: 569 default:
659 warn("Not a valid state\n"); 570 warn("Not a valid state\n");
660 return; 571 return;
661 } 572 }
662 info(msg_button_cancel, slot_name(p_slot)); 573 info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot));
663 p_slot->state = STATIC_STATE; 574 p_slot->state = STATIC_STATE;
664 } 575 }
665 /* ***********Button Pressed (No action on 1st press...) */ 576 /* ***********Button Pressed (No action on 1st press...) */
@@ -672,34 +583,21 @@ static void interrupt_event_handler(struct controller *ctrl)
672 /* slot is on */ 583 /* slot is on */
673 dbg("slot is on\n"); 584 dbg("slot is on\n");
674 p_slot->state = BLINKINGOFF_STATE; 585 p_slot->state = BLINKINGOFF_STATE;
675 info(msg_button_off, slot_name(p_slot)); 586 info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot));
676 } else { 587 } else {
677 /* slot is off */ 588 /* slot is off */
678 dbg("slot is off\n"); 589 dbg("slot is off\n");
679 p_slot->state = BLINKINGON_STATE; 590 p_slot->state = BLINKINGON_STATE;
680 info(msg_button_on, slot_name(p_slot)); 591 info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
681 } 592 }
682 593
683 /* Wait for exclusive access to hardware */
684 mutex_lock(&ctrl->ctrl_lock);
685
686 /* blink green LED and turn off amber */ 594 /* blink green LED and turn off amber */
687 if (PWR_LED(ctrl->ctrlcap)) { 595 if (PWR_LED(ctrl->ctrlcap))
688 p_slot->hpc_ops->green_led_blink(p_slot); 596 p_slot->hpc_ops->green_led_blink(p_slot);
689 /* Wait for the command to complete */
690 wait_for_ctrl_irq (ctrl);
691 }
692 597
693 if (ATTN_LED(ctrl->ctrlcap)) { 598 if (ATTN_LED(ctrl->ctrlcap))
694 p_slot->hpc_ops->set_attention_status(p_slot, 0); 599 p_slot->hpc_ops->set_attention_status(p_slot, 0);
695 600
696 /* Wait for the command to complete */
697 wait_for_ctrl_irq (ctrl);
698 }
699
700 /* Done with exclusive hardware access */
701 mutex_unlock(&ctrl->ctrl_lock);
702
703 init_timer(&p_slot->task_event); 601 init_timer(&p_slot->task_event);
704 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ 602 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
705 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; 603 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -712,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl)
712 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { 610 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
713 if (POWER_CTRL(ctrl->ctrlcap)) { 611 if (POWER_CTRL(ctrl->ctrlcap)) {
714 dbg("power fault\n"); 612 dbg("power fault\n");
715 /* Wait for exclusive access to hardware */ 613 if (ATTN_LED(ctrl->ctrlcap))
716 mutex_lock(&ctrl->ctrl_lock);
717
718 if (ATTN_LED(ctrl->ctrlcap)) {
719 p_slot->hpc_ops->set_attention_status(p_slot, 1); 614 p_slot->hpc_ops->set_attention_status(p_slot, 1);
720 wait_for_ctrl_irq (ctrl);
721 }
722 615
723 if (PWR_LED(ctrl->ctrlcap)) { 616 if (PWR_LED(ctrl->ctrlcap))
724 p_slot->hpc_ops->green_led_off(p_slot); 617 p_slot->hpc_ops->green_led_off(p_slot);
725 wait_for_ctrl_irq (ctrl);
726 }
727
728 /* Done with exclusive hardware access */
729 mutex_unlock(&ctrl->ctrl_lock);
730 } 618 }
731 } 619 }
732 /***********SURPRISE REMOVAL********************/ 620 /***********SURPRISE REMOVAL********************/
@@ -754,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl)
754 } 642 }
755} 643}
756 644
757
758int pciehp_enable_slot(struct slot *p_slot) 645int pciehp_enable_slot(struct slot *p_slot)
759{ 646{
760 u8 getstatus = 0; 647 u8 getstatus = 0;