Commit afd26118 authored by Eddie James's avatar Eddie James Committed by Joel Stanley

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: default avatarEddie James <eajames@linux.ibm.com>
Acked-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reviewed-by: default avatarLei YU <mine260309@gmail.com>
Signed-off-by: default avatarJoel Stanley <joel@jms.id.au>
parent 60c87bc5
...@@ -412,6 +412,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, ...@@ -412,6 +412,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS); msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS);
struct occ *occ = dev_get_drvdata(dev); struct occ *occ = dev_get_drvdata(dev);
struct occ_response *resp = response; struct occ_response *resp = response;
u8 seq_no;
u16 resp_data_length; u16 resp_data_length;
unsigned long start; unsigned long start;
int rc; int rc;
...@@ -426,6 +427,8 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, ...@@ -426,6 +427,8 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
mutex_lock(&occ->occ_lock); mutex_lock(&occ->occ_lock);
/* Extract the seq_no from the command (first byte) */
seq_no = *(const u8 *)request;
rc = occ_putsram(occ, OCC_SRAM_CMD_ADDR, request, req_len); rc = occ_putsram(occ, OCC_SRAM_CMD_ADDR, request, req_len);
if (rc) if (rc)
goto done; goto done;
...@@ -441,11 +444,17 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, ...@@ -441,11 +444,17 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
if (rc) if (rc)
goto done; goto done;
if (resp->return_status == OCC_RESP_CMD_IN_PRG) { if (resp->return_status == OCC_RESP_CMD_IN_PRG ||
resp->seq_no != seq_no) {
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
if (time_after(jiffies, start + timeout)) if (time_after(jiffies, start + timeout)) {
break; dev_err(occ->dev, "resp timeout status=%02x "
"resp seq_no=%d our seq_no=%d\n",
resp->return_status, resp->seq_no,
seq_no);
goto done;
}
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(wait_time); schedule_timeout(wait_time);
......
...@@ -124,12 +124,12 @@ struct extended_sensor { ...@@ -124,12 +124,12 @@ struct extended_sensor {
static int occ_poll(struct occ *occ) static int occ_poll(struct occ *occ)
{ {
int rc; int rc;
u16 checksum = occ->poll_cmd_data + 1; u16 checksum = occ->poll_cmd_data + occ->seq_no + 1;
u8 cmd[8]; u8 cmd[8];
struct occ_poll_response_header *header; struct occ_poll_response_header *header;
/* big endian */ /* big endian */
cmd[0] = 0; /* sequence number */ cmd[0] = occ->seq_no++; /* sequence number */
cmd[1] = 0; /* cmd type */ cmd[1] = 0; /* cmd type */
cmd[2] = 0; /* data length msb */ cmd[2] = 0; /* data length msb */
cmd[3] = 1; /* data length lsb */ cmd[3] = 1; /* data length lsb */
......
...@@ -95,6 +95,7 @@ struct occ { ...@@ -95,6 +95,7 @@ struct occ {
struct occ_sensors sensors; struct occ_sensors sensors;
int powr_sample_time_us; /* average power sample time */ int powr_sample_time_us; /* average power sample time */
u8 seq_no;
u8 poll_cmd_data; /* to perform OCC poll command */ u8 poll_cmd_data; /* to perform OCC poll command */
int (*send_cmd)(struct occ *occ, u8 *cmd); int (*send_cmd)(struct occ *occ, u8 *cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment