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.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 4d8aee119134..83a5226ba9ed 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -302,21 +302,51 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
302 add_timer(&php_ctlr->int_poll_timer); 302 add_timer(&php_ctlr->int_poll_timer);
303} 303}
304 304
305static inline int is_ctrl_busy(struct controller *ctrl)
306{
307 u16 cmd_status = shpc_readw(ctrl, CMD_STATUS);
308 return cmd_status & 0x1;
309}
310
311/*
312 * Returns 1 if SHPC finishes executing a command within 1 sec,
313 * otherwise returns 0.
314 */
315static inline int shpc_poll_ctrl_busy(struct controller *ctrl)
316{
317 int i;
318
319 if (!is_ctrl_busy(ctrl))
320 return 1;
321
322 /* Check every 0.1 sec for a total of 1 sec */
323 for (i = 0; i < 10; i++) {
324 msleep(100);
325 if (!is_ctrl_busy(ctrl))
326 return 1;
327 }
328
329 return 0;
330}
331
305static inline int shpc_wait_cmd(struct controller *ctrl) 332static inline int shpc_wait_cmd(struct controller *ctrl)
306{ 333{
307 int retval = 0; 334 int retval = 0;
308 unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; 335 unsigned long timeout = msecs_to_jiffies(1000);
309 unsigned long timeout = msecs_to_jiffies(timeout_msec); 336 int rc;
310 int rc = wait_event_interruptible_timeout(ctrl->queue, 337
311 !ctrl->cmd_busy, timeout); 338 if (shpchp_poll_mode)
312 if (!rc) { 339 rc = shpc_poll_ctrl_busy(ctrl);
340 else
341 rc = wait_event_interruptible_timeout(ctrl->queue,
342 !is_ctrl_busy(ctrl), timeout);
343 if (!rc && is_ctrl_busy(ctrl)) {
313 retval = -EIO; 344 retval = -EIO;
314 err("Command not completed in %d msec\n", timeout_msec); 345 err("Command not completed in 1000 msec\n");
315 } else if (rc < 0) { 346 } else if (rc < 0) {
316 retval = -EINTR; 347 retval = -EINTR;
317 info("Command was interrupted by a signal\n"); 348 info("Command was interrupted by a signal\n");
318 } 349 }
319 ctrl->cmd_busy = 0;
320 350
321 return retval; 351 return retval;
322} 352}
@@ -327,26 +357,15 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
327 u16 cmd_status; 357 u16 cmd_status;
328 int retval = 0; 358 int retval = 0;
329 u16 temp_word; 359 u16 temp_word;
330 int i;
331 360
332 DBG_ENTER_ROUTINE 361 DBG_ENTER_ROUTINE
333 362
334 mutex_lock(&slot->ctrl->cmd_lock); 363 mutex_lock(&slot->ctrl->cmd_lock);
335 364
336 for (i = 0; i < 10; i++) { 365 if (!shpc_poll_ctrl_busy(ctrl)) {
337 cmd_status = shpc_readw(ctrl, CMD_STATUS);
338
339 if (!(cmd_status & 0x1))
340 break;
341 /* Check every 0.1 sec for a total of 1 sec*/
342 msleep(100);
343 }
344
345 cmd_status = shpc_readw(ctrl, CMD_STATUS);
346
347 if (cmd_status & 0x1) {
348 /* After 1 sec and and the controller is still busy */ 366 /* After 1 sec and and the controller is still busy */
349 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); 367 err("%s : Controller is still busy after 1 sec.\n",
368 __FUNCTION__);
350 retval = -EBUSY; 369 retval = -EBUSY;
351 goto out; 370 goto out;
352 } 371 }
@@ -358,7 +377,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
358 /* To make sure the Controller Busy bit is 0 before we send out the 377 /* To make sure the Controller Busy bit is 0 before we send out the
359 * command. 378 * command.
360 */ 379 */
361 slot->ctrl->cmd_busy = 1;
362 shpc_writew(ctrl, CMD, temp_word); 380 shpc_writew(ctrl, CMD, temp_word);
363 381
364 /* 382 /*
@@ -908,7 +926,6 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
908 serr_int &= ~SERR_INTR_RSVDZ_MASK; 926 serr_int &= ~SERR_INTR_RSVDZ_MASK;
909 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); 927 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
910 928
911 ctrl->cmd_busy = 0;
912 wake_up_interruptible(&ctrl->queue); 929 wake_up_interruptible(&ctrl->queue);
913 } 930 }
914 931
@@ -1101,7 +1118,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1101{ 1118{
1102 struct php_ctlr_state_s *php_ctlr, *p; 1119 struct php_ctlr_state_s *php_ctlr, *p;
1103 void *instance_id = ctrl; 1120 void *instance_id = ctrl;
1104 int rc, num_slots = 0; 1121 int rc = -1, num_slots = 0;
1105 u8 hp_slot; 1122 u8 hp_slot;
1106 u32 shpc_base_offset; 1123 u32 shpc_base_offset;
1107 u32 tempdword, slot_reg, slot_config; 1124 u32 tempdword, slot_reg, slot_config;
@@ -1167,11 +1184,15 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1167 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 1184 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
1168 pdev->subsystem_device); 1185 pdev->subsystem_device);
1169 1186
1170 if (pci_enable_device(pdev)) 1187 rc = pci_enable_device(pdev);
1188 if (rc) {
1189 err("%s: pci_enable_device failed\n", __FUNCTION__);
1171 goto abort_free_ctlr; 1190 goto abort_free_ctlr;
1191 }
1172 1192
1173 if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { 1193 if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
1174 err("%s: cannot reserve MMIO region\n", __FUNCTION__); 1194 err("%s: cannot reserve MMIO region\n", __FUNCTION__);
1195 rc = -1;
1175 goto abort_free_ctlr; 1196 goto abort_free_ctlr;
1176 } 1197 }
1177 1198
@@ -1180,6 +1201,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1180 err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, 1201 err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
1181 ctrl->mmio_size, ctrl->mmio_base); 1202 ctrl->mmio_size, ctrl->mmio_base);
1182 release_mem_region(ctrl->mmio_base, ctrl->mmio_size); 1203 release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
1204 rc = -1;
1183 goto abort_free_ctlr; 1205 goto abort_free_ctlr;
1184 } 1206 }
1185 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); 1207 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
@@ -1282,8 +1304,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1282 */ 1304 */
1283 if (atomic_add_return(1, &shpchp_num_controllers) == 1) { 1305 if (atomic_add_return(1, &shpchp_num_controllers) == 1) {
1284 shpchp_wq = create_singlethread_workqueue("shpchpd"); 1306 shpchp_wq = create_singlethread_workqueue("shpchpd");
1285 if (!shpchp_wq) 1307 if (!shpchp_wq) {
1286 return -ENOMEM; 1308 rc = -ENOMEM;
1309 goto abort_free_ctlr;
1310 }
1287 } 1311 }
1288 1312
1289 /* 1313 /*
@@ -1313,8 +1337,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1313 1337
1314 /* We end up here for the many possible ways to fail this API. */ 1338 /* We end up here for the many possible ways to fail this API. */
1315abort_free_ctlr: 1339abort_free_ctlr:
1340 if (php_ctlr->creg)
1341 iounmap(php_ctlr->creg);
1316 kfree(php_ctlr); 1342 kfree(php_ctlr);
1317abort: 1343abort:
1318 DBG_LEAVE_ROUTINE 1344 DBG_LEAVE_ROUTINE
1319 return -1; 1345 return rc;
1320} 1346}