static int sbefifo_send_command()

in fsi-sbefifo.c [487:538]


static int sbefifo_send_command(struct sbefifo *sbefifo,
				const __be32 *command, size_t cmd_len)
{
	struct device *dev = &sbefifo->fsi_dev->dev;
	size_t len, chunk, vacant = 0, remaining = cmd_len;
	unsigned long timeout;
	u32 status;
	int rc;

	dev_vdbg(dev, "sending command (%zd words, cmd=%04x)\n",
		 cmd_len, be32_to_cpu(command[1]));

	/* As long as there's something to send */
	timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_START_CMD);
	while (remaining) {
		/* Wait for room in the FIFO */
		rc = sbefifo_wait(sbefifo, true, &status, timeout);
		if (rc < 0)
			return rc;
		timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_IN_CMD);

		vacant = sbefifo_vacant(status);
		len = chunk = min(vacant, remaining);

		dev_vdbg(dev, "  status=%08x vacant=%zd chunk=%zd\n",
			 status, vacant, chunk);

		/* Write as much as we can */
		while (len--) {
			rc = sbefifo_up_write(sbefifo, *(command++));
			if (rc) {
				dev_err(dev, "FSI error %d writing UP FIFO\n", rc);
				return rc;
			}
		}
		remaining -= chunk;
		vacant -= chunk;
	}

	/* If there's no room left, wait for some to write EOT */
	if (!vacant) {
		rc = sbefifo_wait(sbefifo, true, &status, timeout);
		if (rc)
			return rc;
	}

	/* Send an EOT */
	rc = sbefifo_regw(sbefifo, SBEFIFO_UP | SBEFIFO_EOT_RAISE, 0);
	if (rc)
		dev_err(dev, "FSI error %d writing EOT\n", rc);
	return rc;
}