arch/powerpc/platforms/powernv/eeh-powernv.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/eeh-powernv.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/powernv/eeh-powernv.c
Extension
.c
Size
44524 bytes
Lines
1696
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations pnv_eeh_ei_fops = {
	.open	= simple_open,
	.write	= pnv_eeh_ei_write,
};

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

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

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

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

#define PNV_EEH_DBGFS_ENTRY(name, reg)				\
static int pnv_eeh_dbgfs_set_##name(void *data, u64 val)	\
{								\
	return pnv_eeh_dbgfs_set(data, reg, val);		\
}								\
								\
static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val)	\
{								\
	return pnv_eeh_dbgfs_get(data, reg, val);		\
}								\
								\
DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name,		\
			pnv_eeh_dbgfs_get_##name,		\
                        pnv_eeh_dbgfs_set_##name,		\
			"0x%llx\n")

PNV_EEH_DBGFS_ENTRY(outb, 0xD10);
PNV_EEH_DBGFS_ENTRY(inbA, 0xD90);
PNV_EEH_DBGFS_ENTRY(inbB, 0xE10);

#endif /* CONFIG_DEBUG_FS */

static void pnv_eeh_enable_phbs(void)
{
	struct pci_controller *hose;
	struct pnv_phb *phb;

	list_for_each_entry(hose, &hose_list, list_node) {
		phb = hose->private_data;
		/*
		 * If EEH is enabled, we're going to rely on that.
		 * Otherwise, we restore to conventional mechanism
		 * to clear frozen PE during PCI config access.
		 */
		if (eeh_enabled())
			phb->flags |= PNV_PHB_FLAG_EEH;
		else
			phb->flags &= ~PNV_PHB_FLAG_EEH;
	}
}

/**
 * pnv_eeh_post_init - EEH platform dependent post initialization
 *
 * EEH platform dependent post initialization on powernv. When
 * the function is called, the EEH PEs and devices should have
 * been built. If the I/O cache staff has been built, EEH is
 * ready to supply service.
 */
int pnv_eeh_post_init(void)
{
	struct pci_controller *hose;
	struct pnv_phb *phb;
	int ret = 0;

	eeh_show_enabled();

	/* Register OPAL event notifier */
	eeh_event_irq = opal_event_request(ilog2(OPAL_EVENT_PCI_ERROR));
	if (eeh_event_irq < 0) {
		pr_err("%s: Can't register OPAL event interrupt (%d)\n",
		       __func__, eeh_event_irq);
		return eeh_event_irq;
	}

	ret = request_irq(eeh_event_irq, pnv_eeh_event,
			  IRQ_TYPE_LEVEL_HIGH, "opal-eeh", NULL);

Annotation

Implementation Notes