static void xgene_edac_rb_report()

in xgene_edac.c [1463:1570]


static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev)
{
	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
	u32 err_addr_lo;
	u32 err_addr_hi;
	u32 reg;

	/* If the register bus resource isn't available, just skip it */
	if (!ctx->edac->rb_map)
		goto rb_skip;

	/*
	 * Check RB access errors
	 * 1. Out of range
	 * 2. Un-implemented page
	 * 3. Un-aligned access
	 * 4. Offline slave IP
	 */
	if (regmap_read(ctx->edac->rb_map, RBCSR, &reg))
		return;
	if (reg & STICKYERR_MASK) {
		bool write;

		dev_err(edac_dev->dev, "IOB bus access error(s)\n");
		if (regmap_read(ctx->edac->rb_map, RBEIR, &reg))
			return;
		write = reg & WRITE_ACCESS_MASK ? 1 : 0;
		if (reg & AGENT_OFFLINE_ERR_MASK)
			dev_err(edac_dev->dev,
				"IOB bus %s access to offline agent error\n",
				write ? "write" : "read");
		if (reg & UNIMPL_RBPAGE_ERR_MASK)
			dev_err(edac_dev->dev,
				"IOB bus %s access to unimplemented page error\n",
				write ? "write" : "read");
		if (reg & WORD_ALIGNED_ERR_MASK)
			dev_err(edac_dev->dev,
				"IOB bus %s word aligned access error\n",
				write ? "write" : "read");
		if (reg & PAGE_ACCESS_ERR_MASK)
			dev_err(edac_dev->dev,
				"IOB bus %s to page out of range access error\n",
				write ? "write" : "read");
		if (regmap_write(ctx->edac->rb_map, RBEIR, 0))
			return;
		if (regmap_write(ctx->edac->rb_map, RBCSR, 0))
			return;
	}
rb_skip:

	/* IOB Bridge agent transaction error interrupt */
	reg = readl(ctx->dev_csr + IOBBATRANSERRINTSTS);
	if (!reg)
		return;

	dev_err(edac_dev->dev, "IOB bridge agent (BA) transaction error\n");
	if (reg & WRERR_RESP_MASK)
		dev_err(edac_dev->dev, "IOB BA write response error\n");
	if (reg & M_WRERR_RESP_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA write response error\n");
	if (reg & XGIC_POISONED_REQ_MASK)
		dev_err(edac_dev->dev, "IOB BA XGIC poisoned write error\n");
	if (reg & M_XGIC_POISONED_REQ_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA XGIC poisoned write error\n");
	if (reg & RBM_POISONED_REQ_MASK)
		dev_err(edac_dev->dev, "IOB BA RBM poisoned write error\n");
	if (reg & M_RBM_POISONED_REQ_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA RBM poisoned write error\n");
	if (reg & WDATA_CORRUPT_MASK)
		dev_err(edac_dev->dev, "IOB BA write error\n");
	if (reg & M_WDATA_CORRUPT_MASK)
		dev_err(edac_dev->dev, "Multiple IOB BA write error\n");
	if (reg & TRANS_CORRUPT_MASK)
		dev_err(edac_dev->dev, "IOB BA transaction error\n");
	if (reg & M_TRANS_CORRUPT_MASK)
		dev_err(edac_dev->dev, "Multiple IOB BA transaction error\n");
	if (reg & RIDRAM_CORRUPT_MASK)
		dev_err(edac_dev->dev,
			"IOB BA RDIDRAM read transaction ID error\n");
	if (reg & M_RIDRAM_CORRUPT_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA RDIDRAM read transaction ID error\n");
	if (reg & WIDRAM_CORRUPT_MASK)
		dev_err(edac_dev->dev,
			"IOB BA RDIDRAM write transaction ID error\n");
	if (reg & M_WIDRAM_CORRUPT_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA RDIDRAM write transaction ID error\n");
	if (reg & ILLEGAL_ACCESS_MASK)
		dev_err(edac_dev->dev,
			"IOB BA XGIC/RB illegal access error\n");
	if (reg & M_ILLEGAL_ACCESS_MASK)
		dev_err(edac_dev->dev,
			"Multiple IOB BA XGIC/RB illegal access error\n");

	err_addr_lo = readl(ctx->dev_csr + IOBBATRANSERRREQINFOL);
	err_addr_hi = readl(ctx->dev_csr + IOBBATRANSERRREQINFOH);
	dev_err(edac_dev->dev, "IOB BA %s access at 0x%02X.%08X (0x%08X)\n",
		REQTYPE_F2_RD(err_addr_hi) ? "read" : "write",
		ERRADDRH_F2_RD(err_addr_hi), err_addr_lo, err_addr_hi);
	if (reg & WRERR_RESP_MASK)
		dev_err(edac_dev->dev, "IOB BA requestor ID 0x%08X\n",
			readl(ctx->dev_csr + IOBBATRANSERRCSWREQID));
	writel(reg, ctx->dev_csr + IOBBATRANSERRINTSTS);
}