/*
 * Copyright 2018 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 *
 */
#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/reboot.h>
#include <linux/syscalls.h>
#include <linux/pm_runtime.h>
#include <linux/list_sort.h>

#include "amdgpu.h"
#include "amdgpu_ras.h"
#include "amdgpu_atomfirmware.h"
#include "amdgpu_xgmi.h"
#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
#include "nbio_v4_3.h"
#include "nbif_v6_3_1.h"
#include "nbio_v7_9.h"
#include "atom.h"
#include "amdgpu_reset.h"
#include "amdgpu_psp.h"

#ifdef CONFIG_X86_MCE_AMD
#include <asm/mce.h>

static bool notifier_registered;
#endif
static const char *RAS_FS_NAME = "ras";

const char *ras_error_string[] = {
	"none",
	"parity",
	"single_correctable",
	"multi_uncorrectable",
	"poison",
};

const char *ras_block_string[] = {
	"umc",
	"sdma",
	"gfx",
	"mmhub",
	"athub",
	"pcie_bif",
	"hdp",
	"xgmi_wafl",
	"df",
	"smn",
	"sem",
	"mp0",
	"mp1",
	"fuse",
	"mca",
	"vcn",
	"jpeg",
	"ih",
	"mpio",
	"mmsch",
};

const char *ras_mca_block_string[] = {
	"mca_mp0",
	"mca_mp1",
	"mca_mpio",
	"mca_iohc",
};

struct amdgpu_ras_block_list {
	/* ras block link */
	struct list_head node;

	struct amdgpu_ras_block_object *ras_obj;
};

const char *get_ras_block_str(struct ras_common_if *ras_block)
{
	if (!ras_block)
		return "NULL";

	if (ras_block->block >= AMDGPU_RAS_BLOCK_COUNT ||
	    ras_block->block >= ARRAY_SIZE(ras_block_string))
		return "OUT OF RANGE";

	if (ras_block->block == AMDGPU_RAS_BLOCK__MCA)
		return ras_mca_block_string[ras_block->sub_block_index];

	return ras_block_string[ras_block->block];
}

#define ras_block_str(_BLOCK_) \
	(((_BLOCK_) < ARRAY_SIZE(ras_block_string)) ? ras_block_string[_BLOCK_] : "Out Of Range")

#define ras_err_str(i) (ras_error_string[ffs(i)])

#define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)

/* inject address is 52 bits */
#define	RAS_UMC_INJECT_ADDR_LIMIT	(0x1ULL << 52)

/* typical ECC bad page rate is 1 bad page per 100MB VRAM */
#define RAS_BAD_PAGE_COVER              (100 * 1024 * 1024ULL)

#define MAX_UMC_POISON_POLLING_TIME_ASYNC  300  //ms

#define AMDGPU_RAS_RETIRE_PAGE_INTERVAL 100  //ms

#define MAX_FLUSH_RETIRE_DWORK_TIMES  100

enum amdgpu_ras_retire_page_reservation {
	AMDGPU_RAS_RETIRE_PAGE_RESERVED,
	AMDGPU_RAS_RETIRE_PAGE_PENDING,
	AMDGPU_RAS_RETIRE_PAGE_FAULT,
};

atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);

static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
				uint64_t addr);
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
				uint64_t addr);
#ifdef CONFIG_X86_MCE_AMD
static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev);
struct mce_notifier_adev_list {
	struct amdgpu_device *devs[MAX_GPU_INSTANCE];
	int num_gpu;
};
static struct mce_notifier_adev_list mce_adev_list;
#endif

void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
{
	if (adev && amdgpu_ras_get_context(adev))
		amdgpu_ras_get_context(adev)->error_query_ready = ready;
}

static bool amdgpu_ras_get_error_query_ready(struct amdgpu_device *adev)
{
	if (adev && amdgpu_ras_get_context(adev))
		return amdgpu_ras_get_context(adev)->error_query_ready;

	return false;
}

static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t address)
{
	struct ras_err_data err_data;
	struct eeprom_table_record err_rec;
	int ret;

	if ((address >= adev->gmc.mc_vram_size) ||
	    (address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
		dev_warn(adev->dev,
		         "RAS WARN: input address 0x%llx is invalid.\n",
		         address);
		return -EINVAL;
	}

	if (amdgpu_ras_check_bad_page(adev, address)) {
		dev_warn(adev->dev,
			 "RAS WARN: 0x%llx has already been marked as bad page!\n",
			 address);
		return 0;
	}

	ret = amdgpu_ras_error_data_init(&err_data);
	if (ret)
		return ret;

	memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
	err_data.err_addr = &err_rec;
	amdgpu_umc_fill_error_record(&err_data, address, address, 0, 0);

	if (amdgpu_bad_page_threshold != 0) {
		amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
					 err_data.err_addr_cnt, false);
		amdgpu_ras_save_bad_pages(adev, NULL);
	}

	amdgpu_ras_error_data_fini(&err_data);

	dev_warn(adev->dev, "WARNING: THIS IS ONLY FOR TEST PURPOSES AND WILL CORRUPT RAS EEPROM\n");
	dev_warn(adev->dev, "Clear EEPROM:\n");
	dev_warn(adev->dev, "    echo 1 > /sys/kernel/debug/dri/0/ras/ras_eeprom_reset\n");

	return 0;
}

static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf,
					size_t size, loff_t *pos)
{
	struct ras_manager *obj = (struct ras_manager *)file_inode(f)->i_private;
	struct ras_query_if info = {
		.head = obj->head,
	};
	ssize_t s;
	char val[128];

	if (amdgpu_ras_query_error_status(obj->adev, &info))
		return -EINVAL;

	/* Hardware counter will be reset automatically after the query on Vega20 and Arcturus */
	if (amdgpu_ip_version(obj->adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 2) &&
	    amdgpu_ip_version(obj->adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 4)) {
		if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
			dev_warn(obj->adev->dev, "Failed to reset error counter and error status");
	}

	s = snprintf(val, sizeof(val), "%s: %lu\n%s: %lu\n",
			"ue", info.ue_count,
			"ce", info.ce_count);
	if (*pos >= s)
		return 0;

	s -= *pos;
	s = min_t(u64, s, size);


	if (copy_to_user(buf, &val[*pos], s))
		return -EINVAL;

	*pos += s;

	return s;
}

static const struct file_operations amdgpu_ras_debugfs_ops = {
	.owner = THIS_MODULE,
	.read = amdgpu_ras_debugfs_read,
	.write = NULL,
	.llseek = default_llseek
};

static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
		*block_id = i;
		if (strcmp(name, ras_block_string[i]) == 0)
			return 0;
	}
	return -EINVAL;
}

static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
		const char __user *buf, size_t size,
		loff_t *pos, struct ras_debug_if *data)
{
	ssize_t s = min_t(u64, 64, size);
	char str[65];
	char block_name[33];
	char err[9] = "ue";
	int op = -1;
	int block_id;
	uint32_t sub_block;
	u64 address, value;
	/* default value is 0 if the mask is not set by user */
	u32 instance_mask = 0;

	if (*pos)
		return -EINVAL;
	*pos = size;

	memset(str, 0, sizeof(str));
	memset(data, 0, sizeof(*data));

	if (copy_from_user(str, buf, s))
		return -EINVAL;

	if (sscanf(str, "disable %32s", block_name) == 1)
		op = 0;
	else if (sscanf(str, "enable %32s %8s", block_name, err) == 2)
		op = 1;
	else if (sscanf(str, "inject %32s %8s", block_name, err) == 2)
		op = 2;
	else if (strstr(str, "retire_page") != NULL)
		op = 3;
	else if (str[0] && str[1] && str[2] && str[3])
		/* ascii string, but commands are not matched. */
		return -EINVAL;

	if (op != -1) {
		if (op == 3) {
			if (sscanf(str, "%*s 0x%llx", &address) != 1 &&
			    sscanf(str, "%*s %llu", &address) != 1)
				return -EINVAL;

			data->op = op;
			data->inject.address = address;

			return 0;
		}

		if (amdgpu_ras_find_block_id_by_name(block_name, &block_id))
			return -EINVAL;

		data->head.block = block_id;
		/* only ue, ce and poison errors are supported */
		if (!memcmp("ue", err, 2))
			data->head.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
		else if (!memcmp("ce", err, 2))
			data->head.type = AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE;
		else if (!memcmp("poison", err, 6))
			data->head.type = AMDGPU_RAS_ERROR__POISON;
		else
			return -EINVAL;

		data->op = op;

		if (op == 2) {
			if (sscanf(str, "%*s %*s %*s 0x%x 0x%llx 0x%llx 0x%x",
				   &sub_block, &address, &value, &instance_mask) != 4 &&
			    sscanf(str, "%*s %*s %*s %u %llu %llu %u",
				   &sub_block, &address, &value, &instance_mask) != 4 &&
				sscanf(str, "%*s %*s %*s 0x%x 0x%llx 0x%llx",
				   &sub_block, &address, &value) != 3 &&
			    sscanf(str, "%*s %*s %*s %u %llu %llu",
				   &sub_block, &address, &value) != 3)
				return -EINVAL;
			data->head.sub_block_index = sub_block;
			data->inject.address = address;
			data->inject.value = value;
			data->inject.instance_mask = instance_mask;
		}
	} else {
		if (size < sizeof(*data))
			return -EINVAL;

		if (copy_from_user(data, buf, sizeof(*data)))
			return -EINVAL;
	}

	return 0;
}

static void amdgpu_ras_instance_mask_check(struct amdgpu_device *adev,
				struct ras_debug_if *data)
{
	int num_xcc = adev->gfx.xcc_mask ? NUM_XCC(adev->gfx.xcc_mask) : 1;
	uint32_t mask, inst_mask = data->inject.instance_mask;

	/* no need to set instance mask if there is only one instance */
	if (num_xcc <= 1 && inst_mask) {
		data->inject.instance_mask = 0;
		dev_dbg(adev->dev,
			"RAS inject mask(0x%x) isn't supported and force it to 0.\n",
			inst_mask);

		return;
	}

	switch (data->head.block) {
	case AMDGPU_RAS_BLOCK__GFX:
		mask = GENMASK(num_xcc - 1, 0);
		break;
	case AMDGPU_RAS_BLOCK__SDMA:
		mask = GENMASK(adev->sdma.num_instances - 1, 0);
		break;
	case AMDGPU_RAS_BLOCK__VCN:
	case AMDGPU_RAS_BLOCK__JPEG:
		mask = GENMASK(adev->vcn.num_vcn_inst - 1, 0);
		break;
	default:
		mask = inst_mask;
		break;
	}

	/* remove invalid bits in instance mask */
	data->inject.instance_mask &= mask;
	if (inst_mask != data->inject.instance_mask)
		dev_dbg(adev->dev,
			"Adjust RAS inject mask 0x%x to 0x%x\n",
			inst_mask, data->inject.instance_mask);
}

/**
 * DOC: AMDGPU RAS debugfs control interface
 *
 * The control interface accepts struct ras_debug_if which has two members.
 *
 * First member: ras_debug_if::head or ras_debug_if::inject.
 *
 * head is used to indicate which IP block will be under control.
 *
 * head has four members, they are block, type, sub_block_index, name.
 * block: which IP will be under control.
 * type: what kind of error will be enabled/disabled/injected.
 * sub_block_index: some IPs have subcomponets. say, GFX, sDMA.
 * name: the name of IP.
 *
 * inject has three more members than head, they are address, value and mask.
 * As their names indicate, inject operation will write the
 * value to the address.
 *
 * The second member: struct ras_debug_if::op.
 * It has three kinds of operations.
 *
 * - 0: disable RAS on the block. Take ::head as its data.
 * - 1: enable RAS on the block. Take ::head as its data.
 * - 2: inject errors on the block. Take ::inject as its data.
 *
 * How to use the interface?
 *
 * In a program
 *
 * Copy the struct ras_debug_if in your code and initialize it.
 * Write the struct to the control interface.
 *
 * From shell
 *
 * .. code-block:: bash
 *
 *	echo "disable <block>" > /sys/kernel/debug/dri/<N>/ras/ras_ctrl
 *	echo "enable  <block> <error>" > /sys/kernel/debug/dri/<N>/ras/ras_ctrl
 *	echo "inject  <block> <error> <sub-block> <address> <value> <mask>" > /sys/kernel/debug/dri/<N>/ras/ras_ctrl
 *
 * Where N, is the card which you want to affect.
 *
 * "disable" requires only the block.
 * "enable" requires the block and error type.
 * "inject" requires the block, error type, address, and value.
 *
 * The block is one of: umc, sdma, gfx, etc.
 *	see ras_block_string[] for details
 *
 * The error type is one of: ue, ce and poison where,
 *	ue is multi-uncorrectable
 *	ce is single-correctable
 *	poison is poison
 *
 * The sub-block is a the sub-block index, pass 0 if there is no sub-block.
 * The address and value are hexadecimal numbers, leading 0x is optional.
 * The mask means instance mask, is optional, default value is 0x1.
 *
 * For instance,
 *
 * .. code-block:: bash
 *
 *	echo inject umc ue 0x0 0x0 0x0 > /sys/kernel/debug/dri/0/ras/ras_ctrl
 *	echo inject umc ce 0 0 0 3 > /sys/kernel/debug/dri/0/ras/ras_ctrl
 *	echo disable umc > /sys/kernel/debug/dri/0/ras/ras_ctrl
 *
 * How to check the result of the operation?
 *
 * To check disable/enable, see "ras" features at,
 * /sys/class/drm/card[0/1/2...]/device/ras/features
 *
 * To check inject, see the corresponding error count at,
 * /sys/class/drm/card[0/1/2...]/device/ras/[gfx|sdma|umc|...]_err_count
 *
 * .. note::
 *	Operations are only allowed on blocks which are supported.
 *	Check the "ras" mask at /sys/module/amdgpu/parameters/ras_mask
 *	to see which blocks support RAS on a particular asic.
 *
 */
static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f,
					     const char __user *buf,
					     size_t size, loff_t *pos)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
	struct ras_debug_if data;
	int ret = 0;

	if (!amdgpu_ras_get_error_query_ready(adev)) {
		dev_warn(adev->dev, "RAS WARN: error injection "
				"currently inaccessible\n");
		return size;
	}

	ret = amdgpu_ras_debugfs_ctrl_parse_data(f, buf, size, pos, &data);
	if (ret)
		return ret;

	if (data.op == 3) {
		ret = amdgpu_reserve_page_direct(adev, data.inject.address);
		if (!ret)
			return size;
		else
			return ret;
	}

	if (!amdgpu_ras_is_supported(adev, data.head.block))
		return -EINVAL;

	switch (data.op) {
	case 0:
		ret = amdgpu_ras_feature_enable(adev, &data.head, 0);
		break;
	case 1:
		ret = amdgpu_ras_feature_enable(adev, &data.head, 1);
		break;
	case 2:
		if ((data.inject.address >= adev->gmc.mc_vram_size &&
		    adev->gmc.mc_vram_size) ||
		    (data.inject.address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
			dev_warn(adev->dev, "RAS WARN: input address "
					"0x%llx is invalid.",
					data.inject.address);
			ret = -EINVAL;
			break;
		}

		/* umc ce/ue error injection for a bad page is not allowed */
		if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) &&
		    amdgpu_ras_check_bad_page(adev, data.inject.address)) {
			dev_warn(adev->dev, "RAS WARN: inject: 0x%llx has "
				 "already been marked as bad!\n",
				 data.inject.address);
			break;
		}

		amdgpu_ras_instance_mask_check(adev, &data);

		/* data.inject.address is offset instead of absolute gpu address */
		ret = amdgpu_ras_error_inject(adev, &data.inject);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	if (ret)
		return ret;

	return size;
}

/**
 * DOC: AMDGPU RAS debugfs EEPROM table reset interface
 *
 * Some boards contain an EEPROM which is used to persistently store a list of
 * bad pages which experiences ECC errors in vram.  This interface provides
 * a way to reset the EEPROM, e.g., after testing error injection.
 *
 * Usage:
 *
 * .. code-block:: bash
 *
 *	echo 1 > ../ras/ras_eeprom_reset
 *
 * will reset EEPROM table to 0 entries.
 *
 */
static ssize_t amdgpu_ras_debugfs_eeprom_write(struct file *f,
					       const char __user *buf,
					       size_t size, loff_t *pos)
{
	struct amdgpu_device *adev =
		(struct amdgpu_device *)file_inode(f)->i_private;
	int ret;

	ret = amdgpu_ras_eeprom_reset_table(
		&(amdgpu_ras_get_context(adev)->eeprom_control));

	if (!ret) {
		/* Something was written to EEPROM.
		 */
		amdgpu_ras_get_context(adev)->flags = RAS_DEFAULT_FLAGS;
		return size;
	} else {
		return ret;
	}
}

static const struct file_operations amdgpu_ras_debugfs_ctrl_ops = {
	.owner = THIS_MODULE,
	.read = NULL,
	.write = amdgpu_ras_debugfs_ctrl_write,
	.llseek = default_llseek
};

static const struct file_operations amdgpu_ras_debugfs_eeprom_ops = {
	.owner = THIS_MODULE,
	.read = NULL,
	.write = amdgpu_ras_debugfs_eeprom_write,
	.llseek = default_llseek
};

/**
 * DOC: AMDGPU RAS sysfs Error Count Interface
 *
 * It allows the user to read the error count for each IP block on the gpu through
 * /sys/class/drm/card[0/1/2...]/device/ras/[gfx/sdma/...]_err_count
 *
 * It outputs the multiple lines which report the uncorrected (ue) and corrected
 * (ce) error counts.
 *
 * The format of one line is below,
 *
 * [ce|ue]: count
 *
 * Example:
 *
 * .. code-block:: bash
 *
 *	ue: 0
 *	ce: 1
 *
 */
static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct ras_manager *obj = container_of(attr, struct ras_manager, sysfs_attr);
	struct ras_query_if info = {
		.head = obj->head,
	};

	if (!amdgpu_ras_get_error_query_ready(obj->adev))
		return sysfs_emit(buf, "Query currently inaccessible\n");

	if (amdgpu_ras_query_error_status(obj->adev, &info))
		return -EINVAL;

	if (amdgpu_ip_version(obj->adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 2) &&
	    amdgpu_ip_version(obj->adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 4)) {
		if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
			dev_warn(obj->adev->dev, "Failed to reset error counter and error status");
	}

	if (info.head.block == AMDGPU_RAS_BLOCK__UMC)
		return sysfs_emit(buf, "%s: %lu\n%s: %lu\n%s: %lu\n", "ue", info.ue_count,
				"ce", info.ce_count, "de", info.de_count);
	else
		return sysfs_emit(buf, "%s: %lu\n%s: %lu\n", "ue", info.ue_count,
				"ce", info.ce_count);
}

/* obj begin */

#define get_obj(obj) do { (obj)->use++; } while (0)
#define alive_obj(obj) ((obj)->use)

static inline void put_obj(struct ras_manager *obj)
{
	if (obj && (--obj->use == 0)) {
		list_del(&obj->node);
		amdgpu_ras_error_data_fini(&obj->err_data);
	}

	if (obj && (obj->use < 0))
		DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", get_ras_block_str(&obj->head));
}

/* make one obj and return it. */
static struct ras_manager *amdgpu_ras_create_obj(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj;

	if (!adev->ras_enabled || !con)
		return NULL;

	if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
		return NULL;

	if (head->block == AMDGPU_RAS_BLOCK__MCA) {
		if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST)
			return NULL;

		obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index];
	} else
		obj = &con->objs[head->block];

	/* already exist. return obj? */
	if (alive_obj(obj))
		return NULL;

	if (amdgpu_ras_error_data_init(&obj->err_data))
		return NULL;

	obj->head = *head;
	obj->adev = adev;
	list_add(&obj->node, &con->head);
	get_obj(obj);

	return obj;
}

/* return an obj equal to head, or the first when head is NULL */
struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj;
	int i;

	if (!adev->ras_enabled || !con)
		return NULL;

	if (head) {
		if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
			return NULL;

		if (head->block == AMDGPU_RAS_BLOCK__MCA) {
			if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST)
				return NULL;

			obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index];
		} else
			obj = &con->objs[head->block];

		if (alive_obj(obj))
			return obj;
	} else {
		for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT + AMDGPU_RAS_MCA_BLOCK_COUNT; i++) {
			obj = &con->objs[i];
			if (alive_obj(obj))
				return obj;
		}
	}

	return NULL;
}
/* obj end */

/* feature ctl begin */
static int amdgpu_ras_is_feature_allowed(struct amdgpu_device *adev,
					 struct ras_common_if *head)
{
	return adev->ras_hw_enabled & BIT(head->block);
}

static int amdgpu_ras_is_feature_enabled(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	return con->features & BIT(head->block);
}

/*
 * if obj is not created, then create one.
 * set feature enable flag.
 */
static int __amdgpu_ras_feature_enable(struct amdgpu_device *adev,
		struct ras_common_if *head, int enable)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);

	/* If hardware does not support ras, then do not create obj.
	 * But if hardware support ras, we can create the obj.
	 * Ras framework checks con->hw_supported to see if it need do
	 * corresponding initialization.
	 * IP checks con->support to see if it need disable ras.
	 */
	if (!amdgpu_ras_is_feature_allowed(adev, head))
		return 0;

	if (enable) {
		if (!obj) {
			obj = amdgpu_ras_create_obj(adev, head);
			if (!obj)
				return -EINVAL;
		} else {
			/* In case we create obj somewhere else */
			get_obj(obj);
		}
		con->features |= BIT(head->block);
	} else {
		if (obj && amdgpu_ras_is_feature_enabled(adev, head)) {
			con->features &= ~BIT(head->block);
			put_obj(obj);
		}
	}

	return 0;
}

/* wrapper of psp_ras_enable_features */
int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
		struct ras_common_if *head, bool enable)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	union ta_ras_cmd_input *info;
	int ret;

	if (!con)
		return -EINVAL;

	/* For non-gfx ip, do not enable ras feature if it is not allowed */
	/* For gfx ip, regardless of feature support status, */
	/* Force issue enable or disable ras feature commands */
	if (head->block != AMDGPU_RAS_BLOCK__GFX &&
	    !amdgpu_ras_is_feature_allowed(adev, head))
		return 0;

	/* Only enable gfx ras feature from host side */
	if (head->block == AMDGPU_RAS_BLOCK__GFX &&
	    !amdgpu_sriov_vf(adev) &&
	    !amdgpu_ras_intr_triggered()) {
		info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL);
		if (!info)
			return -ENOMEM;

		if (!enable) {
			info->disable_features = (struct ta_ras_disable_features_input) {
				.block_id =  amdgpu_ras_block_to_ta(head->block),
				.error_type = amdgpu_ras_error_to_ta(head->type),
			};
		} else {
			info->enable_features = (struct ta_ras_enable_features_input) {
				.block_id =  amdgpu_ras_block_to_ta(head->block),
				.error_type = amdgpu_ras_error_to_ta(head->type),
			};
		}

		ret = psp_ras_enable_features(&adev->psp, info, enable);
		if (ret) {
			dev_err(adev->dev, "ras %s %s failed poison:%d ret:%d\n",
				enable ? "enable":"disable",
				get_ras_block_str(head),
				amdgpu_ras_is_poison_mode_supported(adev), ret);
			kfree(info);
			return ret;
		}

		kfree(info);
	}

	/* setup the obj */
	__amdgpu_ras_feature_enable(adev, head, enable);

	return 0;
}

/* Only used in device probe stage and called only once. */
int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev,
		struct ras_common_if *head, bool enable)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	int ret;

	if (!con)
		return -EINVAL;

	if (con->flags & AMDGPU_RAS_FLAG_INIT_BY_VBIOS) {
		if (enable) {
			/* There is no harm to issue a ras TA cmd regardless of
			 * the currecnt ras state.
			 * If current state == target state, it will do nothing
			 * But sometimes it requests driver to reset and repost
			 * with error code -EAGAIN.
			 */
			ret = amdgpu_ras_feature_enable(adev, head, 1);
			/* With old ras TA, we might fail to enable ras.
			 * Log it and just setup the object.
			 * TODO need remove this WA in the future.
			 */
			if (ret == -EINVAL) {
				ret = __amdgpu_ras_feature_enable(adev, head, 1);
				if (!ret)
					dev_info(adev->dev,
						"RAS INFO: %s setup object\n",
						get_ras_block_str(head));
			}
		} else {
			/* setup the object then issue a ras TA disable cmd.*/
			ret = __amdgpu_ras_feature_enable(adev, head, 1);
			if (ret)
				return ret;

			/* gfx block ras disable cmd must send to ras-ta */
			if (head->block == AMDGPU_RAS_BLOCK__GFX)
				con->features |= BIT(head->block);

			ret = amdgpu_ras_feature_enable(adev, head, 0);

			/* clean gfx block ras features flag */
			if (adev->ras_enabled && head->block == AMDGPU_RAS_BLOCK__GFX)
				con->features &= ~BIT(head->block);
		}
	} else
		ret = amdgpu_ras_feature_enable(adev, head, enable);

	return ret;
}

static int amdgpu_ras_disable_all_features(struct amdgpu_device *adev,
		bool bypass)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj, *tmp;

	list_for_each_entry_safe(obj, tmp, &con->head, node) {
		/* bypass psp.
		 * aka just release the obj and corresponding flags
		 */
		if (bypass) {
			if (__amdgpu_ras_feature_enable(adev, &obj->head, 0))
				break;
		} else {
			if (amdgpu_ras_feature_enable(adev, &obj->head, 0))
				break;
		}
	}

	return con->features;
}

static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
		bool bypass)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	int i;
	const enum amdgpu_ras_error_type default_ras_type = AMDGPU_RAS_ERROR__NONE;

	for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT; i++) {
		struct ras_common_if head = {
			.block = i,
			.type = default_ras_type,
			.sub_block_index = 0,
		};

		if (i == AMDGPU_RAS_BLOCK__MCA)
			continue;

		if (bypass) {
			/*
			 * bypass psp. vbios enable ras for us.
			 * so just create the obj
			 */
			if (__amdgpu_ras_feature_enable(adev, &head, 1))
				break;
		} else {
			if (amdgpu_ras_feature_enable(adev, &head, 1))
				break;
		}
	}

	for (i = 0; i < AMDGPU_RAS_MCA_BLOCK_COUNT; i++) {
		struct ras_common_if head = {
			.block = AMDGPU_RAS_BLOCK__MCA,
			.type = default_ras_type,
			.sub_block_index = i,
		};

		if (bypass) {
			/*
			 * bypass psp. vbios enable ras for us.
			 * so just create the obj
			 */
			if (__amdgpu_ras_feature_enable(adev, &head, 1))
				break;
		} else {
			if (amdgpu_ras_feature_enable(adev, &head, 1))
				break;
		}
	}

	return con->features;
}
/* feature ctl end */

static int amdgpu_ras_block_match_default(struct amdgpu_ras_block_object *block_obj,
		enum amdgpu_ras_block block)
{
	if (!block_obj)
		return -EINVAL;

	if (block_obj->ras_comm.block == block)
		return 0;

	return -EINVAL;
}

static struct amdgpu_ras_block_object *amdgpu_ras_get_ras_block(struct amdgpu_device *adev,
					enum amdgpu_ras_block block, uint32_t sub_block_index)
{
	struct amdgpu_ras_block_list *node, *tmp;
	struct amdgpu_ras_block_object *obj;

	if (block >= AMDGPU_RAS_BLOCK__LAST)
		return NULL;

	list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {
		if (!node->ras_obj) {
			dev_warn(adev->dev, "Warning: abnormal ras list node.\n");
			continue;
		}

		obj = node->ras_obj;
		if (obj->ras_block_match) {
			if (obj->ras_block_match(obj, block, sub_block_index) == 0)
				return obj;
		} else {
			if (amdgpu_ras_block_match_default(obj, block) == 0)
				return obj;
		}
	}

	return NULL;
}

static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_data *err_data)
{
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
	int ret = 0;

	/*
	 * choosing right query method according to
	 * whether smu support query error information
	 */
	ret = amdgpu_dpm_get_ecc_info(adev, (void *)&(ras->umc_ecc));
	if (ret == -EOPNOTSUPP) {
		if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
			adev->umc.ras->ras_block.hw_ops->query_ras_error_count)
			adev->umc.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);

		/* umc query_ras_error_address is also responsible for clearing
		 * error status
		 */
		if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
		    adev->umc.ras->ras_block.hw_ops->query_ras_error_address)
			adev->umc.ras->ras_block.hw_ops->query_ras_error_address(adev, err_data);
	} else if (!ret) {
		if (adev->umc.ras &&
			adev->umc.ras->ecc_info_query_ras_error_count)
			adev->umc.ras->ecc_info_query_ras_error_count(adev, err_data);

		if (adev->umc.ras &&
			adev->umc.ras->ecc_info_query_ras_error_address)
			adev->umc.ras->ecc_info_query_ras_error_address(adev, err_data);
	}
}

static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
					      struct ras_manager *ras_mgr,
					      struct ras_err_data *err_data,
					      struct ras_query_context *qctx,
					      const char *blk_name,
					      bool is_ue,
					      bool is_de)
{
	struct amdgpu_smuio_mcm_config_info *mcm_info;
	struct ras_err_node *err_node;
	struct ras_err_info *err_info;
	u64 event_id = qctx->evid.event_id;

	if (is_ue) {
		for_each_ras_error(err_node, err_data) {
			err_info = &err_node->err_info;
			mcm_info = &err_info->mcm_info;
			if (err_info->ue_count) {
				RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
					      "%lld new uncorrectable hardware errors detected in %s block\n",
					      mcm_info->socket_id,
					      mcm_info->die_id,
					      err_info->ue_count,
					      blk_name);
			}
		}

		for_each_ras_error(err_node, &ras_mgr->err_data) {
			err_info = &err_node->err_info;
			mcm_info = &err_info->mcm_info;
			RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
				      "%lld uncorrectable hardware errors detected in total in %s block\n",
				      mcm_info->socket_id, mcm_info->die_id, err_info->ue_count, blk_name);
		}

	} else {
		if (is_de) {
			for_each_ras_error(err_node, err_data) {
				err_info = &err_node->err_info;
				mcm_info = &err_info->mcm_info;
				if (err_info->de_count) {
					RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
						      "%lld new deferred hardware errors detected in %s block\n",
						      mcm_info->socket_id,
						      mcm_info->die_id,
						      err_info->de_count,
						      blk_name);
				}
			}

			for_each_ras_error(err_node, &ras_mgr->err_data) {
				err_info = &err_node->err_info;
				mcm_info = &err_info->mcm_info;
				RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
					      "%lld deferred hardware errors detected in total in %s block\n",
					      mcm_info->socket_id, mcm_info->die_id,
					      err_info->de_count, blk_name);
			}
		} else {
			for_each_ras_error(err_node, err_data) {
				err_info = &err_node->err_info;
				mcm_info = &err_info->mcm_info;
				if (err_info->ce_count) {
					RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
						      "%lld new correctable hardware errors detected in %s block\n",
						      mcm_info->socket_id,
						      mcm_info->die_id,
						      err_info->ce_count,
						      blk_name);
				}
			}

			for_each_ras_error(err_node, &ras_mgr->err_data) {
				err_info = &err_node->err_info;
				mcm_info = &err_info->mcm_info;
				RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, "
					      "%lld correctable hardware errors detected in total in %s block\n",
					      mcm_info->socket_id, mcm_info->die_id,
					      err_info->ce_count, blk_name);
			}
		}
	}
}

static inline bool err_data_has_source_info(struct ras_err_data *data)
{
	return !list_empty(&data->err_node_list);
}

static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
					     struct ras_query_if *query_if,
					     struct ras_err_data *err_data,
					     struct ras_query_context *qctx)
{
	struct ras_manager *ras_mgr = amdgpu_ras_find_obj(adev, &query_if->head);
	const char *blk_name = get_ras_block_str(&query_if->head);
	u64 event_id = qctx->evid.event_id;

	if (err_data->ce_count) {
		if (err_data_has_source_info(err_data)) {
			amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx,
							  blk_name, false, false);
		} else if (!adev->aid_mask &&
			   adev->smuio.funcs &&
			   adev->smuio.funcs->get_socket_id &&
			   adev->smuio.funcs->get_die_id) {
			RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d "
				      "%ld correctable hardware errors "
				      "detected in %s block\n",
				      adev->smuio.funcs->get_socket_id(adev),
				      adev->smuio.funcs->get_die_id(adev),
				      ras_mgr->err_data.ce_count,
				      blk_name);
		} else {
			RAS_EVENT_LOG(adev, event_id, "%ld correctable hardware errors "
				      "detected in %s block\n",
				      ras_mgr->err_data.ce_count,
				      blk_name);
		}
	}

	if (err_data->ue_count) {
		if (err_data_has_source_info(err_data)) {
			amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx,
							  blk_name, true, false);
		} else if (!adev->aid_mask &&
			   adev->smuio.funcs &&
			   adev->smuio.funcs->get_socket_id &&
			   adev->smuio.funcs->get_die_id) {
			RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d "
				      "%ld uncorrectable hardware errors "
				      "detected in %s block\n",
				      adev->smuio.funcs->get_socket_id(adev),
				      adev->smuio.funcs->get_die_id(adev),
				      ras_mgr->err_data.ue_count,
				      blk_name);
		} else {
			RAS_EVENT_LOG(adev, event_id, "%ld uncorrectable hardware errors "
				      "detected in %s block\n",
				      ras_mgr->err_data.ue_count,
				      blk_name);
		}
	}

	if (err_data->de_count) {
		if (err_data_has_source_info(err_data)) {
			amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx,
							  blk_name, false, true);
		} else if (!adev->aid_mask &&
			   adev->smuio.funcs &&
			   adev->smuio.funcs->get_socket_id &&
			   adev->smuio.funcs->get_die_id) {
			RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d "
				      "%ld deferred hardware errors "
				      "detected in %s block\n",
				      adev->smuio.funcs->get_socket_id(adev),
				      adev->smuio.funcs->get_die_id(adev),
				      ras_mgr->err_data.de_count,
				      blk_name);
		} else {
			RAS_EVENT_LOG(adev, event_id, "%ld deferred hardware errors "
				      "detected in %s block\n",
				      ras_mgr->err_data.de_count,
				      blk_name);
		}
	}
}

static void amdgpu_ras_virt_error_generate_report(struct amdgpu_device *adev,
						  struct ras_query_if *query_if,
						  struct ras_err_data *err_data,
						  struct ras_query_context *qctx)
{
	unsigned long new_ue, new_ce, new_de;
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, &query_if->head);
	const char *blk_name = get_ras_block_str(&query_if->head);
	u64 event_id = qctx->evid.event_id;

	new_ce = err_data->ce_count - obj->err_data.ce_count;
	new_ue = err_data->ue_count - obj->err_data.ue_count;
	new_de = err_data->de_count - obj->err_data.de_count;

	if (new_ce) {
		RAS_EVENT_LOG(adev, event_id, "%lu correctable hardware errors "
			      "detected in %s block\n",
			      new_ce,
			      blk_name);
	}

	if (new_ue) {
		RAS_EVENT_LOG(adev, event_id, "%lu uncorrectable hardware errors "
			      "detected in %s block\n",
			      new_ue,
			      blk_name);
	}

	if (new_de) {
		RAS_EVENT_LOG(adev, event_id, "%lu deferred hardware errors "
			      "detected in %s block\n",
			      new_de,
			      blk_name);
	}
}

static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, struct ras_err_data *err_data)
{
	struct ras_err_node *err_node;
	struct ras_err_info *err_info;

	if (err_data_has_source_info(err_data)) {
		for_each_ras_error(err_node, err_data) {
			err_info = &err_node->err_info;
			amdgpu_ras_error_statistic_de_count(&obj->err_data,
					&err_info->mcm_info, err_info->de_count);
			amdgpu_ras_error_statistic_ce_count(&obj->err_data,
					&err_info->mcm_info, err_info->ce_count);
			amdgpu_ras_error_statistic_ue_count(&obj->err_data,
					&err_info->mcm_info, err_info->ue_count);
		}
	} else {
		/* for legacy asic path which doesn't has error source info */
		obj->err_data.ue_count += err_data->ue_count;
		obj->err_data.ce_count += err_data->ce_count;
		obj->err_data.de_count += err_data->de_count;
	}
}

static void amdgpu_ras_mgr_virt_error_data_statistics_update(struct ras_manager *obj,
							     struct ras_err_data *err_data)
{
	/* Host reports absolute counts */
	obj->err_data.ue_count = err_data->ue_count;
	obj->err_data.ce_count = err_data->ce_count;
	obj->err_data.de_count = err_data->de_count;
}

static struct ras_manager *get_ras_manager(struct amdgpu_device *adev, enum amdgpu_ras_block blk)
{
	struct ras_common_if head;

	memset(&head, 0, sizeof(head));
	head.block = blk;

	return amdgpu_ras_find_obj(adev, &head);
}

int amdgpu_ras_bind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
			const struct aca_info *aca_info, void *data)
{
	struct ras_manager *obj;

	/* in resume phase, no need to create aca fs node */
	if (adev->in_suspend || amdgpu_reset_in_recovery(adev))
		return 0;

	obj = get_ras_manager(adev, blk);
	if (!obj)
		return -EINVAL;

	return amdgpu_aca_add_handle(adev, &obj->aca_handle, ras_block_str(blk), aca_info, data);
}

int amdgpu_ras_unbind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk)
{
	struct ras_manager *obj;

	obj = get_ras_manager(adev, blk);
	if (!obj)
		return -EINVAL;

	amdgpu_aca_remove_handle(&obj->aca_handle);

	return 0;
}

static int amdgpu_aca_log_ras_error_data(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
					 enum aca_error_type type, struct ras_err_data *err_data,
					 struct ras_query_context *qctx)
{
	struct ras_manager *obj;

	obj = get_ras_manager(adev, blk);
	if (!obj)
		return -EINVAL;

	return amdgpu_aca_get_error_data(adev, &obj->aca_handle, type, err_data, qctx);
}

ssize_t amdgpu_ras_aca_sysfs_read(struct device *dev, struct device_attribute *attr,
				  struct aca_handle *handle, char *buf, void *data)
{
	struct ras_manager *obj = container_of(handle, struct ras_manager, aca_handle);
	struct ras_query_if info = {
		.head = obj->head,
	};

	if (!amdgpu_ras_get_error_query_ready(obj->adev))
		return sysfs_emit(buf, "Query currently inaccessible\n");

	if (amdgpu_ras_query_error_status(obj->adev, &info))
		return -EINVAL;

	return sysfs_emit(buf, "%s: %lu\n%s: %lu\n%s: %lu\n", "ue", info.ue_count,
			  "ce", info.ce_count, "de", info.de_count);
}

static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev,
						struct ras_query_if *info,
						struct ras_err_data *err_data,
						struct ras_query_context *qctx,
						unsigned int error_query_mode)
{
	enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT;
	struct amdgpu_ras_block_object *block_obj = NULL;
	int ret;

	if (blk == AMDGPU_RAS_BLOCK_COUNT)
		return -EINVAL;

	if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY)
		return -EINVAL;

	if (error_query_mode == AMDGPU_RAS_VIRT_ERROR_COUNT_QUERY) {
		return amdgpu_virt_req_ras_err_count(adev, blk, err_data);
	} else if (error_query_mode == AMDGPU_RAS_DIRECT_ERROR_QUERY) {
		if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
			amdgpu_ras_get_ecc_info(adev, err_data);
		} else {
			block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
			if (!block_obj || !block_obj->hw_ops) {
				dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
					     get_ras_block_str(&info->head));
				return -EINVAL;
			}

			if (block_obj->hw_ops->query_ras_error_count)
				block_obj->hw_ops->query_ras_error_count(adev, err_data);

			if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
			    (info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
			    (info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
				if (block_obj->hw_ops->query_ras_error_status)
					block_obj->hw_ops->query_ras_error_status(adev);
			}
		}
	} else {
		if (amdgpu_aca_is_enabled(adev)) {
			ret = amdgpu_aca_log_ras_error_data(adev, blk, ACA_ERROR_TYPE_UE, err_data, qctx);
			if (ret)
				return ret;

			ret = amdgpu_aca_log_ras_error_data(adev, blk, ACA_ERROR_TYPE_CE, err_data, qctx);
			if (ret)
				return ret;

			ret = amdgpu_aca_log_ras_error_data(adev, blk, ACA_ERROR_TYPE_DEFERRED, err_data, qctx);
			if (ret)
				return ret;
		} else {
			/* FIXME: add code to check return value later */
			amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_UE, err_data, qctx);
			amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_CE, err_data, qctx);
		}
	}

	return 0;
}

/* query/inject/cure begin */
static int amdgpu_ras_query_error_status_with_event(struct amdgpu_device *adev,
						    struct ras_query_if *info,
						    enum ras_event_type type)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
	struct ras_err_data err_data;
	struct ras_query_context qctx;
	unsigned int error_query_mode;
	int ret;

	if (!obj)
		return -EINVAL;

	ret = amdgpu_ras_error_data_init(&err_data);
	if (ret)
		return ret;

	if (!amdgpu_ras_get_error_query_mode(adev, &error_query_mode))
		return -EINVAL;

	memset(&qctx, 0, sizeof(qctx));
	qctx.evid.type = type;
	qctx.evid.event_id = amdgpu_ras_acquire_event_id(adev, type);

	if (!down_read_trylock(&adev->reset_domain->sem)) {
		ret = -EIO;
		goto out_fini_err_data;
	}

	ret = amdgpu_ras_query_error_status_helper(adev, info,
						   &err_data,
						   &qctx,
						   error_query_mode);
	up_read(&adev->reset_domain->sem);
	if (ret)
		goto out_fini_err_data;

	if (error_query_mode != AMDGPU_RAS_VIRT_ERROR_COUNT_QUERY) {
		amdgpu_rasmgr_error_data_statistic_update(obj, &err_data);
		amdgpu_ras_error_generate_report(adev, info, &err_data, &qctx);
	} else {
		/* Host provides absolute error counts. First generate the report
		 * using the previous VF internal count against new host count.
		 * Then Update VF internal count.
		 */
		amdgpu_ras_virt_error_generate_report(adev, info, &err_data, &qctx);
		amdgpu_ras_mgr_virt_error_data_statistics_update(obj, &err_data);
	}

	info->ue_count = obj->err_data.ue_count;
	info->ce_count = obj->err_data.ce_count;
	info->de_count = obj->err_data.de_count;

out_fini_err_data:
	amdgpu_ras_error_data_fini(&err_data);

	return ret;
}

int amdgpu_ras_query_error_status(struct amdgpu_device *adev, struct ras_query_if *info)
{
	return amdgpu_ras_query_error_status_with_event(adev, info, RAS_EVENT_TYPE_INVALID);
}

int amdgpu_ras_reset_error_count(struct amdgpu_device *adev,
		enum amdgpu_ras_block block)
{
	struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev, block, 0);
	const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
	const struct aca_smu_funcs *smu_funcs = adev->aca.smu_funcs;

	if (!block_obj || !block_obj->hw_ops) {
		dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
				ras_block_str(block));
		return -EOPNOTSUPP;
	}

	if (!amdgpu_ras_is_supported(adev, block) ||
	    !amdgpu_ras_get_aca_debug_mode(adev))
		return -EOPNOTSUPP;

	/* skip ras error reset in gpu reset */
	if ((amdgpu_in_reset(adev) || amdgpu_ras_in_recovery(adev)) &&
	    ((smu_funcs && smu_funcs->set_debug_mode) ||
	     (mca_funcs && mca_funcs->mca_set_debug_mode)))
		return -EOPNOTSUPP;

	if (block_obj->hw_ops->reset_ras_error_count)
		block_obj->hw_ops->reset_ras_error_count(adev);

	return 0;
}

int amdgpu_ras_reset_error_status(struct amdgpu_device *adev,
		enum amdgpu_ras_block block)
{
	struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev, block, 0);

	if (amdgpu_ras_reset_error_count(adev, block) == -EOPNOTSUPP)
		return 0;

	if ((block == AMDGPU_RAS_BLOCK__GFX) ||
	    (block == AMDGPU_RAS_BLOCK__MMHUB)) {
		if (block_obj->hw_ops->reset_ras_error_status)
			block_obj->hw_ops->reset_ras_error_status(adev);
	}

	return 0;
}

/* wrapper of psp_ras_trigger_error */
int amdgpu_ras_error_inject(struct amdgpu_device *adev,
		struct ras_inject_if *info)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
	struct ta_ras_trigger_error_input block_info = {
		.block_id =  amdgpu_ras_block_to_ta(info->head.block),
		.inject_error_type = amdgpu_ras_error_to_ta(info->head.type),
		.sub_block_index = info->head.sub_block_index,
		.address = info->address,
		.value = info->value,
	};
	int ret = -EINVAL;
	struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev,
							info->head.block,
							info->head.sub_block_index);

	/* inject on guest isn't allowed, return success directly */
	if (amdgpu_sriov_vf(adev))
		return 0;

	if (!obj)
		return -EINVAL;

	if (!block_obj || !block_obj->hw_ops)	{
		dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
			     get_ras_block_str(&info->head));
		return -EINVAL;
	}

	/* Calculate XGMI relative offset */
	if (adev->gmc.xgmi.num_physical_nodes > 1 &&
	    info->head.block != AMDGPU_RAS_BLOCK__GFX) {
		block_info.address =
			amdgpu_xgmi_get_relative_phy_addr(adev,
							  block_info.address);
	}

	if (block_obj->hw_ops->ras_error_inject) {
		if (info->head.block == AMDGPU_RAS_BLOCK__GFX)
			ret = block_obj->hw_ops->ras_error_inject(adev, info, info->instance_mask);
		else /* Special ras_error_inject is defined (e.g: xgmi) */
			ret = block_obj->hw_ops->ras_error_inject(adev, &block_info,
						info->instance_mask);
	} else {
		/* default path */
		ret = psp_ras_trigger_error(&adev->psp, &block_info, info->instance_mask);
	}

	if (ret)
		dev_err(adev->dev, "ras inject %s failed %d\n",
			get_ras_block_str(&info->head), ret);

	return ret;
}

/**
 * amdgpu_ras_query_error_count_helper -- Get error counter for specific IP
 * @adev: pointer to AMD GPU device
 * @ce_count: pointer to an integer to be set to the count of correctible errors.
 * @ue_count: pointer to an integer to be set to the count of uncorrectible errors.
 * @query_info: pointer to ras_query_if
 *
 * Return 0 for query success or do nothing, otherwise return an error
 * on failures
 */
static int amdgpu_ras_query_error_count_helper(struct amdgpu_device *adev,
					       unsigned long *ce_count,
					       unsigned long *ue_count,
					       struct ras_query_if *query_info)
{
	int ret;

	if (!query_info)
		/* do nothing if query_info is not specified */
		return 0;

	ret = amdgpu_ras_query_error_status(adev, query_info);
	if (ret)
		return ret;

	*ce_count += query_info->ce_count;
	*ue_count += query_info->ue_count;

	/* some hardware/IP supports read to clear
	 * no need to explictly reset the err status after the query call */
	if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 2) &&
	    amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(11, 0, 4)) {
		if (amdgpu_ras_reset_error_status(adev, query_info->head.block))
			dev_warn(adev->dev,
				 "Failed to reset error counter and error status\n");
	}

	return 0;
}

/**
 * amdgpu_ras_query_error_count -- Get error counts of all IPs or specific IP
 * @adev: pointer to AMD GPU device
 * @ce_count: pointer to an integer to be set to the count of correctible errors.
 * @ue_count: pointer to an integer to be set to the count of uncorrectible
 * errors.
 * @query_info: pointer to ras_query_if if the query request is only for
 * specific ip block; if info is NULL, then the qurey request is for
 * all the ip blocks that support query ras error counters/status
 *
 * If set, @ce_count or @ue_count, count and return the corresponding
 * error counts in those integer pointers. Return 0 if the device
 * supports RAS. Return -EOPNOTSUPP if the device doesn't support RAS.
 */
int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
				 unsigned long *ce_count,
				 unsigned long *ue_count,
				 struct ras_query_if *query_info)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj;
	unsigned long ce, ue;
	int ret;

	if (!adev->ras_enabled || !con)
		return -EOPNOTSUPP;

	/* Don't count since no reporting.
	 */
	if (!ce_count && !ue_count)
		return 0;

	ce = 0;
	ue = 0;
	if (!query_info) {
		/* query all the ip blocks that support ras query interface */
		list_for_each_entry(obj, &con->head, node) {
			struct ras_query_if info = {
				.head = obj->head,
			};

			ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, &info);
		}
	} else {
		/* query specific ip block */
		ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, query_info);
	}

	if (ret)
		return ret;

	if (ce_count)
		*ce_count = ce;

	if (ue_count)
		*ue_count = ue;

	return 0;
}
/* query/inject/cure end */


/* sysfs begin */

static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
		struct ras_badpage **bps, unsigned int *count);

static char *amdgpu_ras_badpage_flags_str(unsigned int flags)
{
	switch (flags) {
	case AMDGPU_RAS_RETIRE_PAGE_RESERVED:
		return "R";
	case AMDGPU_RAS_RETIRE_PAGE_PENDING:
		return "P";
	case AMDGPU_RAS_RETIRE_PAGE_FAULT:
	default:
		return "F";
	}
}

/**
 * DOC: AMDGPU RAS sysfs gpu_vram_bad_pages Interface
 *
 * It allows user to read the bad pages of vram on the gpu through
 * /sys/class/drm/card[0/1/2...]/device/ras/gpu_vram_bad_pages
 *
 * It outputs multiple lines, and each line stands for one gpu page.
 *
 * The format of one line is below,
 * gpu pfn : gpu page size : flags
 *
 * gpu pfn and gpu page size are printed in hex format.
 * flags can be one of below character,
 *
 * R: reserved, this gpu page is reserved and not able to use.
 *
 * P: pending for reserve, this gpu page is marked as bad, will be reserved
 * in next window of page_reserve.
 *
 * F: unable to reserve. this gpu page can't be reserved due to some reasons.
 *
 * Examples:
 *
 * .. code-block:: bash
 *
 *	0x00000001 : 0x00001000 : R
 *	0x00000002 : 0x00001000 : P
 *
 */

static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
		struct kobject *kobj, const struct bin_attribute *attr,
		char *buf, loff_t ppos, size_t count)
{
	struct amdgpu_ras *con =
		container_of(attr, struct amdgpu_ras, badpages_attr);
	struct amdgpu_device *adev = con->adev;
	const unsigned int element_size =
		sizeof("0xabcdabcd : 0x12345678 : R\n") - 1;
	unsigned int start = div64_ul(ppos + element_size - 1, element_size);
	unsigned int end = div64_ul(ppos + count - 1, element_size);
	ssize_t s = 0;
	struct ras_badpage *bps = NULL;
	unsigned int bps_count = 0;

	memset(buf, 0, count);

	if (amdgpu_ras_badpages_read(adev, &bps, &bps_count))
		return 0;

	for (; start < end && start < bps_count; start++)
		s += scnprintf(&buf[s], element_size + 1,
				"0x%08x : 0x%08x : %1s\n",
				bps[start].bp,
				bps[start].size,
				amdgpu_ras_badpage_flags_str(bps[start].flags));

	kfree(bps);

	return s;
}

static ssize_t amdgpu_ras_sysfs_features_read(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct amdgpu_ras *con =
		container_of(attr, struct amdgpu_ras, features_attr);

	return sysfs_emit(buf, "feature mask: 0x%x\n", con->features);
}

static ssize_t amdgpu_ras_sysfs_version_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct amdgpu_ras *con =
		container_of(attr, struct amdgpu_ras, version_attr);
	return sysfs_emit(buf, "table version: 0x%x\n", con->eeprom_control.tbl_hdr.version);
}

static ssize_t amdgpu_ras_sysfs_schema_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct amdgpu_ras *con =
		container_of(attr, struct amdgpu_ras, schema_attr);
	return sysfs_emit(buf, "schema: 0x%x\n", con->schema);
}

static struct {
	enum ras_event_type type;
	const char *name;
} dump_event[] = {
	{RAS_EVENT_TYPE_FATAL, "Fatal Error"},
	{RAS_EVENT_TYPE_POISON_CREATION, "Poison Creation"},
	{RAS_EVENT_TYPE_POISON_CONSUMPTION, "Poison Consumption"},
};

static ssize_t amdgpu_ras_sysfs_event_state_show(struct device *dev,
						 struct device_attribute *attr, char *buf)
{
	struct amdgpu_ras *con =
		container_of(attr, struct amdgpu_ras, event_state_attr);
	struct ras_event_manager *event_mgr = con->event_mgr;
	struct ras_event_state *event_state;
	int i, size = 0;

	if (!event_mgr)
		return -EINVAL;

	size += sysfs_emit_at(buf, size, "current seqno: %llu\n", atomic64_read(&event_mgr->seqno));
	for (i = 0; i < ARRAY_SIZE(dump_event); i++) {
		event_state = &event_mgr->event_state[dump_event[i].type];
		size += sysfs_emit_at(buf, size, "%s: count:%llu, last_seqno:%llu\n",
				      dump_event[i].name,
				      atomic64_read(&event_state->count),
				      event_state->last_seqno);
	}

	return (ssize_t)size;
}

static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (adev->dev->kobj.sd)
		sysfs_remove_file_from_group(&adev->dev->kobj,
				&con->badpages_attr.attr,
				RAS_FS_NAME);
}

static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct attribute *attrs[] = {
		&con->features_attr.attr,
		&con->version_attr.attr,
		&con->schema_attr.attr,
		&con->event_state_attr.attr,
		NULL
	};
	struct attribute_group group = {
		.name = RAS_FS_NAME,
		.attrs = attrs,
	};

	if (adev->dev->kobj.sd)
		sysfs_remove_group(&adev->dev->kobj, &group);

	return 0;
}

int amdgpu_ras_sysfs_create(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);

	if (amdgpu_aca_is_enabled(adev))
		return 0;

	if (!obj || obj->attr_inuse)
		return -EINVAL;

	if (amdgpu_sriov_vf(adev) && !amdgpu_virt_ras_telemetry_block_en(adev, head->block))
		return 0;

	get_obj(obj);

	snprintf(obj->fs_data.sysfs_name, sizeof(obj->fs_data.sysfs_name),
		"%s_err_count", head->name);

	obj->sysfs_attr = (struct device_attribute){
		.attr = {
			.name = obj->fs_data.sysfs_name,
			.mode = S_IRUGO,
		},
			.show = amdgpu_ras_sysfs_read,
	};
	sysfs_attr_init(&obj->sysfs_attr.attr);

	if (sysfs_add_file_to_group(&adev->dev->kobj,
				&obj->sysfs_attr.attr,
				RAS_FS_NAME)) {
		put_obj(obj);
		return -EINVAL;
	}

	obj->attr_inuse = 1;

	return 0;
}

int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);

	if (amdgpu_aca_is_enabled(adev))
		return 0;

	if (!obj || !obj->attr_inuse)
		return -EINVAL;

	if (adev->dev->kobj.sd)
		sysfs_remove_file_from_group(&adev->dev->kobj,
				&obj->sysfs_attr.attr,
				RAS_FS_NAME);
	obj->attr_inuse = 0;
	put_obj(obj);

	return 0;
}

static int amdgpu_ras_sysfs_remove_all(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj, *tmp;

	list_for_each_entry_safe(obj, tmp, &con->head, node) {
		amdgpu_ras_sysfs_remove(adev, &obj->head);
	}

	if (amdgpu_bad_page_threshold != 0)
		amdgpu_ras_sysfs_remove_bad_page_node(adev);

	amdgpu_ras_sysfs_remove_dev_attr_node(adev);

	return 0;
}
/* sysfs end */

/**
 * DOC: AMDGPU RAS Reboot Behavior for Unrecoverable Errors
 *
 * Normally when there is an uncorrectable error, the driver will reset
 * the GPU to recover.  However, in the event of an unrecoverable error,
 * the driver provides an interface to reboot the system automatically
 * in that event.
 *
 * The following file in debugfs provides that interface:
 * /sys/kernel/debug/dri/[0/1/2...]/ras/auto_reboot
 *
 * Usage:
 *
 * .. code-block:: bash
 *
 *	echo true > .../ras/auto_reboot
 *
 */
/* debugfs begin */
static struct dentry *amdgpu_ras_debugfs_create_ctrl_node(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct amdgpu_ras_eeprom_control *eeprom = &con->eeprom_control;
	struct drm_minor  *minor = adev_to_drm(adev)->primary;
	struct dentry     *dir;

	dir = debugfs_create_dir(RAS_FS_NAME, minor->debugfs_root);
	debugfs_create_file("ras_ctrl", S_IWUGO | S_IRUGO, dir, adev,
			    &amdgpu_ras_debugfs_ctrl_ops);
	debugfs_create_file("ras_eeprom_reset", S_IWUGO | S_IRUGO, dir, adev,
			    &amdgpu_ras_debugfs_eeprom_ops);
	debugfs_create_u32("bad_page_cnt_threshold", 0444, dir,
			   &con->bad_page_cnt_threshold);
	debugfs_create_u32("ras_num_recs", 0444, dir, &eeprom->ras_num_recs);
	debugfs_create_x32("ras_hw_enabled", 0444, dir, &adev->ras_hw_enabled);
	debugfs_create_x32("ras_enabled", 0444, dir, &adev->ras_enabled);
	debugfs_create_file("ras_eeprom_size", S_IRUGO, dir, adev,
			    &amdgpu_ras_debugfs_eeprom_size_ops);
	con->de_ras_eeprom_table = debugfs_create_file("ras_eeprom_table",
						       S_IRUGO, dir, adev,
						       &amdgpu_ras_debugfs_eeprom_table_ops);
	amdgpu_ras_debugfs_set_ret_size(&con->eeprom_control);

	/*
	 * After one uncorrectable error happens, usually GPU recovery will
	 * be scheduled. But due to the known problem in GPU recovery failing
	 * to bring GPU back, below interface provides one direct way to
	 * user to reboot system automatically in such case within
	 * ERREVENT_ATHUB_INTERRUPT generated. Normal GPU recovery routine
	 * will never be called.
	 */
	debugfs_create_bool("auto_reboot", S_IWUGO | S_IRUGO, dir, &con->reboot);

	/*
	 * User could set this not to clean up hardware's error count register
	 * of RAS IPs during ras recovery.
	 */
	debugfs_create_bool("disable_ras_err_cnt_harvest", 0644, dir,
			    &con->disable_ras_err_cnt_harvest);
	return dir;
}

static void amdgpu_ras_debugfs_create(struct amdgpu_device *adev,
				      struct ras_fs_if *head,
				      struct dentry *dir)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head->head);

	if (!obj || !dir)
		return;

	get_obj(obj);

	memcpy(obj->fs_data.debugfs_name,
			head->debugfs_name,
			sizeof(obj->fs_data.debugfs_name));

	debugfs_create_file(obj->fs_data.debugfs_name, S_IWUGO | S_IRUGO, dir,
			    obj, &amdgpu_ras_debugfs_ops);
}

static bool amdgpu_ras_aca_is_supported(struct amdgpu_device *adev)
{
	bool ret;

	switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
	case IP_VERSION(13, 0, 6):
	case IP_VERSION(13, 0, 12):
	case IP_VERSION(13, 0, 14):
		ret = true;
		break;
	default:
		ret = false;
		break;
	}

	return ret;
}

void amdgpu_ras_debugfs_create_all(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct dentry *dir;
	struct ras_manager *obj;
	struct ras_fs_if fs_info;

	/*
	 * it won't be called in resume path, no need to check
	 * suspend and gpu reset status
	 */
	if (!IS_ENABLED(CONFIG_DEBUG_FS) || !con)
		return;

	dir = amdgpu_ras_debugfs_create_ctrl_node(adev);

	list_for_each_entry(obj, &con->head, node) {
		if (amdgpu_ras_is_supported(adev, obj->head.block) &&
			(obj->attr_inuse == 1)) {
			sprintf(fs_info.debugfs_name, "%s_err_inject",
					get_ras_block_str(&obj->head));
			fs_info.head = obj->head;
			amdgpu_ras_debugfs_create(adev, &fs_info, dir);
		}
	}

	if (amdgpu_ras_aca_is_supported(adev)) {
		if (amdgpu_aca_is_enabled(adev))
			amdgpu_aca_smu_debugfs_init(adev, dir);
		else
			amdgpu_mca_smu_debugfs_init(adev, dir);
	}
}

/* debugfs end */

/* ras fs */
static const BIN_ATTR(gpu_vram_bad_pages, S_IRUGO,
		      amdgpu_ras_sysfs_badpages_read, NULL, 0);
static DEVICE_ATTR(features, S_IRUGO,
		amdgpu_ras_sysfs_features_read, NULL);
static DEVICE_ATTR(version, 0444,
		amdgpu_ras_sysfs_version_show, NULL);
static DEVICE_ATTR(schema, 0444,
		amdgpu_ras_sysfs_schema_show, NULL);
static DEVICE_ATTR(event_state, 0444,
		   amdgpu_ras_sysfs_event_state_show, NULL);
static int amdgpu_ras_fs_init(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct attribute_group group = {
		.name = RAS_FS_NAME,
	};
	struct attribute *attrs[] = {
		&con->features_attr.attr,
		&con->version_attr.attr,
		&con->schema_attr.attr,
		&con->event_state_attr.attr,
		NULL
	};
	const struct bin_attribute *bin_attrs[] = {
		NULL,
		NULL,
	};
	int r;

	group.attrs = attrs;

	/* add features entry */
	con->features_attr = dev_attr_features;
	sysfs_attr_init(attrs[0]);

	/* add version entry */
	con->version_attr = dev_attr_version;
	sysfs_attr_init(attrs[1]);

	/* add schema entry */
	con->schema_attr = dev_attr_schema;
	sysfs_attr_init(attrs[2]);

	/* add event_state entry */
	con->event_state_attr = dev_attr_event_state;
	sysfs_attr_init(attrs[3]);

	if (amdgpu_bad_page_threshold != 0) {
		/* add bad_page_features entry */
		con->badpages_attr = bin_attr_gpu_vram_bad_pages;
		sysfs_bin_attr_init(&con->badpages_attr);
		bin_attrs[0] = &con->badpages_attr;
		group.bin_attrs_new = bin_attrs;
	}

	r = sysfs_create_group(&adev->dev->kobj, &group);
	if (r)
		dev_err(adev->dev, "Failed to create RAS sysfs group!");

	return 0;
}

static int amdgpu_ras_fs_fini(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *con_obj, *ip_obj, *tmp;

	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
		list_for_each_entry_safe(con_obj, tmp, &con->head, node) {
			ip_obj = amdgpu_ras_find_obj(adev, &con_obj->head);
			if (ip_obj)
				put_obj(ip_obj);
		}
	}

	amdgpu_ras_sysfs_remove_all(adev);
	return 0;
}
/* ras fs end */

/* ih begin */

/* For the hardware that cannot enable bif ring for both ras_controller_irq
 * and ras_err_evnet_athub_irq ih cookies, the driver has to poll status
 * register to check whether the interrupt is triggered or not, and properly
 * ack the interrupt if it is there
 */
void amdgpu_ras_interrupt_fatal_error_handler(struct amdgpu_device *adev)
{
	/* Fatal error events are handled on host side */
	if (amdgpu_sriov_vf(adev))
		return;
	/**
	 * If the current interrupt is caused by a non-fatal RAS error, skip
	 * check for fatal error. For fatal errors, FED status of all devices
	 * in XGMI hive gets set when the first device gets fatal error
	 * interrupt. The error gets propagated to other devices as well, so
	 * make sure to ack the interrupt regardless of FED status.
	 */
	if (!amdgpu_ras_get_fed_status(adev) &&
	    amdgpu_ras_is_err_state(adev, AMDGPU_RAS_BLOCK__ANY))
		return;

	if (adev->nbio.ras &&
	    adev->nbio.ras->handle_ras_controller_intr_no_bifring)
		adev->nbio.ras->handle_ras_controller_intr_no_bifring(adev);

	if (adev->nbio.ras &&
	    adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring)
		adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring(adev);
}

static void amdgpu_ras_interrupt_poison_consumption_handler(struct ras_manager *obj,
				struct amdgpu_iv_entry *entry)
{
	bool poison_stat = false;
	struct amdgpu_device *adev = obj->adev;
	struct amdgpu_ras_block_object *block_obj =
		amdgpu_ras_get_ras_block(adev, obj->head.block, 0);
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	enum ras_event_type type = RAS_EVENT_TYPE_POISON_CONSUMPTION;
	u64 event_id;
	int ret;

	if (!block_obj || !con)
		return;

	ret = amdgpu_ras_mark_ras_event(adev, type);
	if (ret)
		return;

	amdgpu_ras_set_err_poison(adev, block_obj->ras_comm.block);
	/* both query_poison_status and handle_poison_consumption are optional,
	 * but at least one of them should be implemented if we need poison
	 * consumption handler
	 */
	if (block_obj->hw_ops && block_obj->hw_ops->query_poison_status) {
		poison_stat = block_obj->hw_ops->query_poison_status(adev);
		if (!poison_stat) {
			/* Not poison consumption interrupt, no need to handle it */
			dev_info(adev->dev, "No RAS poison status in %s poison IH.\n",
					block_obj->ras_comm.name);

			return;
		}
	}

	amdgpu_umc_poison_handler(adev, obj->head.block, 0);

	if (block_obj->hw_ops && block_obj->hw_ops->handle_poison_consumption)
		poison_stat = block_obj->hw_ops->handle_poison_consumption(adev);

	/* gpu reset is fallback for failed and default cases.
	 * For RMA case, amdgpu_umc_poison_handler will handle gpu reset.
	 */
	if (poison_stat && !amdgpu_ras_is_rma(adev)) {
		event_id = amdgpu_ras_acquire_event_id(adev, type);
		RAS_EVENT_LOG(adev, event_id,
			      "GPU reset for %s RAS poison consumption is issued!\n",
			      block_obj->ras_comm.name);
		amdgpu_ras_reset_gpu(adev);
	}

	if (!poison_stat)
		amdgpu_gfx_poison_consumption_handler(adev, entry);
}

static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj,
				struct amdgpu_iv_entry *entry)
{
	struct amdgpu_device *adev = obj->adev;
	enum ras_event_type type = RAS_EVENT_TYPE_POISON_CREATION;
	u64 event_id;
	int ret;

	ret = amdgpu_ras_mark_ras_event(adev, type);
	if (ret)
		return;

	event_id = amdgpu_ras_acquire_event_id(adev, type);
	RAS_EVENT_LOG(adev, event_id, "Poison is created\n");

	if (amdgpu_ip_version(obj->adev, UMC_HWIP, 0) >= IP_VERSION(12, 0, 0)) {
		struct amdgpu_ras *con = amdgpu_ras_get_context(obj->adev);

		atomic_inc(&con->page_retirement_req_cnt);
		atomic_inc(&con->poison_creation_count);

		wake_up(&con->page_retirement_wq);
	}
}

static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj,
				struct amdgpu_iv_entry *entry)
{
	struct ras_ih_data *data = &obj->ih_data;
	struct ras_err_data err_data;
	int ret;

	if (!data->cb)
		return;

	ret = amdgpu_ras_error_data_init(&err_data);
	if (ret)
		return;

	/* Let IP handle its data, maybe we need get the output
	 * from the callback to update the error type/count, etc
	 */
	amdgpu_ras_set_fed(obj->adev, true);
	ret = data->cb(obj->adev, &err_data, entry);
	/* ue will trigger an interrupt, and in that case
	 * we need do a reset to recovery the whole system.
	 * But leave IP do that recovery, here we just dispatch
	 * the error.
	 */
	if (ret == AMDGPU_RAS_SUCCESS) {
		/* these counts could be left as 0 if
		 * some blocks do not count error number
		 */
		obj->err_data.ue_count += err_data.ue_count;
		obj->err_data.ce_count += err_data.ce_count;
		obj->err_data.de_count += err_data.de_count;
	}

	amdgpu_ras_error_data_fini(&err_data);
}

static void amdgpu_ras_interrupt_handler(struct ras_manager *obj)
{
	struct ras_ih_data *data = &obj->ih_data;
	struct amdgpu_iv_entry entry;

	while (data->rptr != data->wptr) {
		rmb();
		memcpy(&entry, &data->ring[data->rptr],
				data->element_size);

		wmb();
		data->rptr = (data->aligned_element_size +
				data->rptr) % data->ring_size;

		if (amdgpu_ras_is_poison_mode_supported(obj->adev)) {
			if (obj->head.block == AMDGPU_RAS_BLOCK__UMC)
				amdgpu_ras_interrupt_poison_creation_handler(obj, &entry);
			else
				amdgpu_ras_interrupt_poison_consumption_handler(obj, &entry);
		} else {
			if (obj->head.block == AMDGPU_RAS_BLOCK__UMC)
				amdgpu_ras_interrupt_umc_handler(obj, &entry);
			else
				dev_warn(obj->adev->dev,
					"No RAS interrupt handler for non-UMC block with poison disabled.\n");
		}
	}
}

static void amdgpu_ras_interrupt_process_handler(struct work_struct *work)
{
	struct ras_ih_data *data =
		container_of(work, struct ras_ih_data, ih_work);
	struct ras_manager *obj =
		container_of(data, struct ras_manager, ih_data);

	amdgpu_ras_interrupt_handler(obj);
}

int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
		struct ras_dispatch_if *info)
{
	struct ras_manager *obj;
	struct ras_ih_data *data;

	obj = amdgpu_ras_find_obj(adev, &info->head);
	if (!obj)
		return -EINVAL;

	data = &obj->ih_data;

	if (data->inuse == 0)
		return 0;

	/* Might be overflow... */
	memcpy(&data->ring[data->wptr], info->entry,
			data->element_size);

	wmb();
	data->wptr = (data->aligned_element_size +
			data->wptr) % data->ring_size;

	schedule_work(&data->ih_work);

	return 0;
}

int amdgpu_ras_interrupt_remove_handler(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);
	struct ras_ih_data *data;

	if (!obj)
		return -EINVAL;

	data = &obj->ih_data;
	if (data->inuse == 0)
		return 0;

	cancel_work_sync(&data->ih_work);

	kfree(data->ring);
	memset(data, 0, sizeof(*data));
	put_obj(obj);

	return 0;
}

int amdgpu_ras_interrupt_add_handler(struct amdgpu_device *adev,
		struct ras_common_if *head)
{
	struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);
	struct ras_ih_data *data;
	struct amdgpu_ras_block_object *ras_obj;

	if (!obj) {
		/* in case we registe the IH before enable ras feature */
		obj = amdgpu_ras_create_obj(adev, head);
		if (!obj)
			return -EINVAL;
	} else
		get_obj(obj);

	ras_obj = container_of(head, struct amdgpu_ras_block_object, ras_comm);

	data = &obj->ih_data;
	/* add the callback.etc */
	*data = (struct ras_ih_data) {
		.inuse = 0,
		.cb = ras_obj->ras_cb,
		.element_size = sizeof(struct amdgpu_iv_entry),
		.rptr = 0,
		.wptr = 0,
	};

	INIT_WORK(&data->ih_work, amdgpu_ras_interrupt_process_handler);

	data->aligned_element_size = ALIGN(data->element_size, 8);
	/* the ring can store 64 iv entries. */
	data->ring_size = 64 * data->aligned_element_size;
	data->ring = kmalloc(data->ring_size, GFP_KERNEL);
	if (!data->ring) {
		put_obj(obj);
		return -ENOMEM;
	}

	/* IH is ready */
	data->inuse = 1;

	return 0;
}

static int amdgpu_ras_interrupt_remove_all(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj, *tmp;

	list_for_each_entry_safe(obj, tmp, &con->head, node) {
		amdgpu_ras_interrupt_remove_handler(adev, &obj->head);
	}

	return 0;
}
/* ih end */

/* traversal all IPs except NBIO to query error counter */
static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev, enum ras_event_type type)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj;

	if (!adev->ras_enabled || !con)
		return;

	list_for_each_entry(obj, &con->head, node) {
		struct ras_query_if info = {
			.head = obj->head,
		};

		/*
		 * PCIE_BIF IP has one different isr by ras controller
		 * interrupt, the specific ras counter query will be
		 * done in that isr. So skip such block from common
		 * sync flood interrupt isr calling.
		 */
		if (info.head.block == AMDGPU_RAS_BLOCK__PCIE_BIF)
			continue;

		/*
		 * this is a workaround for aldebaran, skip send msg to
		 * smu to get ecc_info table due to smu handle get ecc
		 * info table failed temporarily.
		 * should be removed until smu fix handle ecc_info table.
		 */
		if ((info.head.block == AMDGPU_RAS_BLOCK__UMC) &&
		    (amdgpu_ip_version(adev, MP1_HWIP, 0) ==
		     IP_VERSION(13, 0, 2)))
			continue;

		amdgpu_ras_query_error_status_with_event(adev, &info, type);

		if (amdgpu_ip_version(adev, MP0_HWIP, 0) !=
			    IP_VERSION(11, 0, 2) &&
		    amdgpu_ip_version(adev, MP0_HWIP, 0) !=
			    IP_VERSION(11, 0, 4) &&
		    amdgpu_ip_version(adev, MP0_HWIP, 0) !=
			    IP_VERSION(13, 0, 0)) {
			if (amdgpu_ras_reset_error_status(adev, info.head.block))
				dev_warn(adev->dev, "Failed to reset error counter and error status");
		}
	}
}

/* Parse RdRspStatus and WrRspStatus */
static void amdgpu_ras_error_status_query(struct amdgpu_device *adev,
					  struct ras_query_if *info)
{
	struct amdgpu_ras_block_object *block_obj;
	/*
	 * Only two block need to query read/write
	 * RspStatus at current state
	 */
	if ((info->head.block != AMDGPU_RAS_BLOCK__GFX) &&
		(info->head.block != AMDGPU_RAS_BLOCK__MMHUB))
		return;

	block_obj = amdgpu_ras_get_ras_block(adev,
					info->head.block,
					info->head.sub_block_index);

	if (!block_obj || !block_obj->hw_ops) {
		dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
			     get_ras_block_str(&info->head));
		return;
	}

	if (block_obj->hw_ops->query_ras_error_status)
		block_obj->hw_ops->query_ras_error_status(adev);

}

static void amdgpu_ras_query_err_status(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj;

	if (!adev->ras_enabled || !con)
		return;

	list_for_each_entry(obj, &con->head, node) {
		struct ras_query_if info = {
			.head = obj->head,
		};

		amdgpu_ras_error_status_query(adev, &info);
	}
}

/* recovery begin */

/* return 0 on success.
 * caller need free bps.
 */
static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
		struct ras_badpage **bps, unsigned int *count)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_handler_data *data;
	int i = 0;
	int ret = 0, status;

	if (!con || !con->eh_data || !bps || !count)
		return -EINVAL;

	mutex_lock(&con->recovery_lock);
	data = con->eh_data;
	if (!data || data->count == 0) {
		*bps = NULL;
		ret = -EINVAL;
		goto out;
	}

	*bps = kmalloc(sizeof(struct ras_badpage) * data->count, GFP_KERNEL);
	if (!*bps) {
		ret = -ENOMEM;
		goto out;
	}

	for (; i < data->count; i++) {
		(*bps)[i] = (struct ras_badpage){
			.bp = data->bps[i].retired_page,
			.size = AMDGPU_GPU_PAGE_SIZE,
			.flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED,
		};
		status = amdgpu_vram_mgr_query_page_status(&adev->mman.vram_mgr,
				data->bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT);
		if (status == -EBUSY)
			(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING;
		else if (status == -ENOENT)
			(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT;
	}

	*count = data->count;
out:
	mutex_unlock(&con->recovery_lock);
	return ret;
}

static void amdgpu_ras_set_fed_all(struct amdgpu_device *adev,
				   struct amdgpu_hive_info *hive, bool status)
{
	struct amdgpu_device *tmp_adev;

	if (hive) {
		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
			amdgpu_ras_set_fed(tmp_adev, status);
	} else {
		amdgpu_ras_set_fed(adev, status);
	}
}

bool amdgpu_ras_in_recovery(struct amdgpu_device *adev)
{
	struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
	int hive_ras_recovery = 0;

	if (hive) {
		hive_ras_recovery = atomic_read(&hive->ras_recovery);
		amdgpu_put_xgmi_hive(hive);
	}

	if (ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery))
		return true;

	return false;
}

static enum ras_event_type amdgpu_ras_get_fatal_error_event(struct amdgpu_device *adev)
{
	if (amdgpu_ras_intr_triggered())
		return RAS_EVENT_TYPE_FATAL;
	else
		return RAS_EVENT_TYPE_POISON_CONSUMPTION;
}

static void amdgpu_ras_do_recovery(struct work_struct *work)
{
	struct amdgpu_ras *ras =
		container_of(work, struct amdgpu_ras, recovery_work);
	struct amdgpu_device *remote_adev = NULL;
	struct amdgpu_device *adev = ras->adev;
	struct list_head device_list, *device_list_handle =  NULL;
	struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
	enum ras_event_type type;

	if (hive) {
		atomic_set(&hive->ras_recovery, 1);

		/* If any device which is part of the hive received RAS fatal
		 * error interrupt, set fatal error status on all. This
		 * condition will need a recovery, and flag will be cleared
		 * as part of recovery.
		 */
		list_for_each_entry(remote_adev, &hive->device_list,
				    gmc.xgmi.head)
			if (amdgpu_ras_get_fed_status(remote_adev)) {
				amdgpu_ras_set_fed_all(adev, hive, true);
				break;
			}
	}
	if (!ras->disable_ras_err_cnt_harvest) {

		/* Build list of devices to query RAS related errors */
		if  (hive && adev->gmc.xgmi.num_physical_nodes > 1) {
			device_list_handle = &hive->device_list;
		} else {
			INIT_LIST_HEAD(&device_list);
			list_add_tail(&adev->gmc.xgmi.head, &device_list);
			device_list_handle = &device_list;
		}

		type = amdgpu_ras_get_fatal_error_event(adev);
		list_for_each_entry(remote_adev,
				device_list_handle, gmc.xgmi.head) {
			amdgpu_ras_query_err_status(remote_adev);
			amdgpu_ras_log_on_err_counter(remote_adev, type);
		}

	}

	if (amdgpu_device_should_recover_gpu(ras->adev)) {
		struct amdgpu_reset_context reset_context;
		memset(&reset_context, 0, sizeof(reset_context));

		reset_context.method = AMD_RESET_METHOD_NONE;
		reset_context.reset_req_dev = adev;
		reset_context.src = AMDGPU_RESET_SRC_RAS;
		set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);

		/* Perform full reset in fatal error mode */
		if (!amdgpu_ras_is_poison_mode_supported(ras->adev))
			set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
		else {
			clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);

			if (ras->gpu_reset_flags & AMDGPU_RAS_GPU_RESET_MODE2_RESET) {
				ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE2_RESET;
				reset_context.method = AMD_RESET_METHOD_MODE2;
			}

			/* Fatal error occurs in poison mode, mode1 reset is used to
			 * recover gpu.
			 */
			if (ras->gpu_reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) {
				ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE1_RESET;
				set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);

				psp_fatal_error_recovery_quirk(&adev->psp);
			}
		}

		amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
	}
	atomic_set(&ras->in_recovery, 0);
	if (hive) {
		atomic_set(&hive->ras_recovery, 0);
		amdgpu_put_xgmi_hive(hive);
	}
}

/* alloc/realloc bps array */
static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev,
		struct ras_err_handler_data *data, int pages)
{
	unsigned int old_space = data->count + data->space_left;
	unsigned int new_space = old_space + pages;
	unsigned int align_space = ALIGN(new_space, 512);
	void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL);

	if (!bps) {
		return -ENOMEM;
	}

	if (data->bps) {
		memcpy(bps, data->bps,
				data->count * sizeof(*data->bps));
		kfree(data->bps);
	}

	data->bps = bps;
	data->space_left += align_space - old_space;
	return 0;
}

static int amdgpu_ras_mca2pa_by_idx(struct amdgpu_device *adev,
			struct eeprom_table_record *bps,
			struct ras_err_data *err_data)
{
	struct ta_ras_query_address_input addr_in;
	uint32_t socket = 0;
	int ret = 0;

	if (adev->smuio.funcs && adev->smuio.funcs->get_socket_id)
		socket = adev->smuio.funcs->get_socket_id(adev);

	/* reinit err_data */
	err_data->err_addr_cnt = 0;
	err_data->err_addr_len = adev->umc.retire_unit;

	memset(&addr_in, 0, sizeof(addr_in));
	addr_in.ma.err_addr = bps->address;
	addr_in.ma.socket_id = socket;
	addr_in.ma.ch_inst = bps->mem_channel;
	/* tell RAS TA the node instance is not used */
	addr_in.ma.node_inst = TA_RAS_INV_NODE;

	if (adev->umc.ras && adev->umc.ras->convert_ras_err_addr)
		ret = adev->umc.ras->convert_ras_err_addr(adev, err_data,
				&addr_in, NULL, false);

	return ret;
}

static int amdgpu_ras_mca2pa(struct amdgpu_device *adev,
			struct eeprom_table_record *bps,
			struct ras_err_data *err_data)
{
	struct ta_ras_query_address_input addr_in;
	uint32_t die_id, socket = 0;

	if (adev->smuio.funcs && adev->smuio.funcs->get_socket_id)
		socket = adev->smuio.funcs->get_socket_id(adev);

	/* although die id is gotten from PA in nps1 mode, the id is
	 * fitable for any nps mode
	 */
	if (adev->umc.ras && adev->umc.ras->get_die_id_from_pa)
		die_id = adev->umc.ras->get_die_id_from_pa(adev, bps->address,
					bps->retired_page << AMDGPU_GPU_PAGE_SHIFT);
	else
		return -EINVAL;

	/* reinit err_data */
	err_data->err_addr_cnt = 0;
	err_data->err_addr_len = adev->umc.retire_unit;

	memset(&addr_in, 0, sizeof(addr_in));
	addr_in.ma.err_addr = bps->address;
	addr_in.ma.ch_inst = bps->mem_channel;
	addr_in.ma.umc_inst = bps->mcumc_id;
	addr_in.ma.node_inst = die_id;
	addr_in.ma.socket_id = socket;

	if (adev->umc.ras && adev->umc.ras->convert_ras_err_addr)
		return adev->umc.ras->convert_ras_err_addr(adev, err_data,
					&addr_in, NULL, false);
	else
		return  -EINVAL;
}

static int __amdgpu_ras_restore_bad_pages(struct amdgpu_device *adev,
					struct eeprom_table_record *bps, int count)
{
	int j;
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_handler_data *data = con->eh_data;

	for (j = 0; j < count; j++) {
		if (amdgpu_ras_check_bad_page_unlock(con,
			bps[j].retired_page << AMDGPU_GPU_PAGE_SHIFT))
			continue;

		if (!data->space_left &&
		    amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
			return -ENOMEM;
		}

		amdgpu_ras_reserve_page(adev, bps[j].retired_page);

		memcpy(&data->bps[data->count], &(bps[j]),
				sizeof(struct eeprom_table_record));
		data->count++;
		data->space_left--;
	}

	return 0;
}

static int __amdgpu_ras_convert_rec_array_from_rom(struct amdgpu_device *adev,
				struct eeprom_table_record *bps, struct ras_err_data *err_data,
				enum amdgpu_memory_partition nps)
{
	int i = 0;
	enum amdgpu_memory_partition save_nps;

	save_nps = (bps[0].retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;

	/*old asics just have pa in eeprom*/
	if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) < 12) {
		memcpy(err_data->err_addr, bps,
			sizeof(struct eeprom_table_record) * adev->umc.retire_unit);
		goto out;
	}

	for (i = 0; i < adev->umc.retire_unit; i++)
		bps[i].retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);

	if (save_nps) {
		if (save_nps == nps) {
			if (amdgpu_umc_pages_in_a_row(adev, err_data,
					bps[0].retired_page << AMDGPU_GPU_PAGE_SHIFT))
				return -EINVAL;
		} else {
			if (amdgpu_ras_mca2pa_by_idx(adev, &bps[0], err_data))
				return -EINVAL;
		}
	} else {
		if (amdgpu_ras_mca2pa(adev, &bps[0], err_data)) {
			if (nps == AMDGPU_NPS1_PARTITION_MODE)
				memcpy(err_data->err_addr, bps,
					sizeof(struct eeprom_table_record) * adev->umc.retire_unit);
			else
				return -EOPNOTSUPP;
		}
	}

out:
	return __amdgpu_ras_restore_bad_pages(adev, err_data->err_addr, adev->umc.retire_unit);
}

static int __amdgpu_ras_convert_rec_from_rom(struct amdgpu_device *adev,
				struct eeprom_table_record *bps, struct ras_err_data *err_data,
				enum amdgpu_memory_partition nps)
{
	enum amdgpu_memory_partition save_nps;

	save_nps = (bps->retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;
	bps->retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);

	if (save_nps == nps) {
		if (amdgpu_umc_pages_in_a_row(adev, err_data,
				bps->retired_page << AMDGPU_GPU_PAGE_SHIFT))
			return -EINVAL;
	} else {
		if (amdgpu_ras_mca2pa_by_idx(adev, bps, err_data))
			return -EINVAL;
	}
	return __amdgpu_ras_restore_bad_pages(adev, err_data->err_addr,
									adev->umc.retire_unit);
}

/* it deal with vram only. */
int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
		struct eeprom_table_record *bps, int pages, bool from_rom)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_data err_data;
	struct amdgpu_ras_eeprom_control *control =
			&adev->psp.ras_context.ras->eeprom_control;
	enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE;
	int ret = 0;
	uint32_t i;

	if (!con || !con->eh_data || !bps || pages <= 0)
		return 0;

	if (from_rom) {
		err_data.err_addr =
			kcalloc(adev->umc.retire_unit,
				sizeof(struct eeprom_table_record), GFP_KERNEL);
		if (!err_data.err_addr) {
			dev_warn(adev->dev, "Failed to alloc UMC error address record in mca2pa conversion!\n");
			return -ENOMEM;
		}

		if (adev->gmc.gmc_funcs->query_mem_partition_mode)
			nps = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
	}

	mutex_lock(&con->recovery_lock);

	if (from_rom) {
		for (i = 0; i < pages; i++) {
			if (control->ras_num_recs - i >= adev->umc.retire_unit) {
				if ((bps[i].address == bps[i + 1].address) &&
				    (bps[i].mem_channel == bps[i + 1].mem_channel)) {
					//deal with retire_unit records a time
					ret = __amdgpu_ras_convert_rec_array_from_rom(adev,
									&bps[i], &err_data, nps);
					if (ret)
						goto free;
					i += (adev->umc.retire_unit - 1);
				} else {
					break;
				}
			} else {
				break;
			}
		}
		for (; i < pages; i++) {
			ret = __amdgpu_ras_convert_rec_from_rom(adev,
				&bps[i], &err_data, nps);
			if (ret)
				goto free;
		}
	} else {
		ret = __amdgpu_ras_restore_bad_pages(adev, bps, pages);
	}

free:
	if (from_rom)
		kfree(err_data.err_addr);
	mutex_unlock(&con->recovery_lock);

	return ret;
}

/*
 * write error record array to eeprom, the function should be
 * protected by recovery_lock
 * new_cnt: new added UE count, excluding reserved bad pages, can be NULL
 */
int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev,
		unsigned long *new_cnt)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_handler_data *data;
	struct amdgpu_ras_eeprom_control *control;
	int save_count, unit_num, bad_page_num, i;

	if (!con || !con->eh_data) {
		if (new_cnt)
			*new_cnt = 0;

		return 0;
	}

	mutex_lock(&con->recovery_lock);
	control = &con->eeprom_control;
	data = con->eh_data;
	bad_page_num = control->ras_num_bad_pages;
	save_count = data->count - bad_page_num;
	mutex_unlock(&con->recovery_lock);

	unit_num = save_count / adev->umc.retire_unit;
	if (new_cnt)
		*new_cnt = unit_num;

	/* only new entries are saved */
	if (save_count > 0) {
		/*old asics only save pa to eeprom like before*/
		if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) < 12) {
			if (amdgpu_ras_eeprom_append(control,
					&data->bps[bad_page_num], save_count)) {
				dev_err(adev->dev, "Failed to save EEPROM table data!");
				return -EIO;
			}
		} else {
			for (i = 0; i < unit_num; i++) {
				if (amdgpu_ras_eeprom_append(control,
						&data->bps[bad_page_num +
						i * adev->umc.retire_unit], 1)) {
					dev_err(adev->dev, "Failed to save EEPROM table data!");
					return -EIO;
				}
			}
		}

		dev_info(adev->dev, "Saved %d pages to EEPROM table.\n", save_count);
	}

	return 0;
}

/*
 * read error record array in eeprom and reserve enough space for
 * storing new bad pages
 */
static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev)
{
	struct amdgpu_ras_eeprom_control *control =
		&adev->psp.ras_context.ras->eeprom_control;
	struct eeprom_table_record *bps;
	int ret, i = 0;

	/* no bad page record, skip eeprom access */
	if (control->ras_num_recs == 0 || amdgpu_bad_page_threshold == 0)
		return 0;

	bps = kcalloc(control->ras_num_recs, sizeof(*bps), GFP_KERNEL);
	if (!bps)
		return -ENOMEM;

	ret = amdgpu_ras_eeprom_read(control, bps, control->ras_num_recs);
	if (ret) {
		dev_err(adev->dev, "Failed to load EEPROM table records!");
	} else {
		if (adev->umc.ras && adev->umc.ras->convert_ras_err_addr) {
			for (i = 0; i < control->ras_num_recs; i++) {
				if ((control->ras_num_recs - i) >= adev->umc.retire_unit) {
					if ((bps[i].address == bps[i + 1].address) &&
						(bps[i].mem_channel == bps[i + 1].mem_channel)) {
						control->ras_num_pa_recs += adev->umc.retire_unit;
						i += (adev->umc.retire_unit - 1);
					} else {
						control->ras_num_mca_recs +=
									(control->ras_num_recs - i);
						break;
					}
				} else {
					control->ras_num_mca_recs += (control->ras_num_recs - i);
					break;
				}
			}
		}

		ret = amdgpu_ras_eeprom_check(control);
		if (ret)
			goto out;

		/* HW not usable */
		if (amdgpu_ras_is_rma(adev)) {
			ret = -EHWPOISON;
			goto out;
		}

		ret = amdgpu_ras_add_bad_pages(adev, bps, control->ras_num_recs, true);
	}

out:
	kfree(bps);
	return ret;
}

static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
				uint64_t addr)
{
	struct ras_err_handler_data *data = con->eh_data;
	int i;

	addr >>= AMDGPU_GPU_PAGE_SHIFT;
	for (i = 0; i < data->count; i++)
		if (addr == data->bps[i].retired_page)
			return true;

	return false;
}

/*
 * check if an address belongs to bad page
 *
 * Note: this check is only for umc block
 */
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
				uint64_t addr)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	bool ret = false;

	if (!con || !con->eh_data)
		return ret;

	mutex_lock(&con->recovery_lock);
	ret = amdgpu_ras_check_bad_page_unlock(con, addr);
	mutex_unlock(&con->recovery_lock);
	return ret;
}

static void amdgpu_ras_validate_threshold(struct amdgpu_device *adev,
					  uint32_t max_count)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	/*
	 * amdgpu_bad_page_threshold is used to config
	 * the threshold for the number of bad pages.
	 * -1:  Threshold is set to default value
	 *      Driver will issue a warning message when threshold is reached
	 *      and continue runtime services.
	 * 0:   Disable bad page retirement
	 *      Driver will not retire bad pages
	 *      which is intended for debugging purpose.
	 * -2:  Threshold is determined by a formula
	 *      that assumes 1 bad page per 100M of local memory.
	 *      Driver will continue runtime services when threhold is reached.
	 * 0 < threshold < max number of bad page records in EEPROM,
	 *      A user-defined threshold is set
	 *      Driver will halt runtime services when this custom threshold is reached.
	 */
	if (amdgpu_bad_page_threshold == -2) {
		u64 val = adev->gmc.mc_vram_size;

		do_div(val, RAS_BAD_PAGE_COVER);
		con->bad_page_cnt_threshold = min(lower_32_bits(val),
						  max_count);
	} else if (amdgpu_bad_page_threshold == -1) {
		con->bad_page_cnt_threshold = ((con->reserved_pages_in_bytes) >> 21) << 4;
	} else {
		con->bad_page_cnt_threshold = min_t(int, max_count,
						    amdgpu_bad_page_threshold);
	}
}

int amdgpu_ras_put_poison_req(struct amdgpu_device *adev,
		enum amdgpu_ras_block block, uint16_t pasid,
		pasid_notify pasid_fn, void *data, uint32_t reset)
{
	int ret = 0;
	struct ras_poison_msg poison_msg;
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	memset(&poison_msg, 0, sizeof(poison_msg));
	poison_msg.block = block;
	poison_msg.pasid = pasid;
	poison_msg.reset = reset;
	poison_msg.pasid_fn = pasid_fn;
	poison_msg.data = data;

	ret = kfifo_put(&con->poison_fifo, poison_msg);
	if (!ret) {
		dev_err(adev->dev, "Poison message fifo is full!\n");
		return -ENOSPC;
	}

	return 0;
}

static int amdgpu_ras_get_poison_req(struct amdgpu_device *adev,
		struct ras_poison_msg *poison_msg)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	return kfifo_get(&con->poison_fifo, poison_msg);
}

static void amdgpu_ras_ecc_log_init(struct ras_ecc_log_info *ecc_log)
{
	mutex_init(&ecc_log->lock);

	INIT_RADIX_TREE(&ecc_log->de_page_tree, GFP_KERNEL);
	ecc_log->de_queried_count = 0;
	ecc_log->prev_de_queried_count = 0;
}

static void amdgpu_ras_ecc_log_fini(struct ras_ecc_log_info *ecc_log)
{
	struct radix_tree_iter iter;
	void __rcu **slot;
	struct ras_ecc_err *ecc_err;

	mutex_lock(&ecc_log->lock);
	radix_tree_for_each_slot(slot, &ecc_log->de_page_tree, &iter, 0) {
		ecc_err = radix_tree_deref_slot(slot);
		kfree(ecc_err->err_pages.pfn);
		kfree(ecc_err);
		radix_tree_iter_delete(&ecc_log->de_page_tree, &iter, slot);
	}
	mutex_unlock(&ecc_log->lock);

	mutex_destroy(&ecc_log->lock);
	ecc_log->de_queried_count = 0;
	ecc_log->prev_de_queried_count = 0;
}

static bool amdgpu_ras_schedule_retirement_dwork(struct amdgpu_ras *con,
				uint32_t delayed_ms)
{
	int ret;

	mutex_lock(&con->umc_ecc_log.lock);
	ret = radix_tree_tagged(&con->umc_ecc_log.de_page_tree,
			UMC_ECC_NEW_DETECTED_TAG);
	mutex_unlock(&con->umc_ecc_log.lock);

	if (ret)
		schedule_delayed_work(&con->page_retirement_dwork,
			msecs_to_jiffies(delayed_ms));

	return ret ? true : false;
}

static void amdgpu_ras_do_page_retirement(struct work_struct *work)
{
	struct amdgpu_ras *con = container_of(work, struct amdgpu_ras,
					      page_retirement_dwork.work);
	struct amdgpu_device *adev = con->adev;
	struct ras_err_data err_data;
	unsigned long err_cnt;

	/* If gpu reset is ongoing, delay retiring the bad pages */
	if (amdgpu_in_reset(adev) || amdgpu_ras_in_recovery(adev)) {
		amdgpu_ras_schedule_retirement_dwork(con,
				AMDGPU_RAS_RETIRE_PAGE_INTERVAL * 3);
		return;
	}

	amdgpu_ras_error_data_init(&err_data);

	amdgpu_umc_handle_bad_pages(adev, &err_data);
	err_cnt = err_data.err_addr_cnt;

	amdgpu_ras_error_data_fini(&err_data);

	if (err_cnt && amdgpu_ras_is_rma(adev))
		amdgpu_ras_reset_gpu(adev);

	amdgpu_ras_schedule_retirement_dwork(con,
			AMDGPU_RAS_RETIRE_PAGE_INTERVAL);
}

static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev,
				uint32_t poison_creation_count)
{
	int ret = 0;
	struct ras_ecc_log_info *ecc_log;
	struct ras_query_if info;
	uint32_t timeout = 0;
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
	uint64_t de_queried_count;
	uint32_t new_detect_count, total_detect_count;
	uint32_t need_query_count = poison_creation_count;
	bool query_data_timeout = false;
	enum ras_event_type type = RAS_EVENT_TYPE_POISON_CREATION;

	memset(&info, 0, sizeof(info));
	info.head.block = AMDGPU_RAS_BLOCK__UMC;

	ecc_log = &ras->umc_ecc_log;
	total_detect_count = 0;
	do {
		ret = amdgpu_ras_query_error_status_with_event(adev, &info, type);
		if (ret)
			return ret;

		de_queried_count = ecc_log->de_queried_count;
		if (de_queried_count > ecc_log->prev_de_queried_count) {
			new_detect_count = de_queried_count - ecc_log->prev_de_queried_count;
			ecc_log->prev_de_queried_count = de_queried_count;
			timeout = 0;
		} else {
			new_detect_count = 0;
		}

		if (new_detect_count) {
			total_detect_count += new_detect_count;
		} else {
			if (!timeout && need_query_count)
				timeout = MAX_UMC_POISON_POLLING_TIME_ASYNC;

			if (timeout) {
				if (!--timeout) {
					query_data_timeout = true;
					break;
				}
				msleep(1);
			}
		}
	} while (total_detect_count < need_query_count);

	if (query_data_timeout) {
		dev_warn(adev->dev, "Can't find deferred error! count: %u\n",
			(need_query_count - total_detect_count));
		return -ENOENT;
	}

	if (total_detect_count)
		schedule_delayed_work(&ras->page_retirement_dwork, 0);

	return 0;
}

static void amdgpu_ras_clear_poison_fifo(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_poison_msg msg;
	int ret;

	do {
		ret = kfifo_get(&con->poison_fifo, &msg);
	} while (ret);
}

static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev,
			uint32_t msg_count, uint32_t *gpu_reset)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	uint32_t reset_flags = 0, reset = 0;
	struct ras_poison_msg msg;
	int ret, i;

	kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);

	for (i = 0; i < msg_count; i++) {
		ret = amdgpu_ras_get_poison_req(adev, &msg);
		if (!ret)
			continue;

		if (msg.pasid_fn)
			msg.pasid_fn(adev, msg.pasid, msg.data);

		reset_flags |= msg.reset;
	}

	/* for RMA, amdgpu_ras_poison_creation_handler will trigger gpu reset */
	if (reset_flags && !amdgpu_ras_is_rma(adev)) {
		if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET)
			reset = AMDGPU_RAS_GPU_RESET_MODE1_RESET;
		else if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE2_RESET)
			reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET;
		else
			reset = reset_flags;

		flush_delayed_work(&con->page_retirement_dwork);

		con->gpu_reset_flags |= reset;
		amdgpu_ras_reset_gpu(adev);

		*gpu_reset = reset;

		/* Wait for gpu recovery to complete */
		flush_work(&con->recovery_work);
	}

	return 0;
}

static int amdgpu_ras_page_retirement_thread(void *param)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)param;
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	uint32_t poison_creation_count, msg_count;
	uint32_t gpu_reset;
	int ret;

	while (!kthread_should_stop()) {

		wait_event_interruptible(con->page_retirement_wq,
				kthread_should_stop() ||
				atomic_read(&con->page_retirement_req_cnt));

		if (kthread_should_stop())
			break;

		gpu_reset = 0;

		do {
			poison_creation_count = atomic_read(&con->poison_creation_count);
			ret = amdgpu_ras_poison_creation_handler(adev, poison_creation_count);
			if (ret == -EIO)
				break;

			if (poison_creation_count) {
				atomic_sub(poison_creation_count, &con->poison_creation_count);
				atomic_sub(poison_creation_count, &con->page_retirement_req_cnt);
			}
		} while (atomic_read(&con->poison_creation_count));

		if (ret != -EIO) {
			msg_count = kfifo_len(&con->poison_fifo);
			if (msg_count) {
				ret = amdgpu_ras_poison_consumption_handler(adev,
						msg_count, &gpu_reset);
				if ((ret != -EIO) &&
				    (gpu_reset != AMDGPU_RAS_GPU_RESET_MODE1_RESET))
					atomic_sub(msg_count, &con->page_retirement_req_cnt);
			}
		}

		if ((ret == -EIO) || (gpu_reset == AMDGPU_RAS_GPU_RESET_MODE1_RESET)) {
			/* gpu mode-1 reset is ongoing or just completed ras mode-1 reset */
			/* Clear poison creation request */
			atomic_set(&con->poison_creation_count, 0);

			/* Clear poison fifo */
			amdgpu_ras_clear_poison_fifo(adev);

			/* Clear all poison requests */
			atomic_set(&con->page_retirement_req_cnt, 0);

			if (ret == -EIO) {
				/* Wait for mode-1 reset to complete */
				down_read(&adev->reset_domain->sem);
				up_read(&adev->reset_domain->sem);
			}

			/* Wake up work to save bad pages to eeprom */
			schedule_delayed_work(&con->page_retirement_dwork, 0);
		} else if (gpu_reset) {
			/* gpu just completed mode-2 reset or other reset */
			/* Clear poison consumption messages cached in fifo */
			msg_count = kfifo_len(&con->poison_fifo);
			if (msg_count) {
				amdgpu_ras_clear_poison_fifo(adev);
				atomic_sub(msg_count, &con->page_retirement_req_cnt);
			}

			/* Wake up work to save bad pages to eeprom */
			schedule_delayed_work(&con->page_retirement_dwork, 0);
		}
	}

	return 0;
}

int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct amdgpu_ras_eeprom_control *control;
	int ret;

	if (!con || amdgpu_sriov_vf(adev))
		return 0;

	control = &con->eeprom_control;
	ret = amdgpu_ras_eeprom_init(control);
	if (ret)
		return ret;

	if (!adev->umc.ras || !adev->umc.ras->convert_ras_err_addr)
		control->ras_num_pa_recs = control->ras_num_recs;

	if (control->ras_num_recs) {
		ret = amdgpu_ras_load_bad_pages(adev);
		if (ret)
			return ret;

		amdgpu_dpm_send_hbm_bad_pages_num(
			adev, control->ras_num_bad_pages);

		if (con->update_channel_flag == true) {
			amdgpu_dpm_send_hbm_bad_channel_flag(
				adev, control->bad_channel_bitmap);
			con->update_channel_flag = false;
		}

		/* The format action is only applied to new ASICs */
		if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) >= 12 &&
		    control->tbl_hdr.version < RAS_TABLE_VER_V3)
			if (!amdgpu_ras_eeprom_reset_table(control))
				if (amdgpu_ras_save_bad_pages(adev, NULL))
					dev_warn(adev->dev, "Failed to format RAS EEPROM data in V3 version!\n");
	}

	return ret;
}

int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_handler_data **data;
	u32  max_eeprom_records_count = 0;
	int ret;

	if (!con || amdgpu_sriov_vf(adev))
		return 0;

	/* Allow access to RAS EEPROM via debugfs, when the ASIC
	 * supports RAS and debugfs is enabled, but when
	 * adev->ras_enabled is unset, i.e. when "ras_enable"
	 * module parameter is set to 0.
	 */
	con->adev = adev;

	if (!adev->ras_enabled)
		return 0;

	data = &con->eh_data;
	*data = kzalloc(sizeof(**data), GFP_KERNEL);
	if (!*data) {
		ret = -ENOMEM;
		goto out;
	}

	mutex_init(&con->recovery_lock);
	INIT_WORK(&con->recovery_work, amdgpu_ras_do_recovery);
	atomic_set(&con->in_recovery, 0);
	con->eeprom_control.bad_channel_bitmap = 0;

	max_eeprom_records_count = amdgpu_ras_eeprom_max_record_count(&con->eeprom_control);
	amdgpu_ras_validate_threshold(adev, max_eeprom_records_count);

	if (init_bp_info) {
		ret = amdgpu_ras_init_badpage_info(adev);
		if (ret)
			goto free;
	}

	mutex_init(&con->page_rsv_lock);
	INIT_KFIFO(con->poison_fifo);
	mutex_init(&con->page_retirement_lock);
	init_waitqueue_head(&con->page_retirement_wq);
	atomic_set(&con->page_retirement_req_cnt, 0);
	atomic_set(&con->poison_creation_count, 0);
	con->page_retirement_thread =
		kthread_run(amdgpu_ras_page_retirement_thread, adev, "umc_page_retirement");
	if (IS_ERR(con->page_retirement_thread)) {
		con->page_retirement_thread = NULL;
		dev_warn(adev->dev, "Failed to create umc_page_retirement thread!!!\n");
	}

	INIT_DELAYED_WORK(&con->page_retirement_dwork, amdgpu_ras_do_page_retirement);
	amdgpu_ras_ecc_log_init(&con->umc_ecc_log);
#ifdef CONFIG_X86_MCE_AMD
	if ((adev->asic_type == CHIP_ALDEBARAN) &&
	    (adev->gmc.xgmi.connected_to_cpu))
		amdgpu_register_bad_pages_mca_notifier(adev);
#endif
	return 0;

free:
	kfree((*data)->bps);
	kfree(*data);
	con->eh_data = NULL;
out:
	dev_warn(adev->dev, "Failed to initialize ras recovery! (%d)\n", ret);

	/*
	 * Except error threshold exceeding case, other failure cases in this
	 * function would not fail amdgpu driver init.
	 */
	if (!amdgpu_ras_is_rma(adev))
		ret = 0;
	else
		ret = -EINVAL;

	return ret;
}

static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_err_handler_data *data = con->eh_data;
	int max_flush_timeout = MAX_FLUSH_RETIRE_DWORK_TIMES;
	bool ret;

	/* recovery_init failed to init it, fini is useless */
	if (!data)
		return 0;

	/* Save all cached bad pages to eeprom */
	do {
		flush_delayed_work(&con->page_retirement_dwork);
		ret = amdgpu_ras_schedule_retirement_dwork(con, 0);
	} while (ret && max_flush_timeout--);

	if (con->page_retirement_thread)
		kthread_stop(con->page_retirement_thread);

	atomic_set(&con->page_retirement_req_cnt, 0);
	atomic_set(&con->poison_creation_count, 0);

	mutex_destroy(&con->page_rsv_lock);

	cancel_work_sync(&con->recovery_work);

	cancel_delayed_work_sync(&con->page_retirement_dwork);

	amdgpu_ras_ecc_log_fini(&con->umc_ecc_log);

	mutex_lock(&con->recovery_lock);
	con->eh_data = NULL;
	kfree(data->bps);
	kfree(data);
	mutex_unlock(&con->recovery_lock);

	return 0;
}
/* recovery end */

static bool amdgpu_ras_asic_supported(struct amdgpu_device *adev)
{
	if (amdgpu_sriov_vf(adev)) {
		switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
		case IP_VERSION(13, 0, 2):
		case IP_VERSION(13, 0, 6):
		case IP_VERSION(13, 0, 12):
		case IP_VERSION(13, 0, 14):
			return true;
		default:
			return false;
		}
	}

	if (adev->asic_type == CHIP_IP_DISCOVERY) {
		switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
		case IP_VERSION(13, 0, 0):
		case IP_VERSION(13, 0, 6):
		case IP_VERSION(13, 0, 10):
		case IP_VERSION(13, 0, 12):
		case IP_VERSION(13, 0, 14):
		case IP_VERSION(14, 0, 3):
			return true;
		default:
			return false;
		}
	}

	return adev->asic_type == CHIP_VEGA10 ||
		adev->asic_type == CHIP_VEGA20 ||
		adev->asic_type == CHIP_ARCTURUS ||
		adev->asic_type == CHIP_ALDEBARAN ||
		adev->asic_type == CHIP_SIENNA_CICHLID;
}

/*
 * this is workaround for vega20 workstation sku,
 * force enable gfx ras, ignore vbios gfx ras flag
 * due to GC EDC can not write
 */
static void amdgpu_ras_get_quirks(struct amdgpu_device *adev)
{
	struct atom_context *ctx = adev->mode_info.atom_context;

	if (!ctx)
		return;

	if (strnstr(ctx->vbios_pn, "D16406",
		    sizeof(ctx->vbios_pn)) ||
		strnstr(ctx->vbios_pn, "D36002",
			sizeof(ctx->vbios_pn)))
		adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__GFX);
}

/* Query ras capablity via atomfirmware interface */
static void amdgpu_ras_query_ras_capablity_from_vbios(struct amdgpu_device *adev)
{
	/* mem_ecc cap */
	if (amdgpu_atomfirmware_mem_ecc_supported(adev)) {
		dev_info(adev->dev, "MEM ECC is active.\n");
		adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__UMC |
					 1 << AMDGPU_RAS_BLOCK__DF);
	} else {
		dev_info(adev->dev, "MEM ECC is not presented.\n");
	}

	/* sram_ecc cap */
	if (amdgpu_atomfirmware_sram_ecc_supported(adev)) {
		dev_info(adev->dev, "SRAM ECC is active.\n");
		if (!amdgpu_sriov_vf(adev))
			adev->ras_hw_enabled |= ~(1 << AMDGPU_RAS_BLOCK__UMC |
						  1 << AMDGPU_RAS_BLOCK__DF);
		else
			adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__PCIE_BIF |
						 1 << AMDGPU_RAS_BLOCK__SDMA |
						 1 << AMDGPU_RAS_BLOCK__GFX);

		/*
		 * VCN/JPEG RAS can be supported on both bare metal and
		 * SRIOV environment
		 */
		if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(2, 6, 0) ||
		    amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(4, 0, 0) ||
		    amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(4, 0, 3))
			adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__VCN |
						 1 << AMDGPU_RAS_BLOCK__JPEG);
		else
			adev->ras_hw_enabled &= ~(1 << AMDGPU_RAS_BLOCK__VCN |
						  1 << AMDGPU_RAS_BLOCK__JPEG);

		/*
		 * XGMI RAS is not supported if xgmi num physical nodes
		 * is zero
		 */
		if (!adev->gmc.xgmi.num_physical_nodes)
			adev->ras_hw_enabled &= ~(1 << AMDGPU_RAS_BLOCK__XGMI_WAFL);
	} else {
		dev_info(adev->dev, "SRAM ECC is not presented.\n");
	}
}

/* Query poison mode from umc/df IP callbacks */
static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	bool df_poison, umc_poison;

	/* poison setting is useless on SRIOV guest */
	if (amdgpu_sriov_vf(adev) || !con)
		return;

	/* Init poison supported flag, the default value is false */
	if (adev->gmc.xgmi.connected_to_cpu ||
	    adev->gmc.is_app_apu) {
		/* enabled by default when GPU is connected to CPU */
		con->poison_supported = true;
	} else if (adev->df.funcs &&
	    adev->df.funcs->query_ras_poison_mode &&
	    adev->umc.ras &&
	    adev->umc.ras->query_ras_poison_mode) {
		df_poison =
			adev->df.funcs->query_ras_poison_mode(adev);
		umc_poison =
			adev->umc.ras->query_ras_poison_mode(adev);

		/* Only poison is set in both DF and UMC, we can support it */
		if (df_poison && umc_poison)
			con->poison_supported = true;
		else if (df_poison != umc_poison)
			dev_warn(adev->dev,
				"Poison setting is inconsistent in DF/UMC(%d:%d)!\n",
				df_poison, umc_poison);
	}
}

/*
 * check hardware's ras ability which will be saved in hw_supported.
 * if hardware does not support ras, we can skip some ras initializtion and
 * forbid some ras operations from IP.
 * if software itself, say boot parameter, limit the ras ability. We still
 * need allow IP do some limited operations, like disable. In such case,
 * we have to initialize ras as normal. but need check if operation is
 * allowed or not in each function.
 */
static void amdgpu_ras_check_supported(struct amdgpu_device *adev)
{
	adev->ras_hw_enabled = adev->ras_enabled = 0;

	if (!amdgpu_ras_asic_supported(adev))
		return;

	if (amdgpu_sriov_vf(adev)) {
		if (amdgpu_virt_get_ras_capability(adev))
			goto init_ras_enabled_flag;
	}

	/* query ras capability from psp */
	if (amdgpu_psp_get_ras_capability(&adev->psp))
		goto init_ras_enabled_flag;

	/* query ras capablity from bios */
	if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu) {
		amdgpu_ras_query_ras_capablity_from_vbios(adev);
	} else {
		/* driver only manages a few IP blocks RAS feature
		 * when GPU is connected cpu through XGMI */
		adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__GFX |
					   1 << AMDGPU_RAS_BLOCK__SDMA |
					   1 << AMDGPU_RAS_BLOCK__MMHUB);
	}

	/* apply asic specific settings (vega20 only for now) */
	amdgpu_ras_get_quirks(adev);

	/* query poison mode from umc/df ip callback */
	amdgpu_ras_query_poison_mode(adev);

init_ras_enabled_flag:
	/* hw_supported needs to be aligned with RAS block mask. */
	adev->ras_hw_enabled &= AMDGPU_RAS_BLOCK_MASK;

	adev->ras_enabled = amdgpu_ras_enable == 0 ? 0 :
		adev->ras_hw_enabled & amdgpu_ras_mask;

	/* aca is disabled by default except for psp v13_0_6/v13_0_12/v13_0_14 */
	adev->aca.is_enabled =
		(amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) ||
		 amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) ||
		 amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14));

	/* bad page feature is not applicable to specific app platform */
	if (adev->gmc.is_app_apu &&
	    amdgpu_ip_version(adev, UMC_HWIP, 0) == IP_VERSION(12, 0, 0))
		amdgpu_bad_page_threshold = 0;
}

static void amdgpu_ras_counte_dw(struct work_struct *work)
{
	struct amdgpu_ras *con = container_of(work, struct amdgpu_ras,
					      ras_counte_delay_work.work);
	struct amdgpu_device *adev = con->adev;
	struct drm_device *dev = adev_to_drm(adev);
	unsigned long ce_count, ue_count;
	int res;

	res = pm_runtime_get_sync(dev->dev);
	if (res < 0)
		goto Out;

	/* Cache new values.
	 */
	if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, NULL) == 0) {
		atomic_set(&con->ras_ce_count, ce_count);
		atomic_set(&con->ras_ue_count, ue_count);
	}

	pm_runtime_mark_last_busy(dev->dev);
Out:
	pm_runtime_put_autosuspend(dev->dev);
}

static int amdgpu_get_ras_schema(struct amdgpu_device *adev)
{
	return  amdgpu_ras_is_poison_mode_supported(adev) ? AMDGPU_RAS_ERROR__POISON : 0 |
			AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE |
			AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE |
			AMDGPU_RAS_ERROR__PARITY;
}

static void ras_event_mgr_init(struct ras_event_manager *mgr)
{
	struct ras_event_state *event_state;
	int i;

	memset(mgr, 0, sizeof(*mgr));
	atomic64_set(&mgr->seqno, 0);

	for (i = 0; i < ARRAY_SIZE(mgr->event_state); i++) {
		event_state = &mgr->event_state[i];
		event_state->last_seqno = RAS_EVENT_INVALID_ID;
		atomic64_set(&event_state->count, 0);
	}
}

static void amdgpu_ras_event_mgr_init(struct amdgpu_device *adev)
{
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
	struct amdgpu_hive_info *hive;

	if (!ras)
		return;

	hive = amdgpu_get_xgmi_hive(adev);
	ras->event_mgr = hive ? &hive->event_mgr : &ras->__event_mgr;

	/* init event manager with node 0 on xgmi system */
	if (!amdgpu_reset_in_recovery(adev)) {
		if (!hive || adev->gmc.xgmi.node_id == 0)
			ras_event_mgr_init(ras->event_mgr);
	}

	if (hive)
		amdgpu_put_xgmi_hive(hive);
}

static void amdgpu_ras_init_reserved_vram_size(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!con || (adev->flags & AMD_IS_APU))
		return;

	switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
	case IP_VERSION(13, 0, 2):
	case IP_VERSION(13, 0, 6):
	case IP_VERSION(13, 0, 12):
		con->reserved_pages_in_bytes = AMDGPU_RAS_RESERVED_VRAM_SIZE_DEFAULT;
		break;
	case IP_VERSION(13, 0, 14):
		con->reserved_pages_in_bytes = (AMDGPU_RAS_RESERVED_VRAM_SIZE_DEFAULT << 1);
		break;
	default:
		break;
	}
}

int amdgpu_ras_init(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	int r;

	if (con)
		return 0;

	con = kzalloc(sizeof(*con) +
			sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT +
			sizeof(struct ras_manager) * AMDGPU_RAS_MCA_BLOCK_COUNT,
			GFP_KERNEL);
	if (!con)
		return -ENOMEM;

	con->adev = adev;
	INIT_DELAYED_WORK(&con->ras_counte_delay_work, amdgpu_ras_counte_dw);
	atomic_set(&con->ras_ce_count, 0);
	atomic_set(&con->ras_ue_count, 0);

	con->objs = (struct ras_manager *)(con + 1);

	amdgpu_ras_set_context(adev, con);

	amdgpu_ras_check_supported(adev);

	if (!adev->ras_enabled || adev->asic_type == CHIP_VEGA10) {
		/* set gfx block ras context feature for VEGA20 Gaming
		 * send ras disable cmd to ras ta during ras late init.
		 */
		if (!adev->ras_enabled && adev->asic_type == CHIP_VEGA20) {
			con->features |= BIT(AMDGPU_RAS_BLOCK__GFX);

			return 0;
		}

		r = 0;
		goto release_con;
	}

	con->update_channel_flag = false;
	con->features = 0;
	con->schema = 0;
	INIT_LIST_HEAD(&con->head);
	/* Might need get this flag from vbios. */
	con->flags = RAS_DEFAULT_FLAGS;

	/* initialize nbio ras function ahead of any other
	 * ras functions so hardware fatal error interrupt
	 * can be enabled as early as possible */
	switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {
	case IP_VERSION(7, 4, 0):
	case IP_VERSION(7, 4, 1):
	case IP_VERSION(7, 4, 4):
		if (!adev->gmc.xgmi.connected_to_cpu)
			adev->nbio.ras = &nbio_v7_4_ras;
		break;
	case IP_VERSION(4, 3, 0):
		if (adev->ras_hw_enabled & (1 << AMDGPU_RAS_BLOCK__DF))
			/* unlike other generation of nbio ras,
			 * nbio v4_3 only support fatal error interrupt
			 * to inform software that DF is freezed due to
			 * system fatal error event. driver should not
			 * enable nbio ras in such case. Instead,
			 * check DF RAS */
			adev->nbio.ras = &nbio_v4_3_ras;
		break;
	case IP_VERSION(6, 3, 1):
		if (adev->ras_hw_enabled & (1 << AMDGPU_RAS_BLOCK__DF))
			/* unlike other generation of nbio ras,
			 * nbif v6_3_1 only support fatal error interrupt
			 * to inform software that DF is freezed due to
			 * system fatal error event. driver should not
			 * enable nbio ras in such case. Instead,
			 * check DF RAS
			 */
			adev->nbio.ras = &nbif_v6_3_1_ras;
		break;
	case IP_VERSION(7, 9, 0):
	case IP_VERSION(7, 9, 1):
		if (!adev->gmc.is_app_apu)
			adev->nbio.ras = &nbio_v7_9_ras;
		break;
	default:
		/* nbio ras is not available */
		break;
	}

	/* nbio ras block needs to be enabled ahead of other ras blocks
	 * to handle fatal error */
	r = amdgpu_nbio_ras_sw_init(adev);
	if (r)
		return r;

	if (adev->nbio.ras &&
	    adev->nbio.ras->init_ras_controller_interrupt) {
		r = adev->nbio.ras->init_ras_controller_interrupt(adev);
		if (r)
			goto release_con;
	}

	if (adev->nbio.ras &&
	    adev->nbio.ras->init_ras_err_event_athub_interrupt) {
		r = adev->nbio.ras->init_ras_err_event_athub_interrupt(adev);
		if (r)
			goto release_con;
	}

	/* Packed socket_id to ras feature mask bits[31:29] */
	if (adev->smuio.funcs &&
	    adev->smuio.funcs->get_socket_id)
		con->features |= ((adev->smuio.funcs->get_socket_id(adev)) <<
					AMDGPU_RAS_FEATURES_SOCKETID_SHIFT);

	/* Get RAS schema for particular SOC */
	con->schema = amdgpu_get_ras_schema(adev);

	amdgpu_ras_init_reserved_vram_size(adev);

	if (amdgpu_ras_fs_init(adev)) {
		r = -EINVAL;
		goto release_con;
	}

	if (amdgpu_ras_aca_is_supported(adev)) {
		if (amdgpu_aca_is_enabled(adev))
			r = amdgpu_aca_init(adev);
		else
			r = amdgpu_mca_init(adev);
		if (r)
			goto release_con;
	}

	dev_info(adev->dev, "RAS INFO: ras initialized successfully, "
		 "hardware ability[%x] ras_mask[%x]\n",
		 adev->ras_hw_enabled, adev->ras_enabled);

	return 0;
release_con:
	amdgpu_ras_set_context(adev, NULL);
	kfree(con);

	return r;
}

int amdgpu_persistent_edc_harvesting_supported(struct amdgpu_device *adev)
{
	if (adev->gmc.xgmi.connected_to_cpu ||
	    adev->gmc.is_app_apu)
		return 1;
	return 0;
}

static int amdgpu_persistent_edc_harvesting(struct amdgpu_device *adev,
					struct ras_common_if *ras_block)
{
	struct ras_query_if info = {
		.head = *ras_block,
	};

	if (!amdgpu_persistent_edc_harvesting_supported(adev))
		return 0;

	if (amdgpu_ras_query_error_status(adev, &info) != 0)
		DRM_WARN("RAS init harvest failure");

	if (amdgpu_ras_reset_error_status(adev, ras_block->block) != 0)
		DRM_WARN("RAS init harvest reset failure");

	return 0;
}

bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev)
{
       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

       if (!con)
               return false;

       return con->poison_supported;
}

/* helper function to handle common stuff in ip late init phase */
int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
			 struct ras_common_if *ras_block)
{
	struct amdgpu_ras_block_object *ras_obj = NULL;
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_query_if *query_info;
	unsigned long ue_count, ce_count;
	int r;

	/* disable RAS feature per IP block if it is not supported */
	if (!amdgpu_ras_is_supported(adev, ras_block->block)) {
		amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
		return 0;
	}

	r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1);
	if (r) {
		if (adev->in_suspend || amdgpu_reset_in_recovery(adev)) {
			/* in resume phase, if fail to enable ras,
			 * clean up all ras fs nodes, and disable ras */
			goto cleanup;
		} else
			return r;
	}

	/* check for errors on warm reset edc persisant supported ASIC */
	amdgpu_persistent_edc_harvesting(adev, ras_block);

	/* in resume phase, no need to create ras fs node */
	if (adev->in_suspend || amdgpu_reset_in_recovery(adev))
		return 0;

	ras_obj = container_of(ras_block, struct amdgpu_ras_block_object, ras_comm);
	if (ras_obj->ras_cb || (ras_obj->hw_ops &&
	    (ras_obj->hw_ops->query_poison_status ||
	    ras_obj->hw_ops->handle_poison_consumption))) {
		r = amdgpu_ras_interrupt_add_handler(adev, ras_block);
		if (r)
			goto cleanup;
	}

	if (ras_obj->hw_ops &&
	    (ras_obj->hw_ops->query_ras_error_count ||
	     ras_obj->hw_ops->query_ras_error_status)) {
		r = amdgpu_ras_sysfs_create(adev, ras_block);
		if (r)
			goto interrupt;

		/* Those are the cached values at init.
		 */
		query_info = kzalloc(sizeof(*query_info), GFP_KERNEL);
		if (!query_info)
			return -ENOMEM;
		memcpy(&query_info->head, ras_block, sizeof(struct ras_common_if));

		if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, query_info) == 0) {
			atomic_set(&con->ras_ce_count, ce_count);
			atomic_set(&con->ras_ue_count, ue_count);
		}

		kfree(query_info);
	}

	return 0;

interrupt:
	if (ras_obj->ras_cb)
		amdgpu_ras_interrupt_remove_handler(adev, ras_block);
cleanup:
	amdgpu_ras_feature_enable(adev, ras_block, 0);
	return r;
}

static int amdgpu_ras_block_late_init_default(struct amdgpu_device *adev,
			 struct ras_common_if *ras_block)
{
	return amdgpu_ras_block_late_init(adev, ras_block);
}

/* helper function to remove ras fs node and interrupt handler */
void amdgpu_ras_block_late_fini(struct amdgpu_device *adev,
			  struct ras_common_if *ras_block)
{
	struct amdgpu_ras_block_object *ras_obj;
	if (!ras_block)
		return;

	amdgpu_ras_sysfs_remove(adev, ras_block);

	ras_obj = container_of(ras_block, struct amdgpu_ras_block_object, ras_comm);
	if (ras_obj->ras_cb)
		amdgpu_ras_interrupt_remove_handler(adev, ras_block);
}

static void amdgpu_ras_block_late_fini_default(struct amdgpu_device *adev,
			  struct ras_common_if *ras_block)
{
	return amdgpu_ras_block_late_fini(adev, ras_block);
}

/* do some init work after IP late init as dependence.
 * and it runs in resume/gpu reset/booting up cases.
 */
void amdgpu_ras_resume(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct ras_manager *obj, *tmp;

	if (!adev->ras_enabled || !con) {
		/* clean ras context for VEGA20 Gaming after send ras disable cmd */
		amdgpu_release_ras_context(adev);

		return;
	}

	if (con->flags & AMDGPU_RAS_FLAG_INIT_BY_VBIOS) {
		/* Set up all other IPs which are not implemented. There is a
		 * tricky thing that IP's actual ras error type should be
		 * MULTI_UNCORRECTABLE, but as driver does not handle it, so
		 * ERROR_NONE make sense anyway.
		 */
		amdgpu_ras_enable_all_features(adev, 1);

		/* We enable ras on all hw_supported block, but as boot
		 * parameter might disable some of them and one or more IP has
		 * not implemented yet. So we disable them on behalf.
		 */
		list_for_each_entry_safe(obj, tmp, &con->head, node) {
			if (!amdgpu_ras_is_supported(adev, obj->head.block)) {
				amdgpu_ras_feature_enable(adev, &obj->head, 0);
				/* there should be no any reference. */
				WARN_ON(alive_obj(obj));
			}
		}
	}
}

void amdgpu_ras_suspend(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!adev->ras_enabled || !con)
		return;

	amdgpu_ras_disable_all_features(adev, 0);
	/* Make sure all ras objects are disabled. */
	if (AMDGPU_RAS_GET_FEATURES(con->features))
		amdgpu_ras_disable_all_features(adev, 1);
}

int amdgpu_ras_late_init(struct amdgpu_device *adev)
{
	struct amdgpu_ras_block_list *node, *tmp;
	struct amdgpu_ras_block_object *obj;
	int r;

	amdgpu_ras_event_mgr_init(adev);

	if (amdgpu_ras_aca_is_supported(adev)) {
		if (amdgpu_reset_in_recovery(adev)) {
			if (amdgpu_aca_is_enabled(adev))
				r = amdgpu_aca_reset(adev);
			else
				r = amdgpu_mca_reset(adev);
			if (r)
				return r;
		}

		if (!amdgpu_sriov_vf(adev)) {
			if (amdgpu_aca_is_enabled(adev))
				amdgpu_ras_set_aca_debug_mode(adev, false);
			else
				amdgpu_ras_set_mca_debug_mode(adev, false);
		}
	}

	/* Guest side doesn't need init ras feature */
	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_ras_telemetry_en(adev))
		return 0;

	list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {
		obj = node->ras_obj;
		if (!obj) {
			dev_warn(adev->dev, "Warning: abnormal ras list node.\n");
			continue;
		}

		if (!amdgpu_ras_is_supported(adev, obj->ras_comm.block))
			continue;

		if (obj->ras_late_init) {
			r = obj->ras_late_init(adev, &obj->ras_comm);
			if (r) {
				dev_err(adev->dev, "%s failed to execute ras_late_init! ret:%d\n",
					obj->ras_comm.name, r);
				return r;
			}
		} else
			amdgpu_ras_block_late_init_default(adev, &obj->ras_comm);
	}

	return 0;
}

/* do some fini work before IP fini as dependence */
int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!adev->ras_enabled || !con)
		return 0;


	/* Need disable ras on all IPs here before ip [hw/sw]fini */
	if (AMDGPU_RAS_GET_FEATURES(con->features))
		amdgpu_ras_disable_all_features(adev, 0);
	amdgpu_ras_recovery_fini(adev);
	return 0;
}

int amdgpu_ras_fini(struct amdgpu_device *adev)
{
	struct amdgpu_ras_block_list *ras_node, *tmp;
	struct amdgpu_ras_block_object *obj = NULL;
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!adev->ras_enabled || !con)
		return 0;

	list_for_each_entry_safe(ras_node, tmp, &adev->ras_list, node) {
		if (ras_node->ras_obj) {
			obj = ras_node->ras_obj;
			if (amdgpu_ras_is_supported(adev, obj->ras_comm.block) &&
			    obj->ras_fini)
				obj->ras_fini(adev, &obj->ras_comm);
			else
				amdgpu_ras_block_late_fini_default(adev, &obj->ras_comm);
		}

		/* Clear ras blocks from ras_list and free ras block list node */
		list_del(&ras_node->node);
		kfree(ras_node);
	}

	amdgpu_ras_fs_fini(adev);
	amdgpu_ras_interrupt_remove_all(adev);

	if (amdgpu_ras_aca_is_supported(adev)) {
		if (amdgpu_aca_is_enabled(adev))
			amdgpu_aca_fini(adev);
		else
			amdgpu_mca_fini(adev);
	}

	WARN(AMDGPU_RAS_GET_FEATURES(con->features), "Feature mask is not cleared");

	if (AMDGPU_RAS_GET_FEATURES(con->features))
		amdgpu_ras_disable_all_features(adev, 0);

	cancel_delayed_work_sync(&con->ras_counte_delay_work);

	amdgpu_ras_set_context(adev, NULL);
	kfree(con);

	return 0;
}

bool amdgpu_ras_get_fed_status(struct amdgpu_device *adev)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (!ras)
		return false;

	return test_bit(AMDGPU_RAS_BLOCK__LAST, &ras->ras_err_state);
}

void amdgpu_ras_set_fed(struct amdgpu_device *adev, bool status)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (ras) {
		if (status)
			set_bit(AMDGPU_RAS_BLOCK__LAST, &ras->ras_err_state);
		else
			clear_bit(AMDGPU_RAS_BLOCK__LAST, &ras->ras_err_state);
	}
}

void amdgpu_ras_clear_err_state(struct amdgpu_device *adev)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (ras)
		ras->ras_err_state = 0;
}

void amdgpu_ras_set_err_poison(struct amdgpu_device *adev,
			       enum amdgpu_ras_block block)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (ras)
		set_bit(block, &ras->ras_err_state);
}

bool amdgpu_ras_is_err_state(struct amdgpu_device *adev, int block)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (ras) {
		if (block == AMDGPU_RAS_BLOCK__ANY)
			return (ras->ras_err_state != 0);
		else
			return test_bit(block, &ras->ras_err_state) ||
			       test_bit(AMDGPU_RAS_BLOCK__LAST,
					&ras->ras_err_state);
	}

	return false;
}

static struct ras_event_manager *__get_ras_event_mgr(struct amdgpu_device *adev)
{
	struct amdgpu_ras *ras;

	ras = amdgpu_ras_get_context(adev);
	if (!ras)
		return NULL;

	return ras->event_mgr;
}

int amdgpu_ras_mark_ras_event_caller(struct amdgpu_device *adev, enum ras_event_type type,
				     const void *caller)
{
	struct ras_event_manager *event_mgr;
	struct ras_event_state *event_state;
	int ret = 0;

	if (type >= RAS_EVENT_TYPE_COUNT) {
		ret = -EINVAL;
		goto out;
	}

	event_mgr = __get_ras_event_mgr(adev);
	if (!event_mgr) {
		ret = -EINVAL;
		goto out;
	}

	event_state = &event_mgr->event_state[type];
	event_state->last_seqno = atomic64_inc_return(&event_mgr->seqno);
	atomic64_inc(&event_state->count);

out:
	if (ret && caller)
		dev_warn(adev->dev, "failed mark ras event (%d) in %ps, ret:%d\n",
			 (int)type, caller, ret);

	return ret;
}

u64 amdgpu_ras_acquire_event_id(struct amdgpu_device *adev, enum ras_event_type type)
{
	struct ras_event_manager *event_mgr;
	u64 id;

	if (type >= RAS_EVENT_TYPE_COUNT)
		return RAS_EVENT_INVALID_ID;

	switch (type) {
	case RAS_EVENT_TYPE_FATAL:
	case RAS_EVENT_TYPE_POISON_CREATION:
	case RAS_EVENT_TYPE_POISON_CONSUMPTION:
		event_mgr = __get_ras_event_mgr(adev);
		if (!event_mgr)
			return RAS_EVENT_INVALID_ID;

		id = event_mgr->event_state[type].last_seqno;
		break;
	case RAS_EVENT_TYPE_INVALID:
	default:
		id = RAS_EVENT_INVALID_ID;
		break;
	}

	return id;
}

void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
{
	if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) {
		struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
		enum ras_event_type type = RAS_EVENT_TYPE_FATAL;
		u64 event_id;

		if (amdgpu_ras_mark_ras_event(adev, type))
			return;

		event_id = amdgpu_ras_acquire_event_id(adev, type);

		RAS_EVENT_LOG(adev, event_id, "uncorrectable hardware error"
			      "(ERREVENT_ATHUB_INTERRUPT) detected!\n");

		amdgpu_ras_set_fed(adev, true);
		ras->gpu_reset_flags |= AMDGPU_RAS_GPU_RESET_MODE1_RESET;
		amdgpu_ras_reset_gpu(adev);
	}
}

bool amdgpu_ras_need_emergency_restart(struct amdgpu_device *adev)
{
	if (adev->asic_type == CHIP_VEGA20 &&
	    adev->pm.fw_version <= 0x283400) {
		return !(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) &&
				amdgpu_ras_intr_triggered();
	}

	return false;
}

void amdgpu_release_ras_context(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!con)
		return;

	if (!adev->ras_enabled && con->features & BIT(AMDGPU_RAS_BLOCK__GFX)) {
		con->features &= ~BIT(AMDGPU_RAS_BLOCK__GFX);
		amdgpu_ras_set_context(adev, NULL);
		kfree(con);
	}
}

#ifdef CONFIG_X86_MCE_AMD
static struct amdgpu_device *find_adev(uint32_t node_id)
{
	int i;
	struct amdgpu_device *adev = NULL;

	for (i = 0; i < mce_adev_list.num_gpu; i++) {
		adev = mce_adev_list.devs[i];

		if (adev && adev->gmc.xgmi.connected_to_cpu &&
		    adev->gmc.xgmi.physical_node_id == node_id)
			break;
		adev = NULL;
	}

	return adev;
}

#define GET_MCA_IPID_GPUID(m)	(((m) >> 44) & 0xF)
#define GET_UMC_INST(m)		(((m) >> 21) & 0x7)
#define GET_CHAN_INDEX(m)	((((m) >> 12) & 0x3) | (((m) >> 18) & 0x4))
#define GPU_ID_OFFSET		8

static int amdgpu_bad_page_notifier(struct notifier_block *nb,
				    unsigned long val, void *data)
{
	struct mce *m = (struct mce *)data;
	struct amdgpu_device *adev = NULL;
	uint32_t gpu_id = 0;
	uint32_t umc_inst = 0, ch_inst = 0;

	/*
	 * If the error was generated in UMC_V2, which belongs to GPU UMCs,
	 * and error occurred in DramECC (Extended error code = 0) then only
	 * process the error, else bail out.
	 */
	if (!m || !((smca_get_bank_type(m->extcpu, m->bank) == SMCA_UMC_V2) &&
		    (XEC(m->status, 0x3f) == 0x0)))
		return NOTIFY_DONE;

	/*
	 * If it is correctable error, return.
	 */
	if (mce_is_correctable(m))
		return NOTIFY_OK;

	/*
	 * GPU Id is offset by GPU_ID_OFFSET in MCA_IPID_UMC register.
	 */
	gpu_id = GET_MCA_IPID_GPUID(m->ipid) - GPU_ID_OFFSET;

	adev = find_adev(gpu_id);
	if (!adev) {
		DRM_WARN("%s: Unable to find adev for gpu_id: %d\n", __func__,
								gpu_id);
		return NOTIFY_DONE;
	}

	/*
	 * If it is uncorrectable error, then find out UMC instance and
	 * channel index.
	 */
	umc_inst = GET_UMC_INST(m->ipid);
	ch_inst = GET_CHAN_INDEX(m->ipid);

	dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
			     umc_inst, ch_inst);

	if (!amdgpu_umc_page_retirement_mca(adev, m->addr, ch_inst, umc_inst))
		return NOTIFY_OK;
	else
		return NOTIFY_DONE;
}

static struct notifier_block amdgpu_bad_page_nb = {
	.notifier_call  = amdgpu_bad_page_notifier,
	.priority       = MCE_PRIO_UC,
};

static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev)
{
	/*
	 * Add the adev to the mce_adev_list.
	 * During mode2 reset, amdgpu device is temporarily
	 * removed from the mgpu_info list which can cause
	 * page retirement to fail.
	 * Use this list instead of mgpu_info to find the amdgpu
	 * device on which the UMC error was reported.
	 */
	mce_adev_list.devs[mce_adev_list.num_gpu++] = adev;

	/*
	 * Register the x86 notifier only once
	 * with MCE subsystem.
	 */
	if (notifier_registered == false) {
		mce_register_decode_chain(&amdgpu_bad_page_nb);
		notifier_registered = true;
	}
}
#endif

struct amdgpu_ras *amdgpu_ras_get_context(struct amdgpu_device *adev)
{
	if (!adev)
		return NULL;

	return adev->psp.ras_context.ras;
}

int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con)
{
	if (!adev)
		return -EINVAL;

	adev->psp.ras_context.ras = ras_con;
	return 0;
}

/* check if ras is supported on block, say, sdma, gfx */
int amdgpu_ras_is_supported(struct amdgpu_device *adev,
		unsigned int block)
{
	int ret = 0;
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);

	if (block >= AMDGPU_RAS_BLOCK_COUNT)
		return 0;

	ret = ras && (adev->ras_enabled & (1 << block));

	/* For the special asic with mem ecc enabled but sram ecc
	 * not enabled, even if the ras block is not supported on
	 * .ras_enabled, if the asic supports poison mode and the
	 * ras block has ras configuration, it can be considered
	 * that the ras block supports ras function.
	 */
	if (!ret &&
	    (block == AMDGPU_RAS_BLOCK__GFX ||
	     block == AMDGPU_RAS_BLOCK__SDMA ||
	     block == AMDGPU_RAS_BLOCK__VCN ||
	     block == AMDGPU_RAS_BLOCK__JPEG) &&
		(amdgpu_ras_mask & (1 << block)) &&
	    amdgpu_ras_is_poison_mode_supported(adev) &&
	    amdgpu_ras_get_ras_block(adev, block, 0))
		ret = 1;

	return ret;
}

int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
{
	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);

	/* mode1 is the only selection for RMA status */
	if (amdgpu_ras_is_rma(adev)) {
		ras->gpu_reset_flags = 0;
		ras->gpu_reset_flags |= AMDGPU_RAS_GPU_RESET_MODE1_RESET;
	}

	if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0) {
		struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
		int hive_ras_recovery = 0;

		if (hive) {
			hive_ras_recovery = atomic_read(&hive->ras_recovery);
			amdgpu_put_xgmi_hive(hive);
		}
		/* In the case of multiple GPUs, after a GPU has started
		 * resetting all GPUs on hive, other GPUs do not need to
		 * trigger GPU reset again.
		 */
		if (!hive_ras_recovery)
			amdgpu_reset_domain_schedule(ras->adev->reset_domain, &ras->recovery_work);
		else
			atomic_set(&ras->in_recovery, 0);
	} else {
		flush_work(&ras->recovery_work);
		amdgpu_reset_domain_schedule(ras->adev->reset_domain, &ras->recovery_work);
	}

	return 0;
}

int amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	int ret = 0;

	if (con) {
		ret = amdgpu_mca_smu_set_debug_mode(adev, enable);
		if (!ret)
			con->is_aca_debug_mode = enable;
	}

	return ret;
}

int amdgpu_ras_set_aca_debug_mode(struct amdgpu_device *adev, bool enable)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	int ret = 0;

	if (con) {
		if (amdgpu_aca_is_enabled(adev))
			ret = amdgpu_aca_smu_set_debug_mode(adev, enable);
		else
			ret = amdgpu_mca_smu_set_debug_mode(adev, enable);
		if (!ret)
			con->is_aca_debug_mode = enable;
	}

	return ret;
}

bool amdgpu_ras_get_aca_debug_mode(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	const struct aca_smu_funcs *smu_funcs = adev->aca.smu_funcs;
	const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;

	if (!con)
		return false;

	if ((amdgpu_aca_is_enabled(adev) && smu_funcs && smu_funcs->set_debug_mode) ||
	    (!amdgpu_aca_is_enabled(adev) && mca_funcs && mca_funcs->mca_set_debug_mode))
		return con->is_aca_debug_mode;
	else
		return true;
}

bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,
				     unsigned int *error_query_mode)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
	const struct aca_smu_funcs *smu_funcs = adev->aca.smu_funcs;

	if (!con) {
		*error_query_mode = AMDGPU_RAS_INVALID_ERROR_QUERY;
		return false;
	}

	if (amdgpu_sriov_vf(adev)) {
		*error_query_mode = AMDGPU_RAS_VIRT_ERROR_COUNT_QUERY;
	} else if ((smu_funcs && smu_funcs->set_debug_mode) || (mca_funcs && mca_funcs->mca_set_debug_mode)) {
		*error_query_mode =
			(con->is_aca_debug_mode) ? AMDGPU_RAS_DIRECT_ERROR_QUERY : AMDGPU_RAS_FIRMWARE_ERROR_QUERY;
	} else {
		*error_query_mode = AMDGPU_RAS_DIRECT_ERROR_QUERY;
	}

	return true;
}

/* Register each ip ras block into amdgpu ras */
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
		struct amdgpu_ras_block_object *ras_block_obj)
{
	struct amdgpu_ras_block_list *ras_node;
	if (!adev || !ras_block_obj)
		return -EINVAL;

	ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL);
	if (!ras_node)
		return -ENOMEM;

	INIT_LIST_HEAD(&ras_node->node);
	ras_node->ras_obj = ras_block_obj;
	list_add_tail(&ras_node->node, &adev->ras_list);

	return 0;
}

void amdgpu_ras_get_error_type_name(uint32_t err_type, char *err_type_name)
{
	if (!err_type_name)
		return;

	switch (err_type) {
	case AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE:
		sprintf(err_type_name, "correctable");
		break;
	case AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE:
		sprintf(err_type_name, "uncorrectable");
		break;
	default:
		sprintf(err_type_name, "unknown");
		break;
	}
}

bool amdgpu_ras_inst_get_memory_id_field(struct amdgpu_device *adev,
					 const struct amdgpu_ras_err_status_reg_entry *reg_entry,
					 uint32_t instance,
					 uint32_t *memory_id)
{
	uint32_t err_status_lo_data, err_status_lo_offset;

	if (!reg_entry)
		return false;

	err_status_lo_offset =
		AMDGPU_RAS_REG_ENTRY_OFFSET(reg_entry->hwip, instance,
					    reg_entry->seg_lo, reg_entry->reg_lo);
	err_status_lo_data = RREG32(err_status_lo_offset);

	if ((reg_entry->flags & AMDGPU_RAS_ERR_STATUS_VALID) &&
	    !REG_GET_FIELD(err_status_lo_data, ERR_STATUS_LO, ERR_STATUS_VALID_FLAG))
		return false;

	*memory_id = REG_GET_FIELD(err_status_lo_data, ERR_STATUS_LO, MEMORY_ID);

	return true;
}

bool amdgpu_ras_inst_get_err_cnt_field(struct amdgpu_device *adev,
				       const struct amdgpu_ras_err_status_reg_entry *reg_entry,
				       uint32_t instance,
				       unsigned long *err_cnt)
{
	uint32_t err_status_hi_data, err_status_hi_offset;

	if (!reg_entry)
		return false;

	err_status_hi_offset =
		AMDGPU_RAS_REG_ENTRY_OFFSET(reg_entry->hwip, instance,
					    reg_entry->seg_hi, reg_entry->reg_hi);
	err_status_hi_data = RREG32(err_status_hi_offset);

	if ((reg_entry->flags & AMDGPU_RAS_ERR_INFO_VALID) &&
	    !REG_GET_FIELD(err_status_hi_data, ERR_STATUS_HI, ERR_INFO_VALID_FLAG))
		/* keep the check here in case we need to refer to the result later */
		dev_dbg(adev->dev, "Invalid err_info field\n");

	/* read err count */
	*err_cnt = REG_GET_FIELD(err_status_hi_data, ERR_STATUS, ERR_CNT);

	return true;
}

void amdgpu_ras_inst_query_ras_error_count(struct amdgpu_device *adev,
					   const struct amdgpu_ras_err_status_reg_entry *reg_list,
					   uint32_t reg_list_size,
					   const struct amdgpu_ras_memory_id_entry *mem_list,
					   uint32_t mem_list_size,
					   uint32_t instance,
					   uint32_t err_type,
					   unsigned long *err_count)
{
	uint32_t memory_id;
	unsigned long err_cnt;
	char err_type_name[16];
	uint32_t i, j;

	for (i = 0; i < reg_list_size; i++) {
		/* query memory_id from err_status_lo */
		if (!amdgpu_ras_inst_get_memory_id_field(adev, &reg_list[i],
							 instance, &memory_id))
			continue;

		/* query err_cnt from err_status_hi */
		if (!amdgpu_ras_inst_get_err_cnt_field(adev, &reg_list[i],
						       instance, &err_cnt) ||
		    !err_cnt)
			continue;

		*err_count += err_cnt;

		/* log the errors */
		amdgpu_ras_get_error_type_name(err_type, err_type_name);
		if (!mem_list) {
			/* memory_list is not supported */
			dev_info(adev->dev,
				 "%ld %s hardware errors detected in %s, instance: %d, memory_id: %d\n",
				 err_cnt, err_type_name,
				 reg_list[i].block_name,
				 instance, memory_id);
		} else {
			for (j = 0; j < mem_list_size; j++) {
				if (memory_id == mem_list[j].memory_id) {
					dev_info(adev->dev,
						 "%ld %s hardware errors detected in %s, instance: %d, memory block: %s\n",
						 err_cnt, err_type_name,
						 reg_list[i].block_name,
						 instance, mem_list[j].name);
					break;
				}
			}
		}
	}
}

void amdgpu_ras_inst_reset_ras_error_count(struct amdgpu_device *adev,
					   const struct amdgpu_ras_err_status_reg_entry *reg_list,
					   uint32_t reg_list_size,
					   uint32_t instance)
{
	uint32_t err_status_lo_offset, err_status_hi_offset;
	uint32_t i;

	for (i = 0; i < reg_list_size; i++) {
		err_status_lo_offset =
			AMDGPU_RAS_REG_ENTRY_OFFSET(reg_list[i].hwip, instance,
						    reg_list[i].seg_lo, reg_list[i].reg_lo);
		err_status_hi_offset =
			AMDGPU_RAS_REG_ENTRY_OFFSET(reg_list[i].hwip, instance,
						    reg_list[i].seg_hi, reg_list[i].reg_hi);
		WREG32(err_status_lo_offset, 0);
		WREG32(err_status_hi_offset, 0);
	}
}

int amdgpu_ras_error_data_init(struct ras_err_data *err_data)
{
	memset(err_data, 0, sizeof(*err_data));

	INIT_LIST_HEAD(&err_data->err_node_list);

	return 0;
}

static void amdgpu_ras_error_node_release(struct ras_err_node *err_node)
{
	if (!err_node)
		return;

	list_del(&err_node->node);
	kvfree(err_node);
}

void amdgpu_ras_error_data_fini(struct ras_err_data *err_data)
{
	struct ras_err_node *err_node, *tmp;

	list_for_each_entry_safe(err_node, tmp, &err_data->err_node_list, node)
		amdgpu_ras_error_node_release(err_node);
}

static struct ras_err_node *amdgpu_ras_error_find_node_by_id(struct ras_err_data *err_data,
							     struct amdgpu_smuio_mcm_config_info *mcm_info)
{
	struct ras_err_node *err_node;
	struct amdgpu_smuio_mcm_config_info *ref_id;

	if (!err_data || !mcm_info)
		return NULL;

	for_each_ras_error(err_node, err_data) {
		ref_id = &err_node->err_info.mcm_info;

		if (mcm_info->socket_id == ref_id->socket_id &&
		    mcm_info->die_id == ref_id->die_id)
			return err_node;
	}

	return NULL;
}

static struct ras_err_node *amdgpu_ras_error_node_new(void)
{
	struct ras_err_node *err_node;

	err_node = kvzalloc(sizeof(*err_node), GFP_KERNEL);
	if (!err_node)
		return NULL;

	INIT_LIST_HEAD(&err_node->node);

	return err_node;
}

static int ras_err_info_cmp(void *priv, const struct list_head *a, const struct list_head *b)
{
	struct ras_err_node *nodea = container_of(a, struct ras_err_node, node);
	struct ras_err_node *nodeb = container_of(b, struct ras_err_node, node);
	struct amdgpu_smuio_mcm_config_info *infoa = &nodea->err_info.mcm_info;
	struct amdgpu_smuio_mcm_config_info *infob = &nodeb->err_info.mcm_info;

	if (unlikely(infoa->socket_id != infob->socket_id))
		return infoa->socket_id - infob->socket_id;
	else
		return infoa->die_id - infob->die_id;

	return 0;
}

static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_data,
				struct amdgpu_smuio_mcm_config_info *mcm_info)
{
	struct ras_err_node *err_node;

	err_node = amdgpu_ras_error_find_node_by_id(err_data, mcm_info);
	if (err_node)
		return &err_node->err_info;

	err_node = amdgpu_ras_error_node_new();
	if (!err_node)
		return NULL;

	memcpy(&err_node->err_info.mcm_info, mcm_info, sizeof(*mcm_info));

	err_data->err_list_count++;
	list_add_tail(&err_node->node, &err_data->err_node_list);
	list_sort(NULL, &err_data->err_node_list, ras_err_info_cmp);

	return &err_node->err_info;
}

int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data,
					struct amdgpu_smuio_mcm_config_info *mcm_info,
					u64 count)
{
	struct ras_err_info *err_info;

	if (!err_data || !mcm_info)
		return -EINVAL;

	if (!count)
		return 0;

	err_info = amdgpu_ras_error_get_info(err_data, mcm_info);
	if (!err_info)
		return -EINVAL;

	err_info->ue_count += count;
	err_data->ue_count += count;

	return 0;
}

int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data,
					struct amdgpu_smuio_mcm_config_info *mcm_info,
					u64 count)
{
	struct ras_err_info *err_info;

	if (!err_data || !mcm_info)
		return -EINVAL;

	if (!count)
		return 0;

	err_info = amdgpu_ras_error_get_info(err_data, mcm_info);
	if (!err_info)
		return -EINVAL;

	err_info->ce_count += count;
	err_data->ce_count += count;

	return 0;
}

int amdgpu_ras_error_statistic_de_count(struct ras_err_data *err_data,
					struct amdgpu_smuio_mcm_config_info *mcm_info,
					u64 count)
{
	struct ras_err_info *err_info;

	if (!err_data || !mcm_info)
		return -EINVAL;

	if (!count)
		return 0;

	err_info = amdgpu_ras_error_get_info(err_data, mcm_info);
	if (!err_info)
		return -EINVAL;

	err_info->de_count += count;
	err_data->de_count += count;

	return 0;
}

#define mmMP0_SMN_C2PMSG_92	0x1609C
#define mmMP0_SMN_C2PMSG_126	0x160BE
static void amdgpu_ras_boot_time_error_reporting(struct amdgpu_device *adev,
						 u32 instance)
{
	u32 socket_id, aid_id, hbm_id;
	u32 fw_status;
	u32 boot_error;
	u64 reg_addr;

	/* The pattern for smn addressing in other SOC could be different from
	 * the one for aqua_vanjaram. We should revisit the code if the pattern
	 * is changed. In such case, replace the aqua_vanjaram implementation
	 * with more common helper */
	reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +
		   aqua_vanjaram_encode_ext_smn_addressing(instance);
	fw_status = amdgpu_device_indirect_rreg_ext(adev, reg_addr);

	reg_addr = (mmMP0_SMN_C2PMSG_126 << 2) +
		   aqua_vanjaram_encode_ext_smn_addressing(instance);
	boot_error = amdgpu_device_indirect_rreg_ext(adev, reg_addr);

	socket_id = AMDGPU_RAS_GPU_ERR_SOCKET_ID(boot_error);
	aid_id = AMDGPU_RAS_GPU_ERR_AID_ID(boot_error);
	hbm_id = ((1 == AMDGPU_RAS_GPU_ERR_HBM_ID(boot_error)) ? 0 : 1);

	if (AMDGPU_RAS_GPU_ERR_MEM_TRAINING(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, hbm: %d, fw_status: 0x%x, memory training failed\n",
			 socket_id, aid_id, hbm_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_FW_LOAD(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, firmware load failed at boot time\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_WAFL_LINK_TRAINING(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, wafl link training failed\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_XGMI_LINK_TRAINING(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, xgmi link training failed\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_USR_CP_LINK_TRAINING(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, usr cp link training failed\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_USR_DP_LINK_TRAINING(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, usr dp link training failed\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_HBM_MEM_TEST(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, hbm: %d, fw_status: 0x%x, hbm memory test failed\n",
			 socket_id, aid_id, hbm_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_HBM_BIST_TEST(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, hbm: %d, fw_status: 0x%x, hbm bist test failed\n",
			 socket_id, aid_id, hbm_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_DATA_ABORT(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, data abort exception\n",
			 socket_id, aid_id, fw_status);

	if (AMDGPU_RAS_GPU_ERR_GENERIC(boot_error))
		dev_info(adev->dev,
			 "socket: %d, aid: %d, fw_status: 0x%x, Boot Controller Generic Error\n",
			 socket_id, aid_id, fw_status);
}

static bool amdgpu_ras_boot_error_detected(struct amdgpu_device *adev,
					   u32 instance)
{
	u64 reg_addr;
	u32 reg_data;
	int retry_loop;

	reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +
		   aqua_vanjaram_encode_ext_smn_addressing(instance);

	for (retry_loop = 0; retry_loop < AMDGPU_RAS_BOOT_STATUS_POLLING_LIMIT; retry_loop++) {
		reg_data = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
		if ((reg_data & AMDGPU_RAS_BOOT_STATUS_MASK) == AMDGPU_RAS_BOOT_STEADY_STATUS)
			return false;
		else
			msleep(1);
	}

	return true;
}

void amdgpu_ras_query_boot_status(struct amdgpu_device *adev, u32 num_instances)
{
	u32 i;

	for (i = 0; i < num_instances; i++) {
		if (amdgpu_ras_boot_error_detected(adev, i))
			amdgpu_ras_boot_time_error_reporting(adev, i);
	}
}

int amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
	struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
	uint64_t start = pfn << AMDGPU_GPU_PAGE_SHIFT;
	int ret = 0;

	mutex_lock(&con->page_rsv_lock);
	ret = amdgpu_vram_mgr_query_page_status(mgr, start);
	if (ret == -ENOENT)
		ret = amdgpu_vram_mgr_reserve_range(mgr, start, AMDGPU_GPU_PAGE_SIZE);
	mutex_unlock(&con->page_rsv_lock);

	return ret;
}

void amdgpu_ras_event_log_print(struct amdgpu_device *adev, u64 event_id,
				const char *fmt, ...)
{
	struct va_format vaf;
	va_list args;

	va_start(args, fmt);
	vaf.fmt = fmt;
	vaf.va = &args;

	if (RAS_EVENT_ID_IS_VALID(event_id))
		dev_printk(KERN_INFO, adev->dev, "{%llu}%pV", event_id, &vaf);
	else
		dev_printk(KERN_INFO, adev->dev, "%pV", &vaf);

	va_end(args);
}

bool amdgpu_ras_is_rma(struct amdgpu_device *adev)
{
	struct amdgpu_ras *con = amdgpu_ras_get_context(adev);

	if (!con)
		return false;

	return con->is_rma;
}
