aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci-common.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2007-06-27 14:09:43 -0400
committerKumar Gala <galak@kernel.crashing.org>2007-06-29 02:58:45 -0400
commita4c9e328279d55622d56507629d6b8942e8cc9c9 (patch)
tree6e1791cfdfd6c0b9e56f1b154fca715b9aed9fbd /arch/powerpc/kernel/pci-common.c
parent58083dade53cd434e134cd26ae5e89061f6de1ff (diff)
[POWERPC] Use ppc64 style list management for pci_controller on ppc32
Use the ppc64 style list management and allocation functions for pci_controllers. This makes the pci_controller structs just a bit more common between ppc32 & ppc64. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r--arch/powerpc/kernel/pci-common.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index b518b880d2eb..295cbb18a4f2 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -36,6 +36,62 @@
36#define DBG(fmt...) 36#define DBG(fmt...)
37#endif 37#endif
38 38
39static DEFINE_SPINLOCK(hose_spinlock);
40
41/* XXX kill that some day ... */
42int global_phb_number; /* Global phb counter */
43
44extern struct list_head hose_list;
45
46/*
47 * pci_controller(phb) initialized common variables.
48 */
49static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
50{
51 memset(hose, 0, sizeof(struct pci_controller));
52
53 spin_lock(&hose_spinlock);
54 hose->global_number = global_phb_number++;
55 list_add_tail(&hose->list_node, &hose_list);
56 spin_unlock(&hose_spinlock);
57}
58
59struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
60{
61 struct pci_controller *phb;
62
63 if (mem_init_done)
64 phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
65 else
66 phb = alloc_bootmem(sizeof (struct pci_controller));
67 if (phb == NULL)
68 return NULL;
69 pci_setup_pci_controller(phb);
70 phb->arch_data = dev;
71 phb->is_dynamic = mem_init_done;
72#ifdef CONFIG_PPC64
73 if (dev) {
74 int nid = of_node_to_nid(dev);
75
76 if (nid < 0 || !node_online(nid))
77 nid = -1;
78
79 PHB_SET_NODE(phb, nid);
80 }
81#endif
82 return phb;
83}
84
85void pcibios_free_controller(struct pci_controller *phb)
86{
87 spin_lock(&hose_spinlock);
88 list_del(&phb->list_node);
89 spin_unlock(&hose_spinlock);
90
91 if (phb->is_dynamic)
92 kfree(phb);
93}
94
39/* 95/*
40 * Return the domain number for this bus. 96 * Return the domain number for this bus.
41 */ 97 */
@@ -53,6 +109,28 @@ int pci_domain_nr(struct pci_bus *bus)
53EXPORT_SYMBOL(pci_domain_nr); 109EXPORT_SYMBOL(pci_domain_nr);
54 110
55#ifdef CONFIG_PPC_OF 111#ifdef CONFIG_PPC_OF
112
113/* This routine is meant to be used early during boot, when the
114 * PCI bus numbers have not yet been assigned, and you need to
115 * issue PCI config cycles to an OF device.
116 * It could also be used to "fix" RTAS config cycles if you want
117 * to set pci_assign_all_buses to 1 and still use RTAS for PCI
118 * config cycles.
119 */
120struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
121{
122 if (!have_of)
123 return NULL;
124 while(node) {
125 struct pci_controller *hose, *tmp;
126 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
127 if (hose->arch_data == node)
128 return hose;
129 node = node->parent;
130 }
131 return NULL;
132}
133
56static ssize_t pci_show_devspec(struct device *dev, 134static ssize_t pci_show_devspec(struct device *dev,
57 struct device_attribute *attr, char *buf) 135 struct device_attribute *attr, char *buf)
58{ 136{