aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/shpchp_hpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index ae81427e42b1..c32a1b16704f 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -231,6 +231,7 @@ static spinlock_t list_lock;
231static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); 231static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
232 232
233static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); 233static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
234static int hpc_check_cmd_status(struct controller *ctrl);
234 235
235/* This is the interrupt polling timeout function. */ 236/* This is the interrupt polling timeout function. */
236static void int_poll_timeout(unsigned long lphp_ctlr) 237static void int_poll_timeout(unsigned long lphp_ctlr)
@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
303 int i; 304 int i;
304 305
305 DBG_ENTER_ROUTINE 306 DBG_ENTER_ROUTINE
306 307
308 mutex_lock(&slot->ctrl->cmd_lock);
309
307 if (!php_ctlr) { 310 if (!php_ctlr) {
308 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 311 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
309 return -1; 312 retval = -EINVAL;
313 goto out;
310 } 314 }
311 315
312 for (i = 0; i < 10; i++) { 316 for (i = 0; i < 10; i++) {
@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
323 if (cmd_status & 0x1) { 327 if (cmd_status & 0x1) {
324 /* After 1 sec and and the controller is still busy */ 328 /* After 1 sec and and the controller is still busy */
325 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); 329 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
326 return -1; 330 retval = -EBUSY;
331 goto out;
327 } 332 }
328 333
329 ++t_slot; 334 ++t_slot;
@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
340 * Wait for command completion. 345 * Wait for command completion.
341 */ 346 */
342 retval = shpc_wait_cmd(slot->ctrl); 347 retval = shpc_wait_cmd(slot->ctrl);
348 if (retval)
349 goto out;
350
351 cmd_status = hpc_check_cmd_status(slot->ctrl);
352 if (cmd_status) {
353 err("%s: Failed to issued command 0x%x (error code = %d)\n",
354 __FUNCTION__, cmd, cmd_status);
355 retval = -EIO;
356 }
357 out:
358 mutex_unlock(&slot->ctrl->cmd_lock);
343 359
344 DBG_LEAVE_ROUTINE 360 DBG_LEAVE_ROUTINE
345 return retval; 361 return retval;
@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
1343 .green_led_blink = hpc_set_green_led_blink, 1359 .green_led_blink = hpc_set_green_led_blink,
1344 1360
1345 .release_ctlr = hpc_release_ctlr, 1361 .release_ctlr = hpc_release_ctlr,
1346 .check_cmd_status = hpc_check_cmd_status,
1347}; 1362};
1348 1363
1349inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, 1364inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1455 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); 1470 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
1456 1471
1457 mutex_init(&ctrl->crit_sect); 1472 mutex_init(&ctrl->crit_sect);
1473 mutex_init(&ctrl->cmd_lock);
1474
1458 /* Setup wait queue */ 1475 /* Setup wait queue */
1459 init_waitqueue_head(&ctrl->queue); 1476 init_waitqueue_head(&ctrl->queue);
1460 1477