static int fme_mgr_write()

in dfl-fme-mgr.c [165:218]


static int fme_mgr_write(struct fpga_manager *mgr,
			 const char *buf, size_t count)
{
	struct device *dev = &mgr->dev;
	struct fme_mgr_priv *priv = mgr->priv;
	void __iomem *fme_pr = priv->ioaddr;
	u64 pr_ctrl, pr_status, pr_data;
	int delay = 0, pr_credit, i = 0;

	dev_dbg(dev, "start request\n");

	pr_ctrl = readq(fme_pr + FME_PR_CTRL);
	pr_ctrl |= FME_PR_CTRL_PR_START;
	writeq(pr_ctrl, fme_pr + FME_PR_CTRL);

	dev_dbg(dev, "pushing data from bitstream to HW\n");

	/*
	 * driver can push data to PR hardware using PR_DATA register once HW
	 * has enough pr_credit (> 1), pr_credit reduces one for every 32bit
	 * pr data write to PR_DATA register. If pr_credit <= 1, driver needs
	 * to wait for enough pr_credit from hardware by polling.
	 */
	pr_status = readq(fme_pr + FME_PR_STS);
	pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);

	while (count > 0) {
		while (pr_credit <= 1) {
			if (delay++ > PR_WAIT_TIMEOUT) {
				dev_err(dev, "PR_CREDIT timeout\n");
				return -ETIMEDOUT;
			}
			udelay(1);

			pr_status = readq(fme_pr + FME_PR_STS);
			pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);
		}

		if (count < 4) {
			dev_err(dev, "Invalid PR bitstream size\n");
			return -EINVAL;
		}

		pr_data = 0;
		pr_data |= FIELD_PREP(FME_PR_DATA_PR_DATA_RAW,
				      *(((u32 *)buf) + i));
		writeq(pr_data, fme_pr + FME_PR_DATA);
		count -= 4;
		pr_credit--;
		i++;
	}

	return 0;
}