Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff6bdcd9 authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt
Browse files

powerpc/powernv: Support inbound error injection



For now, we only support outbound error injection. Actually, the
hardware supports injecting inbound errors as well. The patch enables
to inject inbound errors.

Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 20bb842b
Loading
Loading
Loading
Loading
+50 −9
Original line number Original line Diff line number Diff line
@@ -59,26 +59,60 @@ static struct notifier_block ioda_eeh_nb = {
};
};


#ifdef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
static int ioda_eeh_dbgfs_set(void *data, u64 val)
static int ioda_eeh_dbgfs_set(void *data, int offset, u64 val)
{
{
	struct pci_controller *hose = data;
	struct pci_controller *hose = data;
	struct pnv_phb *phb = hose->private_data;
	struct pnv_phb *phb = hose->private_data;


	out_be64(phb->regs + 0xD10, val);
	out_be64(phb->regs + offset, val);
	return 0;
	return 0;
}
}


static int ioda_eeh_dbgfs_get(void *data, u64 *val)
static int ioda_eeh_dbgfs_get(void *data, int offset, u64 *val)
{
{
	struct pci_controller *hose = data;
	struct pci_controller *hose = data;
	struct pnv_phb *phb = hose->private_data;
	struct pnv_phb *phb = hose->private_data;


	*val = in_be64(phb->regs + 0xD10);
	*val = in_be64(phb->regs + offset);
	return 0;
	return 0;
}
}


DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_dbgfs_ops, ioda_eeh_dbgfs_get,
static int ioda_eeh_outb_dbgfs_set(void *data, u64 val)
			ioda_eeh_dbgfs_set, "0x%llx\n");
{
	return ioda_eeh_dbgfs_set(data, 0xD10, val);
}

static int ioda_eeh_outb_dbgfs_get(void *data, u64 *val)
{
	return ioda_eeh_dbgfs_get(data, 0xD10, val);
}

static int ioda_eeh_inbA_dbgfs_set(void *data, u64 val)
{
	return ioda_eeh_dbgfs_set(data, 0xD90, val);
}

static int ioda_eeh_inbA_dbgfs_get(void *data, u64 *val)
{
	return ioda_eeh_dbgfs_get(data, 0xD90, val);
}

static int ioda_eeh_inbB_dbgfs_set(void *data, u64 val)
{
	return ioda_eeh_dbgfs_set(data, 0xE10, val);
}

static int ioda_eeh_inbB_dbgfs_get(void *data, u64 *val)
{
	return ioda_eeh_dbgfs_get(data, 0xE10, val);
}

DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_outb_dbgfs_ops, ioda_eeh_outb_dbgfs_get,
			ioda_eeh_outb_dbgfs_set, "0x%llx\n");
DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbA_dbgfs_ops, ioda_eeh_inbA_dbgfs_get,
			ioda_eeh_inbA_dbgfs_set, "0x%llx\n");
DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get,
			ioda_eeh_inbB_dbgfs_set, "0x%llx\n");
#endif /* CONFIG_DEBUG_FS */
#endif /* CONFIG_DEBUG_FS */


/**
/**
@@ -116,10 +150,17 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
	}
	}


#ifdef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
	if (phb->dbgfs)
	if (phb->dbgfs) {
		debugfs_create_file("err_injct", 0600,
		debugfs_create_file("err_injct_outbound", 0600,
				    phb->dbgfs, hose,
				    &ioda_eeh_outb_dbgfs_ops);
		debugfs_create_file("err_injct_inboundA", 0600,
				    phb->dbgfs, hose,
				    phb->dbgfs, hose,
				    &ioda_eeh_dbgfs_ops);
				    &ioda_eeh_inbA_dbgfs_ops);
		debugfs_create_file("err_injct_inboundB", 0600,
				    phb->dbgfs, hose,
				    &ioda_eeh_inbB_dbgfs_ops);
	}
#endif
#endif


	phb->eeh_state |= PNV_EEH_STATE_ENABLED;
	phb->eeh_state |= PNV_EEH_STATE_ENABLED;