static int fme_mgr_write_init()

in dfl-fme-mgr.c [107:163]


static int fme_mgr_write_init(struct fpga_manager *mgr,
			      struct fpga_image_info *info,
			      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;

	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
		dev_err(dev, "only supports partial reconfiguration.\n");
		return -EINVAL;
	}

	dev_dbg(dev, "resetting PR before initiated PR\n");

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

	if (readq_poll_timeout(fme_pr + FME_PR_CTRL, pr_ctrl,
			       pr_ctrl & FME_PR_CTRL_PR_RSTACK, 1,
			       PR_WAIT_TIMEOUT)) {
		dev_err(dev, "PR Reset ACK timeout\n");
		return -ETIMEDOUT;
	}

	pr_ctrl = readq(fme_pr + FME_PR_CTRL);
	pr_ctrl &= ~FME_PR_CTRL_PR_RST;
	writeq(pr_ctrl, fme_pr + FME_PR_CTRL);

	dev_dbg(dev,
		"waiting for PR resource in HW to be initialized and ready\n");

	if (readq_poll_timeout(fme_pr + FME_PR_STS, pr_status,
			       (pr_status & FME_PR_STS_PR_STS) ==
			       FME_PR_STS_PR_STS_IDLE, 1, PR_WAIT_TIMEOUT)) {
		dev_err(dev, "PR Status timeout\n");
		priv->pr_error = fme_mgr_pr_error_handle(fme_pr);
		return -ETIMEDOUT;
	}

	dev_dbg(dev, "check and clear previous PR error\n");
	priv->pr_error = fme_mgr_pr_error_handle(fme_pr);
	if (priv->pr_error)
		dev_dbg(dev, "previous PR error detected %llx\n",
			(unsigned long long)priv->pr_error);

	dev_dbg(dev, "set PR port ID\n");

	pr_ctrl = readq(fme_pr + FME_PR_CTRL);
	pr_ctrl &= ~FME_PR_CTRL_PR_RGN_ID;
	pr_ctrl |= FIELD_PREP(FME_PR_CTRL_PR_RGN_ID, info->region_id);
	writeq(pr_ctrl, fme_pr + FME_PR_CTRL);

	return 0;
}