aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c148
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)
733static irqreturn_t pcie_isr(int irq, void *dev_id) 728static 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);