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

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

powerpc/eeh: Remove device_node dependency



The patch removes struct eeh_dev::dn and the corresponding helper
functions: eeh_dev_to_of_node() and of_node_to_eeh_dev(). Instead,
eeh_dev_to_pdn() and pdn_to_eeh_dev() should be used to get the
pdn, which might contain device_node on PowerNV platform.

Signed-off-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 0bd78587
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@

struct pci_dev;
struct pci_bus;
struct device_node;
struct pci_dn;

#ifdef CONFIG_EEH
@@ -137,17 +136,11 @@ struct eeh_dev {
	struct eeh_pe *pe;		/* Associated PE		*/
	struct list_head list;		/* Form link list in the PE	*/
	struct pci_controller *phb;	/* Associated PHB		*/
	struct device_node *dn;		/* Associated device node	*/
	struct pci_dn *pdn;		/* Associated PCI device node	*/
	struct pci_dev *pdev;		/* Associated PCI device	*/
	struct pci_bus *bus;		/* PCI bus for partial hotplug	*/
};

static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
{
	return edev ? edev->dn : NULL;
}

static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
{
	return edev ? edev->pdn : NULL;
+0 −14
Original line number Diff line number Diff line
@@ -201,25 +201,11 @@ static inline int pci_device_from_OF_node(struct device_node *np,
}

#if defined(CONFIG_EEH)
static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
{
	/*
	 * For those OF nodes whose parent isn't PCI bridge, they
	 * don't have PCI_DN actually. So we have to skip them for
	 * any EEH operations.
	 */
	if (!dn || !PCI_DN(dn))
		return NULL;

	return PCI_DN(dn)->edev;
}

static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
{
	return pdn ? pdn->edev : NULL;
}
#else
#define of_node_to_eeh_dev(x)	(NULL)
#define pdn_to_eeh_dev(x)	(NULL)
#endif

+13 −11
Original line number Diff line number Diff line
@@ -418,11 +418,11 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
	int ret;
	int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
	unsigned long flags;
	struct device_node *dn;
	struct pci_dn *pdn;
	struct pci_dev *dev;
	struct eeh_pe *pe, *parent_pe, *phb_pe;
	int rc = 0;
	const char *location;
	const char *location = NULL;

	eeh_stats.total_mmio_ffs++;

@@ -433,15 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
		eeh_stats.no_dn++;
		return 0;
	}
	dn = eeh_dev_to_of_node(edev);
	dev = eeh_dev_to_pci_dev(edev);
	pe = eeh_dev_to_pe(edev);

	/* Access to IO BARs might get this far and still not want checking. */
	if (!pe) {
		eeh_stats.ignored_check++;
		pr_debug("EEH: Ignored check for %s %s\n",
			eeh_pci_name(dev), dn->full_name);
		pr_debug("EEH: Ignored check for %s\n",
			eeh_pci_name(dev));
		return 0;
	}

@@ -477,10 +476,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
	if (pe->state & EEH_PE_ISOLATED) {
		pe->check_count++;
		if (pe->check_count % EEH_MAX_FAILS == 0) {
			location = of_get_property(dn, "ibm,loc-code", NULL);
			pdn = eeh_dev_to_pdn(edev);
			if (pdn->node)
				location = of_get_property(pdn->node, "ibm,loc-code", NULL);
			printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
				"location=%s driver=%s pci addr=%s\n",
				pe->check_count, location,
				pe->check_count,
				location ? location : "unknown",
				eeh_driver_name(dev), eeh_pci_name(dev));
			printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
				eeh_driver_name(dev));
@@ -1035,7 +1037,7 @@ int eeh_init(void)
core_initcall_sync(eeh_init);

/**
 * eeh_add_device_early - Enable EEH for the indicated device_node
 * eeh_add_device_early - Enable EEH for the indicated device node
 * @pdn: PCI device node for which to set up EEH
 *
 * This routine must be used to perform EEH initialization for PCI
@@ -1093,7 +1095,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
 */
void eeh_add_device_late(struct pci_dev *dev)
{
	struct device_node *dn;
	struct pci_dn *pdn;
	struct eeh_dev *edev;

	if (!dev || !eeh_enabled())
@@ -1101,8 +1103,8 @@ void eeh_add_device_late(struct pci_dev *dev)

	pr_debug("EEH: Adding device %s\n", pci_name(dev));

	dn = pci_device_to_OF_node(dev);
	edev = of_node_to_eeh_dev(dn);
	pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
	edev = pdn_to_eeh_dev(pdn);
	if (edev->pdev == dev) {
		pr_debug("EEH: Already referenced !\n");
		return;
+11 −14
Original line number Diff line number Diff line
@@ -171,30 +171,27 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,

static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
{
	struct device_node *dn;
	struct pci_dn *pdn;
	struct eeh_dev *edev;
	int i;

	dn = pci_device_to_OF_node(dev);
	if (!dn) {
	pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
	if (!pdn) {
		pr_warn("PCI: no pci dn found for dev=%s\n",
			pci_name(dev));
		return;
	}

	edev = of_node_to_eeh_dev(dn);
	edev = pdn_to_eeh_dev(pdn);
	if (!edev) {
		pr_warn("PCI: no EEH dev found for dn=%s\n",
			dn->full_name);
		pr_warn("PCI: no EEH dev found for %s\n",
			pci_name(dev));
		return;
	}

	/* Skip any devices for which EEH is not enabled. */
	if (!edev->pe) {
#ifdef DEBUG
		pr_info("PCI: skip building address cache for=%s - %s\n",
			pci_name(dev), dn->full_name);
#endif
		dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
		return;
	}

@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
 */
void eeh_addr_cache_build(void)
{
	struct device_node *dn;
	struct pci_dn *pdn;
	struct eeh_dev *edev;
	struct pci_dev *dev = NULL;

	spin_lock_init(&pci_io_addr_cache_root.piar_lock);

	for_each_pci_dev(dev) {
		dn = pci_device_to_OF_node(dev);
		if (!dn)
		pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
		if (!pdn)
			continue;

		edev = of_node_to_eeh_dev(dn);
		edev = pdn_to_eeh_dev(pdn);
		if (!edev)
			continue;

+0 −22
Original line number Diff line number Diff line
@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev)
	module_put(pdev->driver->driver.owner);
}

#if 0
static void print_device_node_tree(struct pci_dn *pdn, int dent)
{
	int i;
	struct device_node *pc;

	if (!pdn)
		return;
	for (i = 0; i < dent; i++)
		printk(" ");
	printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
		pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
		pdn->eeh_pe_config_addr, pdn->node->full_name);
	dent += 3;
	pc = pdn->node->child;
	while (pc) {
		print_device_node_tree(PCI_DN(pc), dent);
		pc = pc->sibling;
	}
}
#endif

/**
 * eeh_disable_irq - Disable interrupt for the recovering device
 * @dev: PCI device
Loading