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

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

powerpc/eeh: Replace device_node with pci_dn in eeh_ops



There are 3 EEH operations whose arguments contain device_node:
read_config(), write_config() and restore_config(). The patch
replaces device_node with pci_dn.

Signed-off-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent ff57b454
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -217,10 +217,10 @@ struct eeh_ops {
	int (*configure_bridge)(struct eeh_pe *pe);
	int (*configure_bridge)(struct eeh_pe *pe);
	int (*err_inject)(struct eeh_pe *pe, int type, int func,
	int (*err_inject)(struct eeh_pe *pe, int type, int func,
			  unsigned long addr, unsigned long mask);
			  unsigned long addr, unsigned long mask);
	int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
	int (*read_config)(struct pci_dn *pdn, int where, int size, u32 *val);
	int (*write_config)(struct device_node *dn, int where, int size, u32 val);
	int (*write_config)(struct pci_dn *pdn, int where, int size, u32 val);
	int (*next_error)(struct eeh_pe **pe);
	int (*next_error)(struct eeh_pe **pe);
	int (*restore_config)(struct device_node *dn);
	int (*restore_config)(struct pci_dn *pdn);
};
};


extern int eeh_subsystem_flags;
extern int eeh_subsystem_flags;
+22 −18
Original line number Original line Diff line number Diff line
@@ -164,30 +164,34 @@ __setup("eeh=", eeh_setup);
 */
 */
static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
{
{
	struct device_node *dn = eeh_dev_to_of_node(edev);
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);
	u32 cfg;
	u32 cfg;
	int cap, i;
	int cap, i;
	int n = 0, l = 0;
	int n = 0, l = 0;
	char buffer[128];
	char buffer[128];


	n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
	n += scnprintf(buf+n, len-n, "%04x:%02x:%02x:%01x\n",
	pr_warn("EEH: of node=%s\n", dn->full_name);
		       edev->phb->global_number, pdn->busno,
		       PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
	pr_warn("EEH: of node=%04x:%02x:%02x:%01x\n",
		edev->phb->global_number, pdn->busno,
		PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));


	eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg);
	eeh_ops->read_config(pdn, PCI_VENDOR_ID, 4, &cfg);
	n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg);
	n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg);
	pr_warn("EEH: PCI device/vendor: %08x\n", cfg);
	pr_warn("EEH: PCI device/vendor: %08x\n", cfg);


	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg);
	eeh_ops->read_config(pdn, PCI_COMMAND, 4, &cfg);
	n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
	n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
	pr_warn("EEH: PCI cmd/status register: %08x\n", cfg);
	pr_warn("EEH: PCI cmd/status register: %08x\n", cfg);


	/* Gather bridge-specific registers */
	/* Gather bridge-specific registers */
	if (edev->mode & EEH_DEV_BRIDGE) {
	if (edev->mode & EEH_DEV_BRIDGE) {
		eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg);
		eeh_ops->read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
		n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
		n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
		pr_warn("EEH: Bridge secondary status: %04x\n", cfg);
		pr_warn("EEH: Bridge secondary status: %04x\n", cfg);


		eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg);
		eeh_ops->read_config(pdn, PCI_BRIDGE_CONTROL, 2, &cfg);
		n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
		n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
		pr_warn("EEH: Bridge control: %04x\n", cfg);
		pr_warn("EEH: Bridge control: %04x\n", cfg);
	}
	}
@@ -195,11 +199,11 @@ static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
	/* Dump out the PCI-X command and status regs */
	/* Dump out the PCI-X command and status regs */
	cap = edev->pcix_cap;
	cap = edev->pcix_cap;
	if (cap) {
	if (cap) {
		eeh_ops->read_config(dn, cap, 4, &cfg);
		eeh_ops->read_config(pdn, cap, 4, &cfg);
		n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
		n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
		pr_warn("EEH: PCI-X cmd: %08x\n", cfg);
		pr_warn("EEH: PCI-X cmd: %08x\n", cfg);


		eeh_ops->read_config(dn, cap+4, 4, &cfg);
		eeh_ops->read_config(pdn, cap+4, 4, &cfg);
		n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg);
		n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg);
		pr_warn("EEH: PCI-X status: %08x\n", cfg);
		pr_warn("EEH: PCI-X status: %08x\n", cfg);
	}
	}
@@ -211,7 +215,7 @@ static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
		pr_warn("EEH: PCI-E capabilities and status follow:\n");
		pr_warn("EEH: PCI-E capabilities and status follow:\n");


		for (i=0; i<=8; i++) {
		for (i=0; i<=8; i++) {
			eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
			eeh_ops->read_config(pdn, cap+4*i, 4, &cfg);
			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);


			if ((i % 4) == 0) {
			if ((i % 4) == 0) {
@@ -238,7 +242,7 @@ static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
		pr_warn("EEH: PCI-E AER capability register set follows:\n");
		pr_warn("EEH: PCI-E AER capability register set follows:\n");


		for (i=0; i<=13; i++) {
		for (i=0; i<=13; i++) {
			eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
			eeh_ops->read_config(pdn, cap+4*i, 4, &cfg);
			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);


			if ((i % 4) == 0) {
			if ((i % 4) == 0) {
@@ -698,7 +702,7 @@ static void *eeh_disable_and_save_dev_state(void *data, void *userdata)
static void *eeh_restore_dev_state(void *data, void *userdata)
static void *eeh_restore_dev_state(void *data, void *userdata)
{
{
	struct eeh_dev *edev = data;
	struct eeh_dev *edev = data;
	struct device_node *dn = eeh_dev_to_of_node(edev);
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);
	struct pci_dev *pdev = eeh_dev_to_pci_dev(edev);
	struct pci_dev *pdev = eeh_dev_to_pci_dev(edev);
	struct pci_dev *dev = userdata;
	struct pci_dev *dev = userdata;


@@ -706,8 +710,8 @@ static void *eeh_restore_dev_state(void *data, void *userdata)
		return NULL;
		return NULL;


	/* Apply customization from firmware */
	/* Apply customization from firmware */
	if (dn && eeh_ops->restore_config)
	if (pdn && eeh_ops->restore_config)
		eeh_ops->restore_config(dn);
		eeh_ops->restore_config(pdn);


	/* The caller should restore state for the specified device */
	/* The caller should restore state for the specified device */
	if (pdev != dev)
	if (pdev != dev)
@@ -870,15 +874,15 @@ int eeh_reset_pe(struct eeh_pe *pe)
 */
 */
void eeh_save_bars(struct eeh_dev *edev)
void eeh_save_bars(struct eeh_dev *edev)
{
{
	struct pci_dn *pdn;
	int i;
	int i;
	struct device_node *dn;


	if (!edev)
	pdn = eeh_dev_to_pdn(edev);
	if (!pdn)
		return;
		return;
	dn = eeh_dev_to_of_node(edev);


	for (i = 0; i < 16; i++)
	for (i = 0; i < 16; i++)
		eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
		eeh_ops->read_config(pdn, i * 4, 4, &edev->config_space[i]);


	/*
	/*
	 * For PCI bridges including root port, we need enable bus
	 * For PCI bridges including root port, we need enable bus
+40 −42
Original line number Original line Diff line number Diff line
@@ -291,27 +291,25 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
 */
 */
static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
{
{
	struct device_node *dn;
	struct eeh_dev *parent;
	struct eeh_dev *parent;
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);


	/*
	/*
	 * It might have the case for the indirect parent
	 * It might have the case for the indirect parent
	 * EEH device already having associated PE, but
	 * EEH device already having associated PE, but
	 * the direct parent EEH device doesn't have yet.
	 * the direct parent EEH device doesn't have yet.
	 */
	 */
	dn = edev->dn->parent;
	pdn = pdn ? pdn->parent : NULL;
	while (dn) {
	while (pdn) {
		/* We're poking out of PCI territory */
		/* We're poking out of PCI territory */
		if (!PCI_DN(dn)) return NULL;
		parent = pdn_to_eeh_dev(pdn);

		if (!parent)
		parent = of_node_to_eeh_dev(dn);
			return NULL;
		/* We're poking out of PCI territory */
		if (!parent) return NULL;


		if (parent->pe)
		if (parent->pe)
			return parent->pe;
			return parent->pe;


		dn = dn->parent;
		pdn = pdn->parent;
	}
	}


	return NULL;
	return NULL;
@@ -653,9 +651,9 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state)
 * blocked on normal path during the stage. So we need utilize
 * blocked on normal path during the stage. So we need utilize
 * eeh operations, which is always permitted.
 * eeh operations, which is always permitted.
 */
 */
static void eeh_bridge_check_link(struct eeh_dev *edev,
static void eeh_bridge_check_link(struct eeh_dev *edev)
				  struct device_node *dn)
{
{
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);
	int cap;
	int cap;
	uint32_t val;
	uint32_t val;
	int timeout = 0;
	int timeout = 0;
@@ -675,32 +673,32 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,


	/* Check slot status */
	/* Check slot status */
	cap = edev->pcie_cap;
	cap = edev->pcie_cap;
	eeh_ops->read_config(dn, cap + PCI_EXP_SLTSTA, 2, &val);
	eeh_ops->read_config(pdn, cap + PCI_EXP_SLTSTA, 2, &val);
	if (!(val & PCI_EXP_SLTSTA_PDS)) {
	if (!(val & PCI_EXP_SLTSTA_PDS)) {
		pr_debug("  No card in the slot (0x%04x) !\n", val);
		pr_debug("  No card in the slot (0x%04x) !\n", val);
		return;
		return;
	}
	}


	/* Check power status if we have the capability */
	/* Check power status if we have the capability */
	eeh_ops->read_config(dn, cap + PCI_EXP_SLTCAP, 2, &val);
	eeh_ops->read_config(pdn, cap + PCI_EXP_SLTCAP, 2, &val);
	if (val & PCI_EXP_SLTCAP_PCP) {
	if (val & PCI_EXP_SLTCAP_PCP) {
		eeh_ops->read_config(dn, cap + PCI_EXP_SLTCTL, 2, &val);
		eeh_ops->read_config(pdn, cap + PCI_EXP_SLTCTL, 2, &val);
		if (val & PCI_EXP_SLTCTL_PCC) {
		if (val & PCI_EXP_SLTCTL_PCC) {
			pr_debug("  In power-off state, power it on ...\n");
			pr_debug("  In power-off state, power it on ...\n");
			val &= ~(PCI_EXP_SLTCTL_PCC | PCI_EXP_SLTCTL_PIC);
			val &= ~(PCI_EXP_SLTCTL_PCC | PCI_EXP_SLTCTL_PIC);
			val |= (0x0100 & PCI_EXP_SLTCTL_PIC);
			val |= (0x0100 & PCI_EXP_SLTCTL_PIC);
			eeh_ops->write_config(dn, cap + PCI_EXP_SLTCTL, 2, val);
			eeh_ops->write_config(pdn, cap + PCI_EXP_SLTCTL, 2, val);
			msleep(2 * 1000);
			msleep(2 * 1000);
		}
		}
	}
	}


	/* Enable link */
	/* Enable link */
	eeh_ops->read_config(dn, cap + PCI_EXP_LNKCTL, 2, &val);
	eeh_ops->read_config(pdn, cap + PCI_EXP_LNKCTL, 2, &val);
	val &= ~PCI_EXP_LNKCTL_LD;
	val &= ~PCI_EXP_LNKCTL_LD;
	eeh_ops->write_config(dn, cap + PCI_EXP_LNKCTL, 2, val);
	eeh_ops->write_config(pdn, cap + PCI_EXP_LNKCTL, 2, val);


	/* Check link */
	/* Check link */
	eeh_ops->read_config(dn, cap + PCI_EXP_LNKCAP, 4, &val);
	eeh_ops->read_config(pdn, cap + PCI_EXP_LNKCAP, 4, &val);
	if (!(val & PCI_EXP_LNKCAP_DLLLARC)) {
	if (!(val & PCI_EXP_LNKCAP_DLLLARC)) {
		pr_debug("  No link reporting capability (0x%08x) \n", val);
		pr_debug("  No link reporting capability (0x%08x) \n", val);
		msleep(1000);
		msleep(1000);
@@ -713,7 +711,7 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
		msleep(20);
		msleep(20);
		timeout += 20;
		timeout += 20;


		eeh_ops->read_config(dn, cap + PCI_EXP_LNKSTA, 2, &val);
		eeh_ops->read_config(pdn, cap + PCI_EXP_LNKSTA, 2, &val);
		if (val & PCI_EXP_LNKSTA_DLLLA)
		if (val & PCI_EXP_LNKSTA_DLLLA)
			break;
			break;
	}
	}
@@ -728,9 +726,9 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
#define BYTE_SWAP(OFF)	(8*((OFF)/4)+3-(OFF))
#define BYTE_SWAP(OFF)	(8*((OFF)/4)+3-(OFF))
#define SAVED_BYTE(OFF)	(((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
#define SAVED_BYTE(OFF)	(((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])


static void eeh_restore_bridge_bars(struct eeh_dev *edev,
static void eeh_restore_bridge_bars(struct eeh_dev *edev)
				    struct device_node *dn)
{
{
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);
	int i;
	int i;


	/*
	/*
@@ -738,49 +736,49 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev,
	 * Bus numbers and windows: 0x18 - 0x30
	 * Bus numbers and windows: 0x18 - 0x30
	 */
	 */
	for (i = 4; i < 13; i++)
	for (i = 4; i < 13; i++)
		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
		eeh_ops->write_config(pdn, i*4, 4, edev->config_space[i]);
	/* Rom: 0x38 */
	/* Rom: 0x38 */
	eeh_ops->write_config(dn, 14*4, 4, edev->config_space[14]);
	eeh_ops->write_config(pdn, 14*4, 4, edev->config_space[14]);


	/* Cache line & Latency timer: 0xC 0xD */
	/* Cache line & Latency timer: 0xC 0xD */
	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
	eeh_ops->write_config(pdn, PCI_CACHE_LINE_SIZE, 1,
                SAVED_BYTE(PCI_CACHE_LINE_SIZE));
                SAVED_BYTE(PCI_CACHE_LINE_SIZE));
        eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
        eeh_ops->write_config(pdn, PCI_LATENCY_TIMER, 1,
                SAVED_BYTE(PCI_LATENCY_TIMER));
                SAVED_BYTE(PCI_LATENCY_TIMER));
	/* Max latency, min grant, interrupt ping and line: 0x3C */
	/* Max latency, min grant, interrupt ping and line: 0x3C */
	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
	eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);


	/* PCI Command: 0x4 */
	/* PCI Command: 0x4 */
	eeh_ops->write_config(dn, PCI_COMMAND, 4, edev->config_space[1]);
	eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]);


	/* Check the PCIe link is ready */
	/* Check the PCIe link is ready */
	eeh_bridge_check_link(edev, dn);
	eeh_bridge_check_link(edev);
}
}


static void eeh_restore_device_bars(struct eeh_dev *edev,
static void eeh_restore_device_bars(struct eeh_dev *edev)
				    struct device_node *dn)
{
{
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);
	int i;
	int i;
	u32 cmd;
	u32 cmd;


	for (i = 4; i < 10; i++)
	for (i = 4; i < 10; i++)
		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
		eeh_ops->write_config(pdn, i*4, 4, edev->config_space[i]);
	/* 12 == Expansion ROM Address */
	/* 12 == Expansion ROM Address */
	eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
	eeh_ops->write_config(pdn, 12*4, 4, edev->config_space[12]);


	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
	eeh_ops->write_config(pdn, PCI_CACHE_LINE_SIZE, 1,
		SAVED_BYTE(PCI_CACHE_LINE_SIZE));
		SAVED_BYTE(PCI_CACHE_LINE_SIZE));
	eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
	eeh_ops->write_config(pdn, PCI_LATENCY_TIMER, 1,
		SAVED_BYTE(PCI_LATENCY_TIMER));
		SAVED_BYTE(PCI_LATENCY_TIMER));


	/* max latency, min grant, interrupt pin and line */
	/* max latency, min grant, interrupt pin and line */
	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
	eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);


	/*
	/*
	 * Restore PERR & SERR bits, some devices require it,
	 * Restore PERR & SERR bits, some devices require it,
	 * don't touch the other command bits
	 * don't touch the other command bits
	 */
	 */
	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
	eeh_ops->read_config(pdn, PCI_COMMAND, 4, &cmd);
	if (edev->config_space[1] & PCI_COMMAND_PARITY)
	if (edev->config_space[1] & PCI_COMMAND_PARITY)
		cmd |= PCI_COMMAND_PARITY;
		cmd |= PCI_COMMAND_PARITY;
	else
	else
@@ -789,7 +787,7 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
		cmd |= PCI_COMMAND_SERR;
		cmd |= PCI_COMMAND_SERR;
	else
	else
		cmd &= ~PCI_COMMAND_SERR;
		cmd &= ~PCI_COMMAND_SERR;
	eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
	eeh_ops->write_config(pdn, PCI_COMMAND, 4, cmd);
}
}


/**
/**
@@ -804,16 +802,16 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
static void *eeh_restore_one_device_bars(void *data, void *flag)
static void *eeh_restore_one_device_bars(void *data, void *flag)
{
{
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct device_node *dn = eeh_dev_to_of_node(edev);
	struct pci_dn *pdn = eeh_dev_to_pdn(edev);


	/* Do special restore for bridges */
	/* Do special restore for bridges */
	if (edev->mode & EEH_DEV_BRIDGE)
	if (edev->mode & EEH_DEV_BRIDGE)
		eeh_restore_bridge_bars(edev, dn);
		eeh_restore_bridge_bars(edev);
	else
	else
		eeh_restore_device_bars(edev, dn);
		eeh_restore_device_bars(edev);


	if (eeh_ops->restore_config)
	if (eeh_ops->restore_config && pdn)
		eeh_ops->restore_config(dn);
		eeh_ops->restore_config(pdn);


	return NULL;
	return NULL;
}
}
+18 −22
Original line number Original line Diff line number Diff line
@@ -842,8 +842,8 @@ static int pnv_eeh_root_reset(struct pci_controller *hose, int option)


static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
{
{
	struct device_node *dn = pci_device_to_OF_node(dev);
	struct pci_dn *pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
	struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
	int aer = edev ? edev->aer_cap : 0;
	int aer = edev ? edev->aer_cap : 0;
	u32 ctrl;
	u32 ctrl;


@@ -856,32 +856,32 @@ static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
	case EEH_RESET_HOT:
	case EEH_RESET_HOT:
		/* Don't report linkDown event */
		/* Don't report linkDown event */
		if (aer) {
		if (aer) {
			eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
			eeh_ops->read_config(pdn, aer + PCI_ERR_UNCOR_MASK,
					     4, &ctrl);
					     4, &ctrl);
			ctrl |= PCI_ERR_UNC_SURPDN;
			ctrl |= PCI_ERR_UNC_SURPDN;
			eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
			eeh_ops->write_config(pdn, aer + PCI_ERR_UNCOR_MASK,
					      4, ctrl);
					      4, ctrl);
		}
		}


		eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
		eeh_ops->read_config(pdn, PCI_BRIDGE_CONTROL, 2, &ctrl);
		ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
		ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
		eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
		eeh_ops->write_config(pdn, PCI_BRIDGE_CONTROL, 2, ctrl);


		msleep(EEH_PE_RST_HOLD_TIME);
		msleep(EEH_PE_RST_HOLD_TIME);
		break;
		break;
	case EEH_RESET_DEACTIVATE:
	case EEH_RESET_DEACTIVATE:
		eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
		eeh_ops->read_config(pdn, PCI_BRIDGE_CONTROL, 2, &ctrl);
		ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
		ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
		eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
		eeh_ops->write_config(pdn, PCI_BRIDGE_CONTROL, 2, ctrl);


		msleep(EEH_PE_RST_SETTLE_TIME);
		msleep(EEH_PE_RST_SETTLE_TIME);


		/* Continue reporting linkDown event */
		/* Continue reporting linkDown event */
		if (aer) {
		if (aer) {
			eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
			eeh_ops->read_config(pdn, aer + PCI_ERR_UNCOR_MASK,
					     4, &ctrl);
					     4, &ctrl);
			ctrl &= ~PCI_ERR_UNC_SURPDN;
			ctrl &= ~PCI_ERR_UNC_SURPDN;
			eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
			eeh_ops->write_config(pdn, aer + PCI_ERR_UNCOR_MASK,
					      4, ctrl);
					      4, ctrl);
		}
		}


@@ -1099,9 +1099,9 @@ static int pnv_eeh_err_inject(struct eeh_pe *pe, int type, int func,
	return 0;
	return 0;
}
}


static inline bool pnv_eeh_cfg_blocked(struct device_node *dn)
static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn)
{
{
	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
	struct eeh_dev *edev = pdn_to_eeh_dev(pdn);


	if (!edev || !edev->pe)
	if (!edev || !edev->pe)
		return false;
		return false;
@@ -1112,15 +1112,13 @@ static inline bool pnv_eeh_cfg_blocked(struct device_node *dn)
	return false;
	return false;
}
}


static int pnv_eeh_read_config(struct device_node *dn,
static int pnv_eeh_read_config(struct pci_dn *pdn,
			       int where, int size, u32 *val)
			       int where, int size, u32 *val)
{
{
	struct pci_dn *pdn = PCI_DN(dn);

	if (!pdn)
	if (!pdn)
		return PCIBIOS_DEVICE_NOT_FOUND;
		return PCIBIOS_DEVICE_NOT_FOUND;


	if (pnv_eeh_cfg_blocked(dn)) {
	if (pnv_eeh_cfg_blocked(pdn)) {
		*val = 0xFFFFFFFF;
		*val = 0xFFFFFFFF;
		return PCIBIOS_SET_FAILED;
		return PCIBIOS_SET_FAILED;
	}
	}
@@ -1128,15 +1126,13 @@ static int pnv_eeh_read_config(struct device_node *dn,
	return pnv_pci_cfg_read(pdn, where, size, val);
	return pnv_pci_cfg_read(pdn, where, size, val);
}
}


static int pnv_eeh_write_config(struct device_node *dn,
static int pnv_eeh_write_config(struct pci_dn *pdn,
				int where, int size, u32 val)
				int where, int size, u32 val)
{
{
	struct pci_dn *pdn = PCI_DN(dn);

	if (!pdn)
	if (!pdn)
		return PCIBIOS_DEVICE_NOT_FOUND;
		return PCIBIOS_DEVICE_NOT_FOUND;


	if (pnv_eeh_cfg_blocked(dn))
	if (pnv_eeh_cfg_blocked(pdn))
		return PCIBIOS_SET_FAILED;
		return PCIBIOS_SET_FAILED;


	return pnv_pci_cfg_write(pdn, where, size, val);
	return pnv_pci_cfg_write(pdn, where, size, val);
@@ -1484,9 +1480,9 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
	return ret;
	return ret;
}
}


static int pnv_eeh_restore_config(struct device_node *dn)
static int pnv_eeh_restore_config(struct pci_dn *pdn)
{
{
	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
	struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
	struct pnv_phb *phb;
	struct pnv_phb *phb;
	s64 ret;
	s64 ret;


+4 −12
Original line number Original line Diff line number Diff line
@@ -651,37 +651,29 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)


/**
/**
 * pseries_eeh_read_config - Read PCI config space
 * pseries_eeh_read_config - Read PCI config space
 * @dn: device node
 * @pdn: PCI device node
 * @where: PCI address
 * @where: PCI address
 * @size: size to read
 * @size: size to read
 * @val: return value
 * @val: return value
 *
 *
 * Read config space from the speicifed device
 * Read config space from the speicifed device
 */
 */
static int pseries_eeh_read_config(struct device_node *dn, int where, int size, u32 *val)
static int pseries_eeh_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
{
{
	struct pci_dn *pdn;

	pdn = PCI_DN(dn);

	return rtas_read_config(pdn, where, size, val);
	return rtas_read_config(pdn, where, size, val);
}
}


/**
/**
 * pseries_eeh_write_config - Write PCI config space
 * pseries_eeh_write_config - Write PCI config space
 * @dn: device node
 * @pdn: PCI device node
 * @where: PCI address
 * @where: PCI address
 * @size: size to write
 * @size: size to write
 * @val: value to be written
 * @val: value to be written
 *
 *
 * Write config space to the specified device
 * Write config space to the specified device
 */
 */
static int pseries_eeh_write_config(struct device_node *dn, int where, int size, u32 val)
static int pseries_eeh_write_config(struct pci_dn *pdn, int where, int size, u32 val)
{
{
	struct pci_dn *pdn;

	pdn = PCI_DN(dn);

	return rtas_write_config(pdn, where, size, val);
	return rtas_write_config(pdn, where, size, val);
}
}