aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2018-05-15 02:14:43 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2018-06-12 00:05:16 -0400
commit4e56828a5db19e2de8f8dc464c6df2e7e9ff4e13 (patch)
treeacc4c44cb01969f50279d7367cf57870cfefad6f
parent0e82e5c1fad79ffe9d316296c7a4c1de539d0c48 (diff)
fsi/fsi-master-gpio: Implement CRC error recovery
The FSI protocol defines two modes of recovery from CRC errors, this implements both: - If the device returns an ECRC (it detected a CRC error in the command), then we simply issue the command again. - If the master detects a CRC error in the response, we send an E_POLL command which requests a resend of the response without actually re-executing the command (which could otherwise have unwanted side effects such as dequeuing a FIFO twice). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reviewed-by: Christopher Bostic <cbostic@linux.vnet.ibm.com> Tested-by: Joel Stanley <joel@jms.id.au> --- Note: This was actually tested by removing some of my fixes, thus causing us to hit occasional CRC errors during high LPC activity.
-rw-r--r--drivers/fsi/fsi-master-gpio.c90
-rw-r--r--include/trace/events/fsi_master_gpio.h27
2 files changed, 99 insertions, 18 deletions
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
index 0a6799bda294..351c12f2ac55 100644
--- a/drivers/fsi/fsi-master-gpio.c
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -22,20 +22,23 @@
22#define FSI_BREAK_CLOCKS 256 /* Number of clocks to issue break */ 22#define FSI_BREAK_CLOCKS 256 /* Number of clocks to issue break */
23#define FSI_POST_BREAK_CLOCKS 16000 /* Number clocks to set up cfam */ 23#define FSI_POST_BREAK_CLOCKS 16000 /* Number clocks to set up cfam */
24#define FSI_INIT_CLOCKS 5000 /* Clock out any old data */ 24#define FSI_INIT_CLOCKS 5000 /* Clock out any old data */
25#define FSI_GPIO_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */
26#define FSI_GPIO_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */
25#define FSI_GPIO_STD_DELAY 10 /* Standard GPIO delay in nS */ 27#define FSI_GPIO_STD_DELAY 10 /* Standard GPIO delay in nS */
26 /* todo: adjust down as low as */ 28 /* todo: adjust down as low as */
27 /* possible or eliminate */ 29 /* possible or eliminate */
30#define FSI_CRC_ERR_RETRIES 10
31
28#define FSI_GPIO_CMD_DPOLL 0x2 32#define FSI_GPIO_CMD_DPOLL 0x2
33#define FSI_GPIO_CMD_EPOLL 0x3
29#define FSI_GPIO_CMD_TERM 0x3f 34#define FSI_GPIO_CMD_TERM 0x3f
30#define FSI_GPIO_CMD_ABS_AR 0x4 35#define FSI_GPIO_CMD_ABS_AR 0x4
31#define FSI_GPIO_CMD_REL_AR 0x5 36#define FSI_GPIO_CMD_REL_AR 0x5
32#define FSI_GPIO_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */ 37#define FSI_GPIO_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */
33 38
34 39/* Slave responses */
35#define FSI_GPIO_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ 40#define FSI_GPIO_RESP_ACK 0 /* Success */
36 41#define FSI_GPIO_RESP_BUSY 1 /* Slave busy */
37/* Bus errors */
38#define FSI_GPIO_ERR_BUSY 1 /* Slave stuck in busy state */
39#define FSI_GPIO_RESP_ERRA 2 /* Any (misc) Error */ 42#define FSI_GPIO_RESP_ERRA 2 /* Any (misc) Error */
40#define FSI_GPIO_RESP_ERRC 3 /* Slave reports master CRC error */ 43#define FSI_GPIO_RESP_ERRC 3 /* Slave reports master CRC error */
41#define FSI_GPIO_MTOE 4 /* Master time out error */ 44#define FSI_GPIO_MTOE 4 /* Master time out error */
@@ -330,6 +333,16 @@ static void build_dpoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id)
330 msg_push_crc(cmd); 333 msg_push_crc(cmd);
331} 334}
332 335
336static void build_epoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id)
337{
338 cmd->bits = 0;
339 cmd->msg = 0;
340
341 msg_push_bits(cmd, slave_id, 2);
342 msg_push_bits(cmd, FSI_GPIO_CMD_EPOLL, 3);
343 msg_push_crc(cmd);
344}
345
333static void echo_delay(struct fsi_master_gpio *master) 346static void echo_delay(struct fsi_master_gpio *master)
334{ 347{
335 set_sda_output(master, 1); 348 set_sda_output(master, 1);
@@ -355,6 +368,12 @@ static void fsi_master_gpio_error(struct fsi_master_gpio *master, int error)
355 368
356} 369}
357 370
371/*
372 * Note: callers rely specifically on this returning -EAGAIN for
373 * a CRC error detected in the response. Use other error code
374 * for other situations. It will be converted to something else
375 * higher up the stack before it reaches userspace.
376 */
358static int read_one_response(struct fsi_master_gpio *master, 377static int read_one_response(struct fsi_master_gpio *master,
359 uint8_t data_size, struct fsi_gpio_msg *msgp, uint8_t *tagp) 378 uint8_t data_size, struct fsi_gpio_msg *msgp, uint8_t *tagp)
360{ 379{
@@ -379,7 +398,7 @@ static int read_one_response(struct fsi_master_gpio *master,
379 "Master time out waiting for response\n"); 398 "Master time out waiting for response\n");
380 fsi_master_gpio_error(master, FSI_GPIO_MTOE); 399 fsi_master_gpio_error(master, FSI_GPIO_MTOE);
381 spin_unlock_irqrestore(&master->bit_lock, flags); 400 spin_unlock_irqrestore(&master->bit_lock, flags);
382 return -EIO; 401 return -ETIMEDOUT;
383 } 402 }
384 403
385 msg.bits = 0; 404 msg.bits = 0;
@@ -405,7 +424,7 @@ static int read_one_response(struct fsi_master_gpio *master,
405 if (crc) { 424 if (crc) {
406 dev_dbg(master->dev, "ERR response CRC\n"); 425 dev_dbg(master->dev, "ERR response CRC\n");
407 fsi_master_gpio_error(master, FSI_GPIO_CRC_INVAL); 426 fsi_master_gpio_error(master, FSI_GPIO_CRC_INVAL);
408 return -EIO; 427 return -EAGAIN;
409 } 428 }
410 429
411 if (msgp) 430 if (msgp)
@@ -451,11 +470,33 @@ static int poll_for_response(struct fsi_master_gpio *master,
451 unsigned long flags; 470 unsigned long flags;
452 uint8_t tag; 471 uint8_t tag;
453 uint8_t *data_byte = data; 472 uint8_t *data_byte = data;
454 473 int crc_err_retries = 0;
455retry: 474retry:
456 rc = read_one_response(master, size, &response, &tag); 475 rc = read_one_response(master, size, &response, &tag);
457 if (rc) 476
458 return rc; 477 /* Handle retries on CRC errors */
478 if (rc == -EAGAIN) {
479 /* Too many retries ? */
480 if (crc_err_retries++ > FSI_CRC_ERR_RETRIES) {
481 /*
482 * Pass it up as a -EIO otherwise upper level will retry
483 * the whole command which isn't what we want here.
484 */
485 rc = -EIO;
486 goto fail;
487 }
488 dev_dbg(master->dev,
489 "CRC error retry %d\n", crc_err_retries);
490 trace_fsi_master_gpio_crc_rsp_error(master);
491 build_epoll_command(&cmd, slave);
492 spin_lock_irqsave(&master->bit_lock, flags);
493 clock_zeros(master, FSI_GPIO_EPOLL_CLOCKS);
494 serial_out(master, &cmd);
495 echo_delay(master);
496 spin_unlock_irqrestore(&master->bit_lock, flags);
497 goto retry;
498 } else if (rc)
499 goto fail;
459 500
460 switch (tag) { 501 switch (tag) {
461 case FSI_GPIO_RESP_ACK: 502 case FSI_GPIO_RESP_ACK:
@@ -496,18 +537,21 @@ retry:
496 break; 537 break;
497 538
498 case FSI_GPIO_RESP_ERRA: 539 case FSI_GPIO_RESP_ERRA:
499 case FSI_GPIO_RESP_ERRC: 540 dev_dbg(master->dev, "ERRA received: 0x%x\n", (int)response.msg);
500 dev_dbg(master->dev, "ERR%c received: 0x%x\n",
501 tag == FSI_GPIO_RESP_ERRA ? 'A' : 'C',
502 (int)response.msg);
503 fsi_master_gpio_error(master, response.msg); 541 fsi_master_gpio_error(master, response.msg);
504 rc = -EIO; 542 rc = -EIO;
505 break; 543 break;
544 case FSI_GPIO_RESP_ERRC:
545 dev_dbg(master->dev, "ERRC received: 0x%x\n", (int)response.msg);
546 fsi_master_gpio_error(master, response.msg);
547 trace_fsi_master_gpio_crc_cmd_error(master);
548 rc = -EAGAIN;
549 break;
506 } 550 }
507 551
508 if (busy_count > 0) 552 if (busy_count > 0)
509 trace_fsi_master_gpio_poll_response_busy(master, busy_count); 553 trace_fsi_master_gpio_poll_response_busy(master, busy_count);
510 554 fail:
511 /* Clock the slave enough to be ready for next operation */ 555 /* Clock the slave enough to be ready for next operation */
512 spin_lock_irqsave(&master->bit_lock, flags); 556 spin_lock_irqsave(&master->bit_lock, flags);
513 clock_zeros(master, FSI_GPIO_PRIME_SLAVE_CLOCKS); 557 clock_zeros(master, FSI_GPIO_PRIME_SLAVE_CLOCKS);
@@ -536,11 +580,21 @@ static int send_request(struct fsi_master_gpio *master,
536static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave, 580static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave,
537 struct fsi_gpio_msg *cmd, size_t resp_len, void *resp) 581 struct fsi_gpio_msg *cmd, size_t resp_len, void *resp)
538{ 582{
539 int rc; 583 int rc = -EAGAIN, retries = 0;
540 584
541 rc = send_request(master, cmd); 585 while ((retries++) < FSI_CRC_ERR_RETRIES) {
542 if (!rc) 586 rc = send_request(master, cmd);
587 if (rc)
588 break;
543 rc = poll_for_response(master, slave, resp_len, resp); 589 rc = poll_for_response(master, slave, resp_len, resp);
590 if (rc != -EAGAIN)
591 break;
592 rc = -EIO;
593 dev_warn(master->dev, "ECRC retry %d\n", retries);
594
595 /* Pace it a bit before retry */
596 msleep(1);
597 }
544 598
545 return rc; 599 return rc;
546} 600}
diff --git a/include/trace/events/fsi_master_gpio.h b/include/trace/events/fsi_master_gpio.h
index 33e928c5acf3..389082132433 100644
--- a/include/trace/events/fsi_master_gpio.h
+++ b/include/trace/events/fsi_master_gpio.h
@@ -64,6 +64,33 @@ TRACE_EVENT(fsi_master_gpio_break,
64 ) 64 )
65); 65);
66 66
67TRACE_EVENT(fsi_master_gpio_crc_cmd_error,
68 TP_PROTO(const struct fsi_master_gpio *master),
69 TP_ARGS(master),
70 TP_STRUCT__entry(
71 __field(int, master_idx)
72 ),
73 TP_fast_assign(
74 __entry->master_idx = master->master.idx;
75 ),
76 TP_printk("fsi-gpio%d ----CRC command retry---",
77 __entry->master_idx
78 )
79);
80
81TRACE_EVENT(fsi_master_gpio_crc_rsp_error,
82 TP_PROTO(const struct fsi_master_gpio *master),
83 TP_ARGS(master),
84 TP_STRUCT__entry(
85 __field(int, master_idx)
86 ),
87 TP_fast_assign(
88 __entry->master_idx = master->master.idx;
89 ),
90 TP_printk("fsi-gpio%d ----CRC response---",
91 __entry->master_idx
92 )
93);
67 94
68TRACE_EVENT(fsi_master_gpio_poll_response_busy, 95TRACE_EVENT(fsi_master_gpio_poll_response_busy,
69 TP_PROTO(const struct fsi_master_gpio *master, int busy), 96 TP_PROTO(const struct fsi_master_gpio *master, int busy),