diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 191 |
2 files changed, 102 insertions, 90 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ccc57627201e..7959c222dc24 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -103,6 +103,7 @@ struct controller { | |||
103 | u8 cap_base; | 103 | u8 cap_base; |
104 | struct timer_list poll_timer; | 104 | struct timer_list poll_timer; |
105 | volatile int cmd_busy; | 105 | volatile int cmd_busy; |
106 | spinlock_t lock; | ||
106 | }; | 107 | }; |
107 | 108 | ||
108 | #define INT_BUTTON_IGNORE 0 | 109 | #define INT_BUTTON_IGNORE 0 |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9aac6a87eb53..016eea94a8a5 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -275,11 +275,19 @@ static inline int pcie_wait_cmd(struct controller *ctrl) | |||
275 | return retval; | 275 | return retval; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 278 | /** |
279 | * pcie_write_cmd - Issue controller command | ||
280 | * @slot: slot to which the command is issued | ||
281 | * @cmd: command value written to slot control register | ||
282 | * @mask: bitmask of slot control register to be modified | ||
283 | */ | ||
284 | static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask) | ||
279 | { | 285 | { |
280 | struct controller *ctrl = slot->ctrl; | 286 | struct controller *ctrl = slot->ctrl; |
281 | int retval = 0; | 287 | int retval = 0; |
282 | u16 slot_status; | 288 | u16 slot_status; |
289 | u16 slot_ctrl; | ||
290 | unsigned long flags; | ||
283 | 291 | ||
284 | DBG_ENTER_ROUTINE | 292 | DBG_ENTER_ROUTINE |
285 | 293 | ||
@@ -299,17 +307,29 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
299 | __FUNCTION__); | 307 | __FUNCTION__); |
300 | } | 308 | } |
301 | 309 | ||
302 | ctrl->cmd_busy = 1; | 310 | spin_lock_irqsave(&ctrl->lock, flags); |
303 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); | 311 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
304 | if (retval) { | 312 | if (retval) { |
305 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | 313 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
306 | goto out; | 314 | goto out_spin_unlock; |
307 | } | 315 | } |
308 | 316 | ||
317 | slot_ctrl &= ~mask; | ||
318 | slot_ctrl |= ((cmd & mask) | CMD_CMPL_INTR_ENABLE); | ||
319 | |||
320 | ctrl->cmd_busy = 1; | ||
321 | retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); | ||
322 | if (retval) | ||
323 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
324 | |||
325 | out_spin_unlock: | ||
326 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
327 | |||
309 | /* | 328 | /* |
310 | * Wait for command completion. | 329 | * Wait for command completion. |
311 | */ | 330 | */ |
312 | retval = pcie_wait_cmd(ctrl); | 331 | if (!retval) |
332 | retval = pcie_wait_cmd(ctrl); | ||
313 | out: | 333 | out: |
314 | mutex_unlock(&ctrl->ctrl_lock); | 334 | mutex_unlock(&ctrl->ctrl_lock); |
315 | DBG_LEAVE_ROUTINE | 335 | DBG_LEAVE_ROUTINE |
@@ -502,25 +522,20 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status) | |||
502 | 522 | ||
503 | static int hpc_toggle_emi(struct slot *slot) | 523 | static int hpc_toggle_emi(struct slot *slot) |
504 | { | 524 | { |
505 | struct controller *ctrl = slot->ctrl; | 525 | u16 slot_cmd; |
506 | u16 slot_cmd = 0; | 526 | u16 cmd_mask; |
507 | u16 slot_ctrl; | 527 | int rc; |
508 | int rc = 0; | ||
509 | 528 | ||
510 | DBG_ENTER_ROUTINE | 529 | DBG_ENTER_ROUTINE |
511 | 530 | ||
512 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 531 | slot_cmd = EMI_CTRL; |
513 | if (rc) { | 532 | cmd_mask = EMI_CTRL; |
514 | err("%s : hp_register_read_word SLOT_CTRL failed\n", | 533 | if (!pciehp_poll_mode) { |
515 | __FUNCTION__); | ||
516 | return rc; | ||
517 | } | ||
518 | |||
519 | slot_cmd = (slot_ctrl | EMI_CTRL); | ||
520 | if (!pciehp_poll_mode) | ||
521 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 534 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
535 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
536 | } | ||
522 | 537 | ||
523 | pcie_write_cmd(slot, slot_cmd); | 538 | rc = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
524 | slot->last_emi_toggle = get_seconds(); | 539 | slot->last_emi_toggle = get_seconds(); |
525 | DBG_LEAVE_ROUTINE | 540 | DBG_LEAVE_ROUTINE |
526 | return rc; | 541 | return rc; |
@@ -529,35 +544,32 @@ static int hpc_toggle_emi(struct slot *slot) | |||
529 | static int hpc_set_attention_status(struct slot *slot, u8 value) | 544 | static int hpc_set_attention_status(struct slot *slot, u8 value) |
530 | { | 545 | { |
531 | struct controller *ctrl = slot->ctrl; | 546 | struct controller *ctrl = slot->ctrl; |
532 | u16 slot_cmd = 0; | 547 | u16 slot_cmd; |
533 | u16 slot_ctrl; | 548 | u16 cmd_mask; |
534 | int rc = 0; | 549 | int rc; |
535 | 550 | ||
536 | DBG_ENTER_ROUTINE | 551 | DBG_ENTER_ROUTINE |
537 | 552 | ||
538 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 553 | cmd_mask = ATTN_LED_CTRL; |
539 | if (rc) { | ||
540 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
541 | return rc; | ||
542 | } | ||
543 | |||
544 | switch (value) { | 554 | switch (value) { |
545 | case 0 : /* turn off */ | 555 | case 0 : /* turn off */ |
546 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0; | 556 | slot_cmd = 0x00C0; |
547 | break; | 557 | break; |
548 | case 1: /* turn on */ | 558 | case 1: /* turn on */ |
549 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040; | 559 | slot_cmd = 0x0040; |
550 | break; | 560 | break; |
551 | case 2: /* turn blink */ | 561 | case 2: /* turn blink */ |
552 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080; | 562 | slot_cmd = 0x0080; |
553 | break; | 563 | break; |
554 | default: | 564 | default: |
555 | return -1; | 565 | return -1; |
556 | } | 566 | } |
557 | if (!pciehp_poll_mode) | 567 | if (!pciehp_poll_mode) { |
558 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 568 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
569 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
570 | } | ||
559 | 571 | ||
560 | pcie_write_cmd(slot, slot_cmd); | 572 | rc = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
561 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 573 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
562 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 574 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
563 | 575 | ||
@@ -570,21 +582,18 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
570 | { | 582 | { |
571 | struct controller *ctrl = slot->ctrl; | 583 | struct controller *ctrl = slot->ctrl; |
572 | u16 slot_cmd; | 584 | u16 slot_cmd; |
573 | u16 slot_ctrl; | 585 | u16 cmd_mask; |
574 | int rc = 0; | ||
575 | 586 | ||
576 | DBG_ENTER_ROUTINE | 587 | DBG_ENTER_ROUTINE |
577 | 588 | ||
578 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 589 | slot_cmd = 0x0100; |
579 | if (rc) { | 590 | cmd_mask = PWR_LED_CTRL; |
580 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 591 | if (!pciehp_poll_mode) { |
581 | return; | 592 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
593 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
582 | } | 594 | } |
583 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; | ||
584 | if (!pciehp_poll_mode) | ||
585 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
586 | 595 | ||
587 | pcie_write_cmd(slot, slot_cmd); | 596 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
588 | 597 | ||
589 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 598 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
590 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 599 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
@@ -596,22 +605,18 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
596 | { | 605 | { |
597 | struct controller *ctrl = slot->ctrl; | 606 | struct controller *ctrl = slot->ctrl; |
598 | u16 slot_cmd; | 607 | u16 slot_cmd; |
599 | u16 slot_ctrl; | 608 | u16 cmd_mask; |
600 | int rc = 0; | ||
601 | 609 | ||
602 | DBG_ENTER_ROUTINE | 610 | DBG_ENTER_ROUTINE |
603 | 611 | ||
604 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 612 | slot_cmd = 0x0300; |
605 | if (rc) { | 613 | cmd_mask = PWR_LED_CTRL; |
606 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 614 | if (!pciehp_poll_mode) { |
607 | return; | 615 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
616 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
608 | } | 617 | } |
609 | 618 | ||
610 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300; | 619 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
611 | |||
612 | if (!pciehp_poll_mode) | ||
613 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
614 | pcie_write_cmd(slot, slot_cmd); | ||
615 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 620 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
616 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 621 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
617 | 622 | ||
@@ -623,22 +628,18 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
623 | { | 628 | { |
624 | struct controller *ctrl = slot->ctrl; | 629 | struct controller *ctrl = slot->ctrl; |
625 | u16 slot_cmd; | 630 | u16 slot_cmd; |
626 | u16 slot_ctrl; | 631 | u16 cmd_mask; |
627 | int rc = 0; | ||
628 | 632 | ||
629 | DBG_ENTER_ROUTINE | 633 | DBG_ENTER_ROUTINE |
630 | 634 | ||
631 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 635 | slot_cmd = 0x0200; |
632 | if (rc) { | 636 | cmd_mask = PWR_LED_CTRL; |
633 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 637 | if (!pciehp_poll_mode) { |
634 | return; | 638 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
639 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
635 | } | 640 | } |
636 | 641 | ||
637 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200; | 642 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
638 | |||
639 | if (!pciehp_poll_mode) | ||
640 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
641 | pcie_write_cmd(slot, slot_cmd); | ||
642 | 643 | ||
643 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 644 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
644 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 645 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
@@ -669,7 +670,8 @@ static int hpc_power_on_slot(struct slot * slot) | |||
669 | { | 670 | { |
670 | struct controller *ctrl = slot->ctrl; | 671 | struct controller *ctrl = slot->ctrl; |
671 | u16 slot_cmd; | 672 | u16 slot_cmd; |
672 | u16 slot_ctrl, slot_status; | 673 | u16 cmd_mask; |
674 | u16 slot_status; | ||
673 | int retval = 0; | 675 | int retval = 0; |
674 | 676 | ||
675 | DBG_ENTER_ROUTINE | 677 | DBG_ENTER_ROUTINE |
@@ -692,23 +694,23 @@ static int hpc_power_on_slot(struct slot * slot) | |||
692 | } | 694 | } |
693 | } | 695 | } |
694 | 696 | ||
695 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 697 | slot_cmd = POWER_ON; |
696 | if (retval) { | 698 | cmd_mask = PWR_CTRL; |
697 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
698 | return retval; | ||
699 | } | ||
700 | |||
701 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; | ||
702 | |||
703 | /* Enable detection that we turned off at slot power-off time */ | 699 | /* Enable detection that we turned off at slot power-off time */ |
704 | if (!pciehp_poll_mode) | 700 | if (!pciehp_poll_mode) { |
705 | slot_cmd = slot_cmd | | 701 | slot_cmd = slot_cmd | |
706 | PWR_FAULT_DETECT_ENABLE | | 702 | PWR_FAULT_DETECT_ENABLE | |
707 | MRL_DETECT_ENABLE | | 703 | MRL_DETECT_ENABLE | |
708 | PRSN_DETECT_ENABLE | | 704 | PRSN_DETECT_ENABLE | |
709 | HP_INTR_ENABLE; | 705 | HP_INTR_ENABLE; |
706 | cmd_mask = cmd_mask | | ||
707 | PWR_FAULT_DETECT_ENABLE | | ||
708 | MRL_DETECT_ENABLE | | ||
709 | PRSN_DETECT_ENABLE | | ||
710 | HP_INTR_ENABLE; | ||
711 | } | ||
710 | 712 | ||
711 | retval = pcie_write_cmd(slot, slot_cmd); | 713 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
712 | 714 | ||
713 | if (retval) { | 715 | if (retval) { |
714 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); | 716 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); |
@@ -726,21 +728,15 @@ static int hpc_power_off_slot(struct slot * slot) | |||
726 | { | 728 | { |
727 | struct controller *ctrl = slot->ctrl; | 729 | struct controller *ctrl = slot->ctrl; |
728 | u16 slot_cmd; | 730 | u16 slot_cmd; |
729 | u16 slot_ctrl; | 731 | u16 cmd_mask; |
730 | int retval = 0; | 732 | int retval = 0; |
731 | 733 | ||
732 | DBG_ENTER_ROUTINE | 734 | DBG_ENTER_ROUTINE |
733 | 735 | ||
734 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); | 736 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); |
735 | 737 | ||
736 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 738 | slot_cmd = POWER_OFF; |
737 | if (retval) { | 739 | cmd_mask = PWR_CTRL; |
738 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
739 | return retval; | ||
740 | } | ||
741 | |||
742 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; | ||
743 | |||
744 | /* | 740 | /* |
745 | * If we get MRL or presence detect interrupts now, the isr | 741 | * If we get MRL or presence detect interrupts now, the isr |
746 | * will notice the sticky power-fault bit too and issue power | 742 | * will notice the sticky power-fault bit too and issue power |
@@ -748,14 +744,19 @@ static int hpc_power_off_slot(struct slot * slot) | |||
748 | * of command completions, since the power-fault bit remains on | 744 | * of command completions, since the power-fault bit remains on |
749 | * till the slot is powered on again. | 745 | * till the slot is powered on again. |
750 | */ | 746 | */ |
751 | if (!pciehp_poll_mode) | 747 | if (!pciehp_poll_mode) { |
752 | slot_cmd = (slot_cmd & | 748 | slot_cmd = (slot_cmd & |
753 | ~PWR_FAULT_DETECT_ENABLE & | 749 | ~PWR_FAULT_DETECT_ENABLE & |
754 | ~MRL_DETECT_ENABLE & | 750 | ~MRL_DETECT_ENABLE & |
755 | ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; | 751 | ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; |
752 | cmd_mask = cmd_mask | | ||
753 | PWR_FAULT_DETECT_ENABLE | | ||
754 | MRL_DETECT_ENABLE | | ||
755 | PRSN_DETECT_ENABLE | | ||
756 | HP_INTR_ENABLE; | ||
757 | } | ||
756 | 758 | ||
757 | retval = pcie_write_cmd(slot, slot_cmd); | 759 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
758 | |||
759 | if (retval) { | 760 | if (retval) { |
760 | err("%s: Write command failed!\n", __FUNCTION__); | 761 | err("%s: Write command failed!\n", __FUNCTION__); |
761 | return -1; | 762 | return -1; |
@@ -775,6 +776,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
775 | u16 temp_word; | 776 | u16 temp_word; |
776 | int hp_slot = 0; /* only 1 slot per PCI Express port */ | 777 | int hp_slot = 0; /* only 1 slot per PCI Express port */ |
777 | int rc = 0; | 778 | int rc = 0; |
779 | unsigned long flags; | ||
778 | 780 | ||
779 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 781 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
780 | if (rc) { | 782 | if (rc) { |
@@ -794,10 +796,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
794 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 796 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
795 | /* Mask Hot-plug Interrupt Enable */ | 797 | /* Mask Hot-plug Interrupt Enable */ |
796 | if (!pciehp_poll_mode) { | 798 | if (!pciehp_poll_mode) { |
799 | spin_lock_irqsave(&ctrl->lock, flags); | ||
797 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 800 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
798 | if (rc) { | 801 | if (rc) { |
799 | err("%s: Cannot read SLOT_CTRL register\n", | 802 | err("%s: Cannot read SLOT_CTRL register\n", |
800 | __FUNCTION__); | 803 | __FUNCTION__); |
804 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
801 | return IRQ_NONE; | 805 | return IRQ_NONE; |
802 | } | 806 | } |
803 | 807 | ||
@@ -808,8 +812,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
808 | if (rc) { | 812 | if (rc) { |
809 | err("%s: Cannot write to SLOTCTRL register\n", | 813 | err("%s: Cannot write to SLOTCTRL register\n", |
810 | __FUNCTION__); | 814 | __FUNCTION__); |
815 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
811 | return IRQ_NONE; | 816 | return IRQ_NONE; |
812 | } | 817 | } |
818 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
813 | 819 | ||
814 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 820 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
815 | if (rc) { | 821 | if (rc) { |
@@ -859,10 +865,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
859 | } | 865 | } |
860 | /* Unmask Hot-plug Interrupt Enable */ | 866 | /* Unmask Hot-plug Interrupt Enable */ |
861 | if (!pciehp_poll_mode) { | 867 | if (!pciehp_poll_mode) { |
868 | spin_lock_irqsave(&ctrl->lock, flags); | ||
862 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 869 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
863 | if (rc) { | 870 | if (rc) { |
864 | err("%s: Cannot read SLOTCTRL register\n", | 871 | err("%s: Cannot read SLOTCTRL register\n", |
865 | __FUNCTION__); | 872 | __FUNCTION__); |
873 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
866 | return IRQ_NONE; | 874 | return IRQ_NONE; |
867 | } | 875 | } |
868 | 876 | ||
@@ -873,8 +881,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
873 | if (rc) { | 881 | if (rc) { |
874 | err("%s: Cannot write to SLOTCTRL register\n", | 882 | err("%s: Cannot write to SLOTCTRL register\n", |
875 | __FUNCTION__); | 883 | __FUNCTION__); |
884 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
876 | return IRQ_NONE; | 885 | return IRQ_NONE; |
877 | } | 886 | } |
887 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
878 | 888 | ||
879 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 889 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
880 | if (rc) { | 890 | if (rc) { |
@@ -1237,6 +1247,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1237 | 1247 | ||
1238 | mutex_init(&ctrl->crit_sect); | 1248 | mutex_init(&ctrl->crit_sect); |
1239 | mutex_init(&ctrl->ctrl_lock); | 1249 | mutex_init(&ctrl->ctrl_lock); |
1250 | spin_lock_init(&ctrl->lock); | ||
1240 | 1251 | ||
1241 | /* setup wait queue */ | 1252 | /* setup wait queue */ |
1242 | init_waitqueue_head(&ctrl->queue); | 1253 | init_waitqueue_head(&ctrl->queue); |