aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 891f81a0400c..425a0f609977 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -722,6 +722,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
722{ 722{
723 struct controller *ctrl = (struct controller *)dev_id; 723 struct controller *ctrl = (struct controller *)dev_id;
724 u16 detected, intr_loc; 724 u16 detected, intr_loc;
725 struct slot *p_slot;
725 726
726 /* 727 /*
727 * In order to guarantee that all interrupt events are 728 * In order to guarantee that all interrupt events are
@@ -756,21 +757,38 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
756 wake_up_interruptible(&ctrl->queue); 757 wake_up_interruptible(&ctrl->queue);
757 } 758 }
758 759
760 if (!(intr_loc & ~CMD_COMPLETED))
761 return IRQ_HANDLED;
762
763 /*
764 * Return without handling events if this handler routine is
765 * called before controller initialization is done. This may
766 * happen if hotplug event or another interrupt that shares
767 * the IRQ with pciehp arrives before slot initialization is
768 * done after interrupt handler is registered.
769 *
770 * FIXME - Need more structural fixes. We need to be ready to
771 * handle the event before installing interrupt handler.
772 */
773 p_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
774 if (!p_slot || !p_slot->hpc_ops)
775 return IRQ_HANDLED;
776
759 /* Check MRL Sensor Changed */ 777 /* Check MRL Sensor Changed */
760 if (intr_loc & MRL_SENS_CHANGED) 778 if (intr_loc & MRL_SENS_CHANGED)
761 pciehp_handle_switch_change(0, ctrl); 779 pciehp_handle_switch_change(p_slot);
762 780
763 /* Check Attention Button Pressed */ 781 /* Check Attention Button Pressed */
764 if (intr_loc & ATTN_BUTTN_PRESSED) 782 if (intr_loc & ATTN_BUTTN_PRESSED)
765 pciehp_handle_attention_button(0, ctrl); 783 pciehp_handle_attention_button(p_slot);
766 784
767 /* Check Presence Detect Changed */ 785 /* Check Presence Detect Changed */
768 if (intr_loc & PRSN_DETECT_CHANGED) 786 if (intr_loc & PRSN_DETECT_CHANGED)
769 pciehp_handle_presence_change(0, ctrl); 787 pciehp_handle_presence_change(p_slot);
770 788
771 /* Check Power Fault Detected */ 789 /* Check Power Fault Detected */
772 if (intr_loc & PWR_FAULT_DETECTED) 790 if (intr_loc & PWR_FAULT_DETECTED)
773 pciehp_handle_power_fault(0, ctrl); 791 pciehp_handle_power_fault(p_slot);
774 792
775 return IRQ_HANDLED; 793 return IRQ_HANDLED;
776} 794}
@@ -1028,6 +1046,12 @@ static int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1028static int pcie_init_hardware_part1(struct controller *ctrl, 1046static int pcie_init_hardware_part1(struct controller *ctrl,
1029 struct pcie_device *dev) 1047 struct pcie_device *dev)
1030{ 1048{
1049 /* Clear all remaining event bits in Slot Status register */
1050 if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f)) {
1051 err("%s: Cannot write to SLOTSTATUS register\n", __func__);
1052 return -1;
1053 }
1054
1031 /* Mask Hot-plug Interrupt Enable */ 1055 /* Mask Hot-plug Interrupt Enable */
1032 if (pcie_write_cmd(ctrl, 0, HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE)) { 1056 if (pcie_write_cmd(ctrl, 0, HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE)) {
1033 err("%s: Cannot mask hotplug interrupt enable\n", __func__); 1057 err("%s: Cannot mask hotplug interrupt enable\n", __func__);
@@ -1040,16 +1064,6 @@ int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev)
1040{ 1064{
1041 u16 cmd, mask; 1065 u16 cmd, mask;
1042 1066
1043 /*
1044 * We need to clear all events before enabling hotplug interrupt
1045 * notification mechanism in order for hotplug controler to
1046 * generate interrupts.
1047 */
1048 if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f)) {
1049 err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
1050 return -1;
1051 }
1052
1053 cmd = PRSN_DETECT_ENABLE; 1067 cmd = PRSN_DETECT_ENABLE;
1054 if (ATTN_BUTTN(ctrl)) 1068 if (ATTN_BUTTN(ctrl))
1055 cmd |= ATTN_BUTTN_ENABLE; 1069 cmd |= ATTN_BUTTN_ENABLE;