aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h3
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c40
2 files changed, 36 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 920091c4b18d..79c9ddaad3fb 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -97,6 +97,7 @@ 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 unsigned int no_cmd_complete:1;
100}; 101};
101 102
102#define INT_BUTTON_IGNORE 0 103#define INT_BUTTON_IGNORE 0
@@ -135,6 +136,7 @@ struct controller {
135#define PWR_LED_PRSN 0x00000010 136#define PWR_LED_PRSN 0x00000010
136#define HP_SUPR_RM_SUP 0x00000020 137#define HP_SUPR_RM_SUP 0x00000020
137#define EMI_PRSN 0x00020000 138#define EMI_PRSN 0x00020000
139#define NO_CMD_CMPL_SUP 0x00040000
138 140
139#define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN) 141#define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN)
140#define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN) 142#define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN)
@@ -143,6 +145,7 @@ struct controller {
143#define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN) 145#define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN)
144#define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP) 146#define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP)
145#define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN) 147#define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN)
148#define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & NO_CMD_CMPL_SUP)
146 149
147extern int pciehp_sysfs_enable_slot(struct slot *slot); 150extern int pciehp_sysfs_enable_slot(struct slot *slot);
148extern int pciehp_sysfs_disable_slot(struct slot *slot); 151extern int pciehp_sysfs_disable_slot(struct slot *slot);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 425a0f609977..70940fb3fffa 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -286,12 +286,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
286 goto out; 286 goto out;
287 } 287 }
288 288
289 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 289 if (slot_status & CMD_COMPLETED) {
290 /* After 1 sec and CMD_COMPLETED still not set, just 290 if (!ctrl->no_cmd_complete) {
291 proceed forward to issue the next command according 291 /*
292 to spec. Just print out the error message */ 292 * After 1 sec and CMD_COMPLETED still not set, just
293 dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", 293 * proceed forward to issue the next command according
294 __func__); 294 * to spec. Just print out the error message.
295 */
296 dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
297 __func__);
298 } else if (!NO_CMD_CMPL(ctrl)) {
299 /*
300 * This controller semms to notify of command completed
301 * event even though it supports none of power
302 * controller, attention led, power led and EMI.
303 */
304 dbg("%s: Unexpected CMD_COMPLETED. Need to wait for "
305 "command completed event.\n", __func__);
306 ctrl->no_cmd_complete = 0;
307 } else {
308 dbg("%s: Unexpected CMD_COMPLETED. Maybe the "
309 "controller is broken.\n", __func__);
310 }
295 } 311 }
296 312
297 retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); 313 retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
@@ -315,7 +331,7 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
315 /* 331 /*
316 * Wait for command completion. 332 * Wait for command completion.
317 */ 333 */
318 if (!retval) 334 if (!retval && !ctrl->no_cmd_complete)
319 retval = pcie_wait_cmd(ctrl); 335 retval = pcie_wait_cmd(ctrl);
320 out: 336 out:
321 mutex_unlock(&ctrl->ctrl_lock); 337 mutex_unlock(&ctrl->ctrl_lock);
@@ -1130,6 +1146,7 @@ static inline void dbg_ctrl(struct controller *ctrl)
1130 dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); 1146 dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no");
1131 dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); 1147 dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
1132 dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); 1148 dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no");
1149 dbg(" Comamnd Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
1133 pciehp_readw(ctrl, SLOTSTATUS, &reg16); 1150 pciehp_readw(ctrl, SLOTSTATUS, &reg16);
1134 dbg("Slot Status : 0x%04x\n", reg16); 1151 dbg("Slot Status : 0x%04x\n", reg16);
1135 pciehp_readw(ctrl, SLOTSTATUS, &reg16); 1152 pciehp_readw(ctrl, SLOTSTATUS, &reg16);
@@ -1161,6 +1178,15 @@ int pcie_init(struct controller *ctrl, struct pcie_device *dev)
1161 mutex_init(&ctrl->ctrl_lock); 1178 mutex_init(&ctrl->ctrl_lock);
1162 init_waitqueue_head(&ctrl->queue); 1179 init_waitqueue_head(&ctrl->queue);
1163 dbg_ctrl(ctrl); 1180 dbg_ctrl(ctrl);
1181 /*
1182 * Controller doesn't notify of command completion if the "No
1183 * Command Completed Support" bit is set in Slot Capability
1184 * register or the controller supports none of power
1185 * controller, attention led, power led and EMI.
1186 */
1187 if (NO_CMD_CMPL(ctrl) ||
1188 !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl)))
1189 ctrl->no_cmd_complete = 1;
1164 1190
1165 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", 1191 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
1166 pdev->vendor, pdev->device, 1192 pdev->vendor, pdev->device,