Commit b5d937de authored by Grant Likely's avatar Grant Likely

powerpc/pci: Make both ppc32 and ppc64 use sysdata for pci_controller

Currently, ppc32 uses sysdata for the pci_controller pointer, and
ppc64 uses it to hold the device_node pointer.  This patch moves the
of_node pointer into (struct pci_bus*)->dev.of_node and
(struct pci_dev*)->dev.of_node so that sysdata can be converted to always
use the pci_controller pointer instead.  It also fixes up the
allocating of pci devices so that the of_node pointer gets assigned
consistently and increments the ref count.
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 04bea68b
...@@ -332,6 +332,7 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose) ...@@ -332,6 +332,7 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose)
hose->global_number); hose->global_number);
return; return;
} }
bus.dev->of_node = of_node_get(node);
bus->secondary = hose->first_busno; bus->secondary = hose->first_busno;
hose->bus = bus; hose->bus = bus;
......
...@@ -164,13 +164,13 @@ extern void setup_indirect_pci(struct pci_controller* hose, ...@@ -164,13 +164,13 @@ extern void setup_indirect_pci(struct pci_controller* hose,
resource_size_t cfg_addr, resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags); resource_size_t cfg_data, u32 flags);
#ifndef CONFIG_PPC64
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{ {
return bus->sysdata; return bus->sysdata;
} }
#ifndef CONFIG_PPC64
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
{ {
struct pci_controller *host; struct pci_controller *host;
...@@ -228,19 +228,10 @@ extern void * update_dn_pci_info(struct device_node *dn, void *data); ...@@ -228,19 +228,10 @@ extern void * update_dn_pci_info(struct device_node *dn, void *data);
/* Get a device_node from a pci_dev. This code must be fast except /* Get a device_node from a pci_dev. This code must be fast except
* in the case where the sysdata is incorrect and needs to be fixed * in the case where the sysdata is incorrect and needs to be fixed
* up (this will only happen once). * up (this will only happen once). */
* In this case the sysdata will have been inherited from a PCI host
* bridge or a PCI-PCI bridge further up the tree, so it will point
* to a valid struct pci_dn, just not the one we want.
*/
static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
{ {
struct device_node *dn = dev->sysdata; return dev->dev.of_node ? dev->dev.of_node : fetch_dev_dn(dev);
struct pci_dn *pdn = dn->data;
if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number)
return dn; /* fast path. sysdata is good */
return fetch_dev_dn(dev);
} }
static inline int pci_device_from_OF_node(struct device_node *np, static inline int pci_device_from_OF_node(struct device_node *np,
...@@ -258,7 +249,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) ...@@ -258,7 +249,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
if (bus->self) if (bus->self)
return pci_device_to_OF_node(bus->self); return pci_device_to_OF_node(bus->self);
else else
return bus->sysdata; /* Must be root bus (PHB) */ return bus->dev.of_node; /* Must be root bus (PHB) */
} }
/** Find the bus corresponding to the indicated device node */ /** Find the bus corresponding to the indicated device node */
...@@ -270,14 +261,6 @@ extern void pcibios_remove_pci_devices(struct pci_bus *bus); ...@@ -270,14 +261,6 @@ extern void pcibios_remove_pci_devices(struct pci_bus *bus);
/** Discover new pci devices under this bus, and add them */ /** Discover new pci devices under this bus, and add them */
extern void pcibios_add_pci_devices(struct pci_bus *bus); extern void pcibios_add_pci_devices(struct pci_bus *bus);
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
struct device_node *busdn = bus->sysdata;
BUG_ON(busdn == NULL);
return PCI_DN(busdn)->phb;
}
extern void isa_bridge_find_early(struct pci_controller *hose); extern void isa_bridge_find_early(struct pci_controller *hose);
......
...@@ -201,7 +201,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, ...@@ -201,7 +201,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
extern void pcibios_setup_bus_devices(struct pci_bus *bus); extern void pcibios_setup_bus_devices(struct pci_bus *bus);
extern void pcibios_setup_bus_self(struct pci_bus *bus); extern void pcibios_setup_bus_self(struct pci_bus *bus);
extern void pcibios_setup_phb_io_space(struct pci_controller *hose); extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
extern void pcibios_scan_phb(struct pci_controller *hose, void *sysdata); extern void pcibios_scan_phb(struct pci_controller *hose);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_PCI_H */ #endif /* __ASM_POWERPC_PCI_H */
...@@ -74,7 +74,7 @@ static int __devinit of_pci_phb_probe(struct platform_device *dev, ...@@ -74,7 +74,7 @@ static int __devinit of_pci_phb_probe(struct platform_device *dev,
#endif /* CONFIG_EEH */ #endif /* CONFIG_EEH */
/* Scan the bus */ /* Scan the bus */
pcibios_scan_phb(phb, dev->dev.of_node); pcibios_scan_phb(phb);
if (phb->bus == NULL) if (phb->bus == NULL)
return -ENXIO; return -ENXIO;
......
...@@ -1688,13 +1688,8 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn, ...@@ -1688,13 +1688,8 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn,
/** /**
* pci_scan_phb - Given a pci_controller, setup and scan the PCI bus * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
* @hose: Pointer to the PCI host controller instance structure * @hose: Pointer to the PCI host controller instance structure
* @sysdata: value to use for sysdata pointer. ppc32 and ppc64 differ here
*
* Note: the 'data' pointer is a temporary measure. As 32 and 64 bit
* pci code gets merged, this parameter should become unnecessary because
* both will use the same value.
*/ */
void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata) void __devinit pcibios_scan_phb(struct pci_controller *hose)
{ {
struct pci_bus *bus; struct pci_bus *bus;
struct device_node *node = hose->dn; struct device_node *node = hose->dn;
...@@ -1704,13 +1699,13 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata) ...@@ -1704,13 +1699,13 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata)
node ? node->full_name : "<NO NAME>"); node ? node->full_name : "<NO NAME>");
/* Create an empty bus for the toplevel */ /* Create an empty bus for the toplevel */
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
sysdata);
if (bus == NULL) { if (bus == NULL) {
pr_err("Failed to create bus for PCI domain %04x\n", pr_err("Failed to create bus for PCI domain %04x\n",
hose->global_number); hose->global_number);
return; return;
} }
bus->dev.of_node = of_node_get(node);
bus->secondary = hose->first_busno; bus->secondary = hose->first_busno;
hose->bus = bus; hose->bus = bus;
......
...@@ -381,7 +381,7 @@ static int __init pcibios_init(void) ...@@ -381,7 +381,7 @@ static int __init pcibios_init(void)
if (pci_assign_all_buses) if (pci_assign_all_buses)
hose->first_busno = next_busno; hose->first_busno = next_busno;
hose->last_busno = 0xff; hose->last_busno = 0xff;
pcibios_scan_phb(hose, hose); pcibios_scan_phb(hose);
pci_bus_add_devices(hose->bus); pci_bus_add_devices(hose->bus);
if (pci_assign_all_buses || next_busno <= hose->last_busno) if (pci_assign_all_buses || next_busno <= hose->last_busno)
next_busno = hose->last_busno + pcibios_assign_bus_offset; next_busno = hose->last_busno + pcibios_assign_bus_offset;
......
...@@ -64,7 +64,7 @@ static int __init pcibios_init(void) ...@@ -64,7 +64,7 @@ static int __init pcibios_init(void)
/* Scan all of the recorded PCI controllers. */ /* Scan all of the recorded PCI controllers. */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
pcibios_scan_phb(hose, hose->dn); pcibios_scan_phb(hose);
pci_bus_add_devices(hose->bus); pci_bus_add_devices(hose->bus);
} }
...@@ -242,10 +242,10 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, ...@@ -242,10 +242,10 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
break; break;
bus = NULL; bus = NULL;
} }
if (bus == NULL || bus->sysdata == NULL) if (bus == NULL || bus->dev.of_node == NULL)
return -ENODEV; return -ENODEV;
hose_node = (struct device_node *)bus->sysdata; hose_node = bus->dev.of_node;
hose = PCI_DN(hose_node)->phb; hose = PCI_DN(hose_node)->phb;
switch (which) { switch (which) {
......
...@@ -161,7 +161,7 @@ static void *is_devfn_node(struct device_node *dn, void *data) ...@@ -161,7 +161,7 @@ static void *is_devfn_node(struct device_node *dn, void *data)
/* /*
* This is the "slow" path for looking up a device_node from a * This is the "slow" path for looking up a device_node from a
* pci_dev. It will hunt for the device under its parent's * pci_dev. It will hunt for the device under its parent's
* phb and then update sysdata for a future fastpath. * phb and then update of_node pointer.
* *
* It may also do fixups on the actual device since this happens * It may also do fixups on the actual device since this happens
* on the first read/write. * on the first read/write.
...@@ -170,16 +170,19 @@ static void *is_devfn_node(struct device_node *dn, void *data) ...@@ -170,16 +170,19 @@ static void *is_devfn_node(struct device_node *dn, void *data)
* In this case it may probe for real hardware ("just in case") * In this case it may probe for real hardware ("just in case")
* and add a device_node to the device tree if necessary. * and add a device_node to the device tree if necessary.
* *
* Is this function necessary anymore now that dev->dev.of_node is
* used to store the node pointer?
*
*/ */
struct device_node *fetch_dev_dn(struct pci_dev *dev) struct device_node *fetch_dev_dn(struct pci_dev *dev)
{ {
struct device_node *orig_dn = dev->sysdata; struct device_node *orig_dn = dev->dev.of_node;
struct device_node *dn; struct device_node *dn;
unsigned long searchval = (dev->bus->number << 8) | dev->devfn; unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
if (dn) if (dn)
dev->sysdata = dn; dev->dev.of_node = dn;
return dn; return dn;
} }
EXPORT_SYMBOL(fetch_dev_dn); EXPORT_SYMBOL(fetch_dev_dn);
......
...@@ -135,7 +135,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -135,7 +135,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pr_debug(" create device, devfn: %x, type: %s\n", devfn, type); pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
dev->bus = bus; dev->bus = bus;
dev->sysdata = node; dev->dev.of_node = of_node_get(node);
dev->dev.parent = bus->bridge; dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type; dev->dev.bus = &pci_bus_type;
dev->devfn = devfn; dev->devfn = devfn;
...@@ -238,7 +238,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node, ...@@ -238,7 +238,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
bus->primary = dev->bus->number; bus->primary = dev->bus->number;
bus->subordinate = busrange[1]; bus->subordinate = busrange[1];
bus->bridge_ctl = 0; bus->bridge_ctl = 0;
bus->sysdata = node; bus->dev.of_node = of_node_get(node);
/* parse ranges property */ /* parse ranges property */
/* PCI #address-cells == 3 and #size-cells == 2 always */ /* PCI #address-cells == 3 and #size-cells == 2 always */
......
...@@ -149,7 +149,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) ...@@ -149,7 +149,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
if (dn->child) if (dn->child)
eeh_add_device_tree_early(dn); eeh_add_device_tree_early(dn);
pcibios_scan_phb(phb, dn); pcibios_scan_phb(phb);
pcibios_finish_adding_to_bus(phb->bus); pcibios_finish_adding_to_bus(phb->bus);
return phb; return phb;
......
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