Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OCC: FSI and hwmon: Add sequence numbering

Sequence numbering of the commands submitted to the OCC is required by
the OCC interface specification. Add sequence numbering and check for
the correct sequence number on the response.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Lei YU <mine260309@gmail.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>

authored by

Eddie James and committed by
Joel Stanley
afd26118 60c87bc5

+15 -5
+12 -3
drivers/fsi/fsi-occ.c
··· 412 412 msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS); 413 413 struct occ *occ = dev_get_drvdata(dev); 414 414 struct occ_response *resp = response; 415 + u8 seq_no; 415 416 u16 resp_data_length; 416 417 unsigned long start; 417 418 int rc; ··· 427 426 428 427 mutex_lock(&occ->occ_lock); 429 428 429 + /* Extract the seq_no from the command (first byte) */ 430 + seq_no = *(const u8 *)request; 430 431 rc = occ_putsram(occ, OCC_SRAM_CMD_ADDR, request, req_len); 431 432 if (rc) 432 433 goto done; ··· 444 441 if (rc) 445 442 goto done; 446 443 447 - if (resp->return_status == OCC_RESP_CMD_IN_PRG) { 444 + if (resp->return_status == OCC_RESP_CMD_IN_PRG || 445 + resp->seq_no != seq_no) { 448 446 rc = -ETIMEDOUT; 449 447 450 - if (time_after(jiffies, start + timeout)) 451 - break; 448 + if (time_after(jiffies, start + timeout)) { 449 + dev_err(occ->dev, "resp timeout status=%02x " 450 + "resp seq_no=%d our seq_no=%d\n", 451 + resp->return_status, resp->seq_no, 452 + seq_no); 453 + goto done; 454 + } 452 455 453 456 set_current_state(TASK_UNINTERRUPTIBLE); 454 457 schedule_timeout(wait_time);
+2 -2
drivers/hwmon/occ/common.c
··· 124 124 static int occ_poll(struct occ *occ) 125 125 { 126 126 int rc; 127 - u16 checksum = occ->poll_cmd_data + 1; 127 + u16 checksum = occ->poll_cmd_data + occ->seq_no + 1; 128 128 u8 cmd[8]; 129 129 struct occ_poll_response_header *header; 130 130 131 131 /* big endian */ 132 - cmd[0] = 0; /* sequence number */ 132 + cmd[0] = occ->seq_no++; /* sequence number */ 133 133 cmd[1] = 0; /* cmd type */ 134 134 cmd[2] = 0; /* data length msb */ 135 135 cmd[3] = 1; /* data length lsb */
+1
drivers/hwmon/occ/common.h
··· 95 95 struct occ_sensors sensors; 96 96 97 97 int powr_sample_time_us; /* average power sample time */ 98 + u8 seq_no; 98 99 u8 poll_cmd_data; /* to perform OCC poll command */ 99 100 int (*send_cmd)(struct occ *occ, u8 *cmd); 100 101