[PATCH v3 linux dev-4.13 3/3] fsi/fsi-occ: Simple conversion to new sbefifo driver
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri May 18 11:34:29 AEST 2018
Replace open/close/write/read API with the simple submit()
API and the helper to parse status.
This doesn't yet extract FFDC
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
drivers/fsi/Makefile | 2 +-
drivers/fsi/fsi-occ.c | 202 +++++++++++++++++--------------------
drivers/hwmon/occ/Makefile | 2 +-
3 files changed, 94 insertions(+), 112 deletions(-)
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index f331e929423c..75fdc6d8cfc4 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_FSI_MASTER_HUB) += fsi-master-hub.o
obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
obj-$(CONFIG_FSI_SCOM) += fsi-scom.o
obj-$(CONFIG_FSI_SBEFIFO) += fsi-sbefifo.o
-#obj-$(CONFIG_FSI_OCC) += fsi-occ.o
+obj-$(CONFIG_FSI_OCC) += fsi-occ.o
diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
index d368b62e5471..bdee26096688 100644
--- a/drivers/fsi/fsi-occ.c
+++ b/drivers/fsi/fsi-occ.c
@@ -36,6 +36,13 @@
#define OCC_CMD_DATA_BYTES 4090
#define OCC_RESP_DATA_BYTES 4089
+/*
+ * Assume we don't have FFDC, if we do we'll overflow and
+ * fail the command. This needs to be big enough for simple
+ * commands as well.
+ */
+#define OCC_SBE_STATUS_WORDS 16
+
#define OCC_TIMEOUT_MS 1000
#define OCC_CMD_IN_PRG_WAIT_MS 50
@@ -447,110 +454,71 @@ static int occ_verify_checksum(struct occ_response *resp, u16 data_length)
return 0;
}
-static int occ_write_sbefifo(struct sbefifo_client *client, const char *buf,
- ssize_t len)
-{
- int rc;
- ssize_t total = 0;
-
- do {
- rc = sbefifo_drv_write(client, &buf[total], len - total);
- if (rc < 0)
- return rc;
- else if (!rc)
- break;
-
- total += rc;
- } while (total < len);
-
- return (total == len) ? 0 : -ENOSPC;
-}
-
-static int occ_read_sbefifo(struct sbefifo_client *client, char *buf,
- ssize_t len)
-{
- int rc;
- ssize_t total = 0;
-
- do {
- rc = sbefifo_drv_read(client, &buf[total], len - total);
- if (rc < 0)
- return rc;
- else if (!rc)
- break;
-
- total += rc;
- } while (total < len);
-
- return (total == len) ? 0 : -ENODATA;
-}
-
static int occ_getsram(struct device *sbefifo, u32 address, u8 *data,
ssize_t len)
{
- int rc;
- u8 *resp;
- __be32 buf[5];
u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */
- struct sbefifo_client *client;
+ size_t resp_len, resp_data_len;
+ __be32 *resp, cmd[5];
+ int rc;
/*
* Magic sequence to do SBE getsram command. SBE will fetch data from
* specified SRAM address.
*/
- buf[0] = cpu_to_be32(0x5);
- buf[1] = cpu_to_be32(0xa403);
- buf[2] = cpu_to_be32(1);
- buf[3] = cpu_to_be32(address);
- buf[4] = cpu_to_be32(data_len);
-
- client = sbefifo_drv_open(sbefifo, 0);
- if (!client)
- return -ENODEV;
-
- rc = occ_write_sbefifo(client, (const char *)buf, sizeof(buf));
- if (rc)
- goto done;
-
- resp = kzalloc(data_len, GFP_KERNEL);
- if (!resp) {
- rc = -ENOMEM;
- goto done;
- }
+ cmd[0] = cpu_to_be32(0x5);
+ cmd[1] = cpu_to_be32(0xa403);
+ cmd[2] = cpu_to_be32(1);
+ cmd[3] = cpu_to_be32(address);
+ cmd[4] = cpu_to_be32(data_len);
+
+ resp_len = (data_len >> 2) + OCC_SBE_STATUS_WORDS;
+ resp = kzalloc(resp_len << 2 , GFP_KERNEL);
+ if (!resp)
+ return -ENOMEM;
- rc = occ_read_sbefifo(client, (char *)resp, data_len);
+ rc = sbefifo_submit(sbefifo, cmd, 5, resp, &resp_len);
if (rc)
goto free;
-
- /* check for good response */
- rc = occ_read_sbefifo(client, (char *)buf, 8);
+ rc = sbefifo_parse_status(0xa403, resp, resp_len, &resp_len);
if (rc)
goto free;
- if ((be32_to_cpu(buf[0]) == data_len) &&
- (be32_to_cpu(buf[1]) == 0xC0DEA403))
- memcpy(data, resp, len);
- else
+ resp_data_len = be32_to_cpu(resp[resp_len - 1]);
+ if (resp_data_len != data_len) {
+ pr_err("occ: SRAM read expected %d bytes got %d\n",
+ data_len, resp_data_len);
rc = -EBADMSG;
+ } else {
+ memcpy(data, resp, len);
+ }
free:
+ /* Convert positive SBEI status */
+ if (rc > 0) {
+ pr_err("occ: SRAM read returned failure status: %08x\n", rc);
+ rc = -EBADMSG;
+ }
kfree(resp);
-
-done:
- sbefifo_drv_release(client);
return rc;
}
static int occ_putsram(struct device *sbefifo, u32 address, u8 *data,
ssize_t len)
{
- int rc;
- __be32 *buf;
+ size_t cmd_len, buf_len, resp_len, resp_data_len;
u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */
- size_t cmd_len = data_len + 20;
- struct sbefifo_client *client;
+ __be32 *buf;
+ int rc;
- buf = kzalloc(cmd_len, GFP_KERNEL);
+ /*
+ * We use the same buffer for command and response, make
+ * sure it's big enough
+ */
+ resp_len = OCC_SBE_STATUS_WORDS;
+ cmd_len = (data_len >> 2) + 5;
+ buf_len = max(cmd_len, resp_len);
+ buf = kzalloc(buf_len << 2, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -558,7 +526,7 @@ static int occ_putsram(struct device *sbefifo, u32 address, u8 *data,
* Magic sequence to do SBE putsram command. SBE will transfer
* data to specified SRAM address.
*/
- buf[0] = cpu_to_be32(0x5 + (data_len / 4));
+ buf[0] = cpu_to_be32(cmd_len);
buf[1] = cpu_to_be32(0xa404);
buf[2] = cpu_to_be32(1);
buf[3] = cpu_to_be32(address);
@@ -566,37 +534,43 @@ static int occ_putsram(struct device *sbefifo, u32 address, u8 *data,
memcpy(&buf[5], data, len);
- client = sbefifo_drv_open(sbefifo, 0);
- if (!client) {
- rc = -ENODEV;
- goto free;
- }
-
- rc = occ_write_sbefifo(client, (const char *)buf, cmd_len);
+ rc = sbefifo_submit(sbefifo, buf, cmd_len, buf, &resp_len);
if (rc)
- goto done;
-
- rc = occ_read_sbefifo(client, (char *)buf, 8);
+ goto free;
+ rc = sbefifo_parse_status(0xa404, buf, resp_len, &resp_len);
if (rc)
- goto done;
+ goto free;
- /* check for good response */
- if ((be32_to_cpu(buf[0]) != data_len) ||
- (be32_to_cpu(buf[1]) != 0xC0DEA404))
+ if (resp_len != 1) {
+ pr_err("occ: SRAM write response lenght invalid: %d\n",
+ resp_len);
rc = -EBADMSG;
-
-done:
- sbefifo_drv_release(client);
+ } else {
+ resp_data_len = be32_to_cpu(buf[0]);
+ if (resp_data_len != data_len) {
+ pr_err("occ: SRAM write expected %d bytes got %d\n",
+ data_len, resp_data_len);
+ rc = -EBADMSG;
+ }
+ }
free:
+ /* Convert positive SBEI status */
+ if (rc > 0) {
+ pr_err("occ: SRAM write returned failure status: %08x\n", rc);
+ rc = -EBADMSG;
+ }
kfree(buf);
return rc;
}
static int occ_trigger_attn(struct device *sbefifo)
{
+ __be32 buf[OCC_SBE_STATUS_WORDS];
+ size_t resp_len, resp_data_len;
int rc;
- __be32 buf[7];
- struct sbefifo_client *client;
+
+ BUILD_BUG_ON(OCC_SBE_STATUS_WORDS < 7);
+ resp_len = OCC_SBE_STATUS_WORDS;
buf[0] = cpu_to_be32(0x5 + 0x2); /* Chip-op length in words */
buf[1] = cpu_to_be32(0xa404); /* PutOCCSRAM */
@@ -606,24 +580,32 @@ static int occ_trigger_attn(struct device *sbefifo)
buf[5] = cpu_to_be32(0x20010000); /* Trigger OCC attention */
buf[6] = 0;
- client = sbefifo_drv_open(sbefifo, 0);
- if (!client)
- return -ENODEV;
-
- rc = occ_write_sbefifo(client, (const char *)buf, sizeof(buf));
+ rc = sbefifo_submit(sbefifo, buf, 7, buf, &resp_len);
if (rc)
- goto done;
-
- rc = occ_read_sbefifo(client, (char *)buf, 8);
+ goto error;
+ rc = sbefifo_parse_status(0xa404, buf, resp_len, &resp_len);
if (rc)
- goto done;
+ goto error;
- /* check for good response */
- if ((be32_to_cpu(buf[0]) != 8) || (be32_to_cpu(buf[1]) != 0xC0DEA404))
+ if (resp_len != 1) {
+ pr_err("occ: SRAM attn response lenght invalid: %d\n",
+ resp_len);
rc = -EBADMSG;
+ } else {
+ resp_data_len = be32_to_cpu(buf[0]);
+ if (resp_data_len != 8) {
+ pr_err("occ: SRAM attn expected 8 bytes got %d\n",
+ resp_data_len);
+ rc = -EBADMSG;
+ }
+ }
+ error:
+ /* Convert positive SBEI status */
+ if (rc > 0) {
+ pr_err("occ: SRAM attn returned failure status: %08x\n", rc);
+ rc = -EBADMSG;
+ }
-done:
- sbefifo_drv_release(client);
return rc;
}
diff --git a/drivers/hwmon/occ/Makefile b/drivers/hwmon/occ/Makefile
index ca6d25ae9da8..ab5c3e965ccb 100644
--- a/drivers/hwmon/occ/Makefile
+++ b/drivers/hwmon/occ/Makefile
@@ -1,7 +1,7 @@
occ-hwmon-objs := common.o
ifeq ($(CONFIG_SENSORS_OCC_P9_SBE), y)
-#occ-hwmon-objs += p9_sbe.o
+occ-hwmon-objs += p9_sbe.o
endif
ifeq ($(CONFIG_SENSORS_OCC_P8_I2C), y)
--
2.17.0
More information about the openbmc
mailing list