All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: openbmc@lists.ozlabs.org
Subject: [PATCH linux dev-4.13 08/10] fsi/fsi-occ: Simple conversion to new sbefifo driver
Date: Thu, 24 May 2018 15:14:27 +1000	[thread overview]
Message-ID: <20180524051429.4638-8-benh@kernel.crashing.org> (raw)
In-Reply-To: <20180524051429.4638-1-benh@kernel.crashing.org>

Replace open/close/write/read API with the simple submit()
API and the helper to parse status.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 drivers/fsi/Makefile       |   2 +-
 drivers/fsi/fsi-occ.c      | 209 +++++++++++++++++--------------------
 drivers/hwmon/occ/Makefile |   2 +-
 3 files changed, 99 insertions(+), 114 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..3f96d7ddea91 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,72 @@ 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(SBEFIFO_CMD_GET_OCC_SRAM);
+	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(sbefifo, SBEFIFO_CMD_GET_OCC_SRAM,
+				  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 %zd\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,72 +527,88 @@ 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[1] = cpu_to_be32(0xa404);
+	buf[0] = cpu_to_be32(cmd_len);
+	buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM);
 	buf[2] = cpu_to_be32(1);
 	buf[3] = cpu_to_be32(address);
 	buf[4] = cpu_to_be32(data_len);
 
 	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(sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM,
+				  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: %zd\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 %zd\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 */
+	buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM);
 	buf[2] = cpu_to_be32(0x3);              /* Mode: Circular */
 	buf[3] = cpu_to_be32(0x0);              /* Address: ignored in mode 3 */
 	buf[4] = cpu_to_be32(0x8);              /* Data length in bytes */
 	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(sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM,
+				  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: %zd\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 %zd\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

  parent reply	other threads:[~2018-05-24  5:15 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-24  5:14 [PATCH linux dev-4.13 01/10] fsi/gpio: Include command build in locked section Benjamin Herrenschmidt
2018-05-24  5:14 ` [PATCH linux dev-4.13 02/10] fsi/gpio: Use relative-addressing commands Benjamin Herrenschmidt
2018-05-24 14:34   ` Christopher Bostic
2018-05-24  5:14 ` [PATCH linux dev-4.13 03/10] fsi/fsi-master-gpio: Implement CRC error recovery Benjamin Herrenschmidt
2018-05-24 15:05   ` Christopher Bostic
2018-05-24  5:14 ` [PATCH linux dev-4.13 04/10] fsi/fsi-master-gpio: More error handling cleanup Benjamin Herrenschmidt
2018-05-24 18:50   ` Christopher Bostic
2018-05-24  5:14 ` [PATCH linux dev-4.13 05/10] fsi/master-gpio: Replace bit_bit lock with IRQ disable/enable Benjamin Herrenschmidt
2018-05-24  5:14 ` [PATCH linux dev-4.13 06/10] fsi: Remove old sbefifo driver Benjamin Herrenschmidt
2018-05-24  5:14 ` [PATCH linux dev-4.13 07/10] fsi/sbefifo: Add driver for the SBE FIFO Benjamin Herrenschmidt
2018-05-24  5:14 ` Benjamin Herrenschmidt [this message]
2018-05-24  5:14 ` [PATCH linux dev-4.13 09/10] fsi/occ: Don't set driver data late Benjamin Herrenschmidt
2018-05-24  5:14 ` [PATCH linux dev-4.13 10/10] hwmon/occ: Silence probe error message when host is shutdown Benjamin Herrenschmidt
2018-05-24 13:40 ` [PATCH linux dev-4.13 01/10] fsi/gpio: Include command build in locked section Christopher Bostic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180524051429.4638-8-benh@kernel.crashing.org \
    --to=benh@kernel.crashing.org \
    --cc=openbmc@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.