Commit 3532a741 authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/powernv: Use pci_dn, not device_node, in PCI config accessor

The PCI config accessors previously relied on device_node.  Unfortunately,
VFs don't have a corresponding device_node, so change the accessors to use
pci_dn instead.

[bhelgaas: changelog]
Signed-off-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent cca87d30
...@@ -1038,21 +1038,31 @@ static inline bool pnv_eeh_cfg_blocked(struct device_node *dn) ...@@ -1038,21 +1038,31 @@ static inline bool pnv_eeh_cfg_blocked(struct device_node *dn)
static int pnv_eeh_read_config(struct device_node *dn, static int pnv_eeh_read_config(struct device_node *dn,
int where, int size, u32 *val) int where, int size, u32 *val)
{ {
struct pci_dn *pdn = PCI_DN(dn);
if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND;
if (pnv_eeh_cfg_blocked(dn)) { if (pnv_eeh_cfg_blocked(dn)) {
*val = 0xFFFFFFFF; *val = 0xFFFFFFFF;
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;
} }
return pnv_pci_cfg_read(dn, 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 device_node *dn,
int where, int size, u32 val) int where, int size, u32 val)
{ {
struct pci_dn *pdn = PCI_DN(dn);
if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND;
if (pnv_eeh_cfg_blocked(dn)) if (pnv_eeh_cfg_blocked(dn))
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;
return pnv_pci_cfg_write(dn, where, size, val); return pnv_pci_cfg_write(pdn, where, size, val);
} }
static void pnv_eeh_dump_hub_diag_common(struct OpalIoP7IOCErrorData *data) static void pnv_eeh_dump_hub_diag_common(struct OpalIoP7IOCErrorData *data)
......
...@@ -366,9 +366,9 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) ...@@ -366,9 +366,9 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
spin_unlock_irqrestore(&phb->lock, flags); spin_unlock_irqrestore(&phb->lock, flags);
} }
static void pnv_pci_config_check_eeh(struct pnv_phb *phb, static void pnv_pci_config_check_eeh(struct pci_dn *pdn)
struct device_node *dn)
{ {
struct pnv_phb *phb = pdn->phb->private_data;
u8 fstate; u8 fstate;
__be16 pcierr; __be16 pcierr;
int pe_no; int pe_no;
...@@ -379,7 +379,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, ...@@ -379,7 +379,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
* setup that yet. So all ER errors should be mapped to * setup that yet. So all ER errors should be mapped to
* reserved PE. * reserved PE.
*/ */
pe_no = PCI_DN(dn)->pe_number; pe_no = pdn->pe_number;
if (pe_no == IODA_INVALID_PE) { if (pe_no == IODA_INVALID_PE) {
if (phb->type == PNV_PHB_P5IOC2) if (phb->type == PNV_PHB_P5IOC2)
pe_no = 0; pe_no = 0;
...@@ -407,8 +407,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, ...@@ -407,8 +407,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
} }
cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n", cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n",
(PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn), (pdn->busno << 8) | (pdn->devfn), pe_no, fstate);
pe_no, fstate);
/* Clear the frozen state if applicable */ /* Clear the frozen state if applicable */
if (fstate == OPAL_EEH_STOPPED_MMIO_FREEZE || if (fstate == OPAL_EEH_STOPPED_MMIO_FREEZE ||
...@@ -425,10 +424,9 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, ...@@ -425,10 +424,9 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
} }
} }
int pnv_pci_cfg_read(struct device_node *dn, int pnv_pci_cfg_read(struct pci_dn *pdn,
int where, int size, u32 *val) int where, int size, u32 *val)
{ {
struct pci_dn *pdn = PCI_DN(dn);
struct pnv_phb *phb = pdn->phb->private_data; struct pnv_phb *phb = pdn->phb->private_data;
u32 bdfn = (pdn->busno << 8) | pdn->devfn; u32 bdfn = (pdn->busno << 8) | pdn->devfn;
s64 rc; s64 rc;
...@@ -462,10 +460,9 @@ int pnv_pci_cfg_read(struct device_node *dn, ...@@ -462,10 +460,9 @@ int pnv_pci_cfg_read(struct device_node *dn,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
int pnv_pci_cfg_write(struct device_node *dn, int pnv_pci_cfg_write(struct pci_dn *pdn,
int where, int size, u32 val) int where, int size, u32 val)
{ {
struct pci_dn *pdn = PCI_DN(dn);
struct pnv_phb *phb = pdn->phb->private_data; struct pnv_phb *phb = pdn->phb->private_data;
u32 bdfn = (pdn->busno << 8) | pdn->devfn; u32 bdfn = (pdn->busno << 8) | pdn->devfn;
...@@ -489,18 +486,17 @@ int pnv_pci_cfg_write(struct device_node *dn, ...@@ -489,18 +486,17 @@ int pnv_pci_cfg_write(struct device_node *dn,
} }
#if CONFIG_EEH #if CONFIG_EEH
static bool pnv_pci_cfg_check(struct pci_controller *hose, static bool pnv_pci_cfg_check(struct pci_dn *pdn)
struct device_node *dn)
{ {
struct eeh_dev *edev = NULL; struct eeh_dev *edev = NULL;
struct pnv_phb *phb = hose->private_data; struct pnv_phb *phb = pdn->phb->private_data;
/* EEH not enabled ? */ /* EEH not enabled ? */
if (!(phb->flags & PNV_PHB_FLAG_EEH)) if (!(phb->flags & PNV_PHB_FLAG_EEH))
return true; return true;
/* PE reset or device removed ? */ /* PE reset or device removed ? */
edev = of_node_to_eeh_dev(dn); edev = pdn->edev;
if (edev) { if (edev) {
if (edev->pe && if (edev->pe &&
(edev->pe->state & EEH_PE_CFG_BLOCKED)) (edev->pe->state & EEH_PE_CFG_BLOCKED))
...@@ -513,8 +509,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose, ...@@ -513,8 +509,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose,
return true; return true;
} }
#else #else
static inline pnv_pci_cfg_check(struct pci_controller *hose, static inline pnv_pci_cfg_check(struct pci_dn *pdn)
struct device_node *dn)
{ {
return true; return true;
} }
...@@ -524,32 +519,26 @@ static int pnv_pci_read_config(struct pci_bus *bus, ...@@ -524,32 +519,26 @@ static int pnv_pci_read_config(struct pci_bus *bus,
unsigned int devfn, unsigned int devfn,
int where, int size, u32 *val) int where, int size, u32 *val)
{ {
struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
struct pci_dn *pdn; struct pci_dn *pdn;
struct pnv_phb *phb; struct pnv_phb *phb;
bool found = false;
int ret; int ret;
*val = 0xFFFFFFFF; *val = 0xFFFFFFFF;
for (dn = busdn->child; dn; dn = dn->sibling) { pdn = pci_get_pdn_by_devfn(bus, devfn);
pdn = PCI_DN(dn); if (!pdn)
if (pdn && pdn->devfn == devfn) { return PCIBIOS_DEVICE_NOT_FOUND;
phb = pdn->phb->private_data;
found = true;
break;
}
}
if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) if (!pnv_pci_cfg_check(pdn))
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
ret = pnv_pci_cfg_read(dn, where, size, val); ret = pnv_pci_cfg_read(pdn, where, size, val);
if (phb->flags & PNV_PHB_FLAG_EEH) { phb = pdn->phb->private_data;
if (phb->flags & PNV_PHB_FLAG_EEH && pdn->edev) {
if (*val == EEH_IO_ERROR_VALUE(size) && if (*val == EEH_IO_ERROR_VALUE(size) &&
eeh_dev_check_failure(of_node_to_eeh_dev(dn))) eeh_dev_check_failure(pdn->edev))
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} else { } else {
pnv_pci_config_check_eeh(phb, dn); pnv_pci_config_check_eeh(pdn);
} }
return ret; return ret;
...@@ -559,27 +548,21 @@ static int pnv_pci_write_config(struct pci_bus *bus, ...@@ -559,27 +548,21 @@ static int pnv_pci_write_config(struct pci_bus *bus,
unsigned int devfn, unsigned int devfn,
int where, int size, u32 val) int where, int size, u32 val)
{ {
struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
struct pci_dn *pdn; struct pci_dn *pdn;
struct pnv_phb *phb; struct pnv_phb *phb;
bool found = false;
int ret; int ret;
for (dn = busdn->child; dn; dn = dn->sibling) { pdn = pci_get_pdn_by_devfn(bus, devfn);
pdn = PCI_DN(dn); if (!pdn)
if (pdn && pdn->devfn == devfn) { return PCIBIOS_DEVICE_NOT_FOUND;
phb = pdn->phb->private_data;
found = true;
break;
}
}
if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) if (!pnv_pci_cfg_check(pdn))
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
ret = pnv_pci_cfg_write(dn, where, size, val); ret = pnv_pci_cfg_write(pdn, where, size, val);
phb = pdn->phb->private_data;
if (!(phb->flags & PNV_PHB_FLAG_EEH)) if (!(phb->flags & PNV_PHB_FLAG_EEH))
pnv_pci_config_check_eeh(phb, dn); pnv_pci_config_check_eeh(pdn);
return ret; return ret;
} }
......
...@@ -196,9 +196,9 @@ extern struct pci_ops pnv_pci_ops; ...@@ -196,9 +196,9 @@ extern struct pci_ops pnv_pci_ops;
void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
unsigned char *log_buff); unsigned char *log_buff);
int pnv_pci_cfg_read(struct device_node *dn, int pnv_pci_cfg_read(struct pci_dn *pdn,
int where, int size, u32 *val); int where, int size, u32 *val);
int pnv_pci_cfg_write(struct device_node *dn, int pnv_pci_cfg_write(struct pci_dn *pdn,
int where, int size, u32 val); int where, int size, u32 val);
extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
void *tce_mem, u64 tce_size, void *tce_mem, u64 tce_size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment