diff options
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 148 |
2 files changed, 29 insertions, 120 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index f14267e197dd..9dd132925ffa 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -97,7 +97,6 @@ struct controller { | |||
97 | u8 cap_base; | 97 | u8 cap_base; |
98 | struct timer_list poll_timer; | 98 | struct timer_list poll_timer; |
99 | volatile int cmd_busy; | 99 | volatile int cmd_busy; |
100 | spinlock_t lock; | ||
101 | }; | 100 | }; |
102 | 101 | ||
103 | #define INT_BUTTON_IGNORE 0 | 102 | #define INT_BUTTON_IGNORE 0 |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b4bbd07d1e39..51a5055f6965 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -252,7 +252,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask) | |||
252 | int retval = 0; | 252 | int retval = 0; |
253 | u16 slot_status; | 253 | u16 slot_status; |
254 | u16 slot_ctrl; | 254 | u16 slot_ctrl; |
255 | unsigned long flags; | ||
256 | 255 | ||
257 | mutex_lock(&ctrl->ctrl_lock); | 256 | mutex_lock(&ctrl->ctrl_lock); |
258 | 257 | ||
@@ -270,11 +269,10 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask) | |||
270 | __func__); | 269 | __func__); |
271 | } | 270 | } |
272 | 271 | ||
273 | spin_lock_irqsave(&ctrl->lock, flags); | ||
274 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 272 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
275 | if (retval) { | 273 | if (retval) { |
276 | err("%s: Cannot read SLOTCTRL register\n", __func__); | 274 | err("%s: Cannot read SLOTCTRL register\n", __func__); |
277 | goto out_spin_unlock; | 275 | goto out; |
278 | } | 276 | } |
279 | 277 | ||
280 | slot_ctrl &= ~mask; | 278 | slot_ctrl &= ~mask; |
@@ -285,9 +283,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask) | |||
285 | if (retval) | 283 | if (retval) |
286 | err("%s: Cannot write to SLOTCTRL register\n", __func__); | 284 | err("%s: Cannot write to SLOTCTRL register\n", __func__); |
287 | 285 | ||
288 | out_spin_unlock: | ||
289 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
290 | |||
291 | /* | 286 | /* |
292 | * Wait for command completion. | 287 | * Wait for command completion. |
293 | */ | 288 | */ |
@@ -733,139 +728,55 @@ static int hpc_power_off_slot(struct slot * slot) | |||
733 | static irqreturn_t pcie_isr(int irq, void *dev_id) | 728 | static irqreturn_t pcie_isr(int irq, void *dev_id) |
734 | { | 729 | { |
735 | struct controller *ctrl = (struct controller *)dev_id; | 730 | struct controller *ctrl = (struct controller *)dev_id; |
736 | u16 slot_status, intr_detect, intr_loc; | 731 | u16 detected, intr_loc; |
737 | u16 temp_word; | ||
738 | int hp_slot = 0; /* only 1 slot per PCI Express port */ | ||
739 | int rc = 0; | ||
740 | unsigned long flags; | ||
741 | |||
742 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
743 | if (rc) { | ||
744 | err("%s: Cannot read SLOTSTATUS register\n", __func__); | ||
745 | return IRQ_NONE; | ||
746 | } | ||
747 | 732 | ||
748 | intr_detect = (ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | | 733 | /* |
749 | MRL_SENS_CHANGED | PRSN_DETECT_CHANGED | CMD_COMPLETED); | 734 | * In order to guarantee that all interrupt events are |
750 | 735 | * serviced, we need to re-inspect Slot Status register after | |
751 | intr_loc = slot_status & intr_detect; | 736 | * clearing what is presumed to be the last pending interrupt. |
752 | 737 | */ | |
753 | /* Check to see if it was our interrupt */ | 738 | intr_loc = 0; |
754 | if ( !intr_loc ) | 739 | do { |
755 | return IRQ_NONE; | 740 | if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) { |
756 | 741 | err("%s: Cannot read SLOTSTATUS\n", __func__); | |
757 | dbg("%s: intr_loc %x\n", __func__, intr_loc); | ||
758 | /* Mask Hot-plug Interrupt Enable */ | ||
759 | if (!pciehp_poll_mode) { | ||
760 | spin_lock_irqsave(&ctrl->lock, flags); | ||
761 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
762 | if (rc) { | ||
763 | err("%s: Cannot read SLOT_CTRL register\n", | ||
764 | __func__); | ||
765 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
766 | return IRQ_NONE; | 742 | return IRQ_NONE; |
767 | } | 743 | } |
768 | 744 | ||
769 | dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n", | 745 | detected &= (ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | |
770 | __func__, temp_word); | 746 | MRL_SENS_CHANGED | PRSN_DETECT_CHANGED | |
771 | temp_word = (temp_word & ~HP_INTR_ENABLE & | 747 | CMD_COMPLETED); |
772 | ~CMD_CMPL_INTR_ENABLE) | 0x00; | 748 | intr_loc |= detected; |
773 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | 749 | if (!intr_loc) |
774 | if (rc) { | ||
775 | err("%s: Cannot write to SLOTCTRL register\n", | ||
776 | __func__); | ||
777 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
778 | return IRQ_NONE; | 750 | return IRQ_NONE; |
779 | } | 751 | if (pciehp_writew(ctrl, SLOTSTATUS, detected)) { |
780 | spin_unlock_irqrestore(&ctrl->lock, flags); | 752 | err("%s: Cannot write to SLOTSTATUS\n", __func__); |
781 | |||
782 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
783 | if (rc) { | ||
784 | err("%s: Cannot read SLOT_STATUS register\n", | ||
785 | __func__); | ||
786 | return IRQ_NONE; | 753 | return IRQ_NONE; |
787 | } | 754 | } |
788 | dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n", | 755 | } while (detected); |
789 | __func__, slot_status); | ||
790 | 756 | ||
791 | /* Clear command complete interrupt caused by this write */ | 757 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
792 | temp_word = 0x1f; | ||
793 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
794 | if (rc) { | ||
795 | err("%s: Cannot write to SLOTSTATUS register\n", | ||
796 | __func__); | ||
797 | return IRQ_NONE; | ||
798 | } | ||
799 | } | ||
800 | 758 | ||
759 | /* Check Command Complete Interrupt Pending */ | ||
801 | if (intr_loc & CMD_COMPLETED) { | 760 | if (intr_loc & CMD_COMPLETED) { |
802 | /* | ||
803 | * Command Complete Interrupt Pending | ||
804 | */ | ||
805 | ctrl->cmd_busy = 0; | 761 | ctrl->cmd_busy = 0; |
806 | wake_up_interruptible(&ctrl->queue); | 762 | wake_up_interruptible(&ctrl->queue); |
807 | } | 763 | } |
808 | 764 | ||
765 | /* Check MRL Sensor Changed */ | ||
809 | if (intr_loc & MRL_SENS_CHANGED) | 766 | if (intr_loc & MRL_SENS_CHANGED) |
810 | pciehp_handle_switch_change(hp_slot, ctrl); | 767 | pciehp_handle_switch_change(0, ctrl); |
811 | 768 | ||
769 | /* Check Attention Button Pressed */ | ||
812 | if (intr_loc & ATTN_BUTTN_PRESSED) | 770 | if (intr_loc & ATTN_BUTTN_PRESSED) |
813 | pciehp_handle_attention_button(hp_slot, ctrl); | 771 | pciehp_handle_attention_button(0, ctrl); |
814 | 772 | ||
773 | /* Check Presence Detect Changed */ | ||
815 | if (intr_loc & PRSN_DETECT_CHANGED) | 774 | if (intr_loc & PRSN_DETECT_CHANGED) |
816 | pciehp_handle_presence_change(hp_slot, ctrl); | 775 | pciehp_handle_presence_change(0, ctrl); |
817 | 776 | ||
777 | /* Check Power Fault Detected */ | ||
818 | if (intr_loc & PWR_FAULT_DETECTED) | 778 | if (intr_loc & PWR_FAULT_DETECTED) |
819 | pciehp_handle_power_fault(hp_slot, ctrl); | 779 | pciehp_handle_power_fault(0, ctrl); |
820 | |||
821 | /* Clear all events after serving them */ | ||
822 | temp_word = 0x1F; | ||
823 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
824 | if (rc) { | ||
825 | err("%s: Cannot write to SLOTSTATUS register\n", __func__); | ||
826 | return IRQ_NONE; | ||
827 | } | ||
828 | /* Unmask Hot-plug Interrupt Enable */ | ||
829 | if (!pciehp_poll_mode) { | ||
830 | spin_lock_irqsave(&ctrl->lock, flags); | ||
831 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
832 | if (rc) { | ||
833 | err("%s: Cannot read SLOTCTRL register\n", | ||
834 | __func__); | ||
835 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
836 | return IRQ_NONE; | ||
837 | } | ||
838 | |||
839 | dbg("%s: Unmask Hot-plug Interrupt Enable\n", __func__); | ||
840 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | ||
841 | |||
842 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
843 | if (rc) { | ||
844 | err("%s: Cannot write to SLOTCTRL register\n", | ||
845 | __func__); | ||
846 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
847 | return IRQ_NONE; | ||
848 | } | ||
849 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
850 | |||
851 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
852 | if (rc) { | ||
853 | err("%s: Cannot read SLOT_STATUS register\n", | ||
854 | __func__); | ||
855 | return IRQ_NONE; | ||
856 | } | ||
857 | |||
858 | /* Clear command complete interrupt caused by this write */ | ||
859 | temp_word = 0x1F; | ||
860 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
861 | if (rc) { | ||
862 | err("%s: Cannot write to SLOTSTATUS failed\n", | ||
863 | __func__); | ||
864 | return IRQ_NONE; | ||
865 | } | ||
866 | dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n", | ||
867 | __func__, temp_word); | ||
868 | } | ||
869 | 780 | ||
870 | return IRQ_HANDLED; | 781 | return IRQ_HANDLED; |
871 | } | 782 | } |
@@ -1334,7 +1245,6 @@ int pcie_init(struct controller *ctrl, struct pcie_device *dev) | |||
1334 | 1245 | ||
1335 | mutex_init(&ctrl->crit_sect); | 1246 | mutex_init(&ctrl->crit_sect); |
1336 | mutex_init(&ctrl->ctrl_lock); | 1247 | mutex_init(&ctrl->ctrl_lock); |
1337 | spin_lock_init(&ctrl->lock); | ||
1338 | 1248 | ||
1339 | /* setup wait queue */ | 1249 | /* setup wait queue */ |
1340 | init_waitqueue_head(&ctrl->queue); | 1250 | init_waitqueue_head(&ctrl->queue); |