diff options
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 78 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 61 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 66 | ||||
-rw-r--r-- | include/asm-powerpc/pci-bridge.h | 11 |
4 files changed, 94 insertions, 122 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 | ||
39 | static DEFINE_SPINLOCK(hose_spinlock); | ||
40 | |||
41 | /* XXX kill that some day ... */ | ||
42 | int global_phb_number; /* Global phb counter */ | ||
43 | |||
44 | extern struct list_head hose_list; | ||
45 | |||
46 | /* | ||
47 | * pci_controller(phb) initialized common variables. | ||
48 | */ | ||
49 | static 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 | |||
59 | struct 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 | |||
85 | void 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) | |||
53 | EXPORT_SYMBOL(pci_domain_nr); | 109 | EXPORT_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 | */ | ||
120 | struct 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 | |||
56 | static ssize_t pci_show_devspec(struct device *dev, | 134 | static ssize_t pci_show_devspec(struct device *dev, |
57 | struct device_attribute *attr, char *buf) | 135 | struct device_attribute *attr, char *buf) |
58 | { | 136 | { |
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 3dd931ecce91..10d8a3542cf6 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -55,8 +55,7 @@ static u8* pci_to_OF_bus_map; | |||
55 | */ | 55 | */ |
56 | int pci_assign_all_buses; | 56 | int pci_assign_all_buses; |
57 | 57 | ||
58 | struct pci_controller* hose_head; | 58 | LIST_HEAD(hose_list); |
59 | struct pci_controller** hose_tail = &hose_head; | ||
60 | 59 | ||
61 | static int pci_bus_count; | 60 | static int pci_bus_count; |
62 | 61 | ||
@@ -607,25 +606,6 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
607 | return 0; | 606 | return 0; |
608 | } | 607 | } |
609 | 608 | ||
610 | static int next_controller_index; | ||
611 | |||
612 | struct pci_controller * __init | ||
613 | pcibios_alloc_controller(struct device_node *dev) | ||
614 | { | ||
615 | struct pci_controller *hose; | ||
616 | |||
617 | hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); | ||
618 | memset(hose, 0, sizeof(struct pci_controller)); | ||
619 | |||
620 | *hose_tail = hose; | ||
621 | hose_tail = &hose->next; | ||
622 | |||
623 | hose->global_number = next_controller_index++; | ||
624 | hose->arch_data = dev; | ||
625 | |||
626 | return hose; | ||
627 | } | ||
628 | |||
629 | #ifdef CONFIG_PPC_OF | 609 | #ifdef CONFIG_PPC_OF |
630 | /* | 610 | /* |
631 | * Functions below are used on OpenFirmware machines. | 611 | * Functions below are used on OpenFirmware machines. |
@@ -671,7 +651,7 @@ void | |||
671 | pcibios_make_OF_bus_map(void) | 651 | pcibios_make_OF_bus_map(void) |
672 | { | 652 | { |
673 | int i; | 653 | int i; |
674 | struct pci_controller* hose; | 654 | struct pci_controller *hose, *tmp; |
675 | struct property *map_prop; | 655 | struct property *map_prop; |
676 | struct device_node *dn; | 656 | struct device_node *dn; |
677 | 657 | ||
@@ -688,7 +668,7 @@ pcibios_make_OF_bus_map(void) | |||
688 | pci_to_OF_bus_map[i] = 0xff; | 668 | pci_to_OF_bus_map[i] = 0xff; |
689 | 669 | ||
690 | /* For each hose, we begin searching bridges */ | 670 | /* For each hose, we begin searching bridges */ |
691 | for(hose=hose_head; hose; hose=hose->next) { | 671 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
692 | struct device_node* node; | 672 | struct device_node* node; |
693 | node = (struct device_node *)hose->arch_data; | 673 | node = (struct device_node *)hose->arch_data; |
694 | if (!node) | 674 | if (!node) |
@@ -819,27 +799,6 @@ pci_device_to_OF_node(struct pci_dev *dev) | |||
819 | } | 799 | } |
820 | EXPORT_SYMBOL(pci_device_to_OF_node); | 800 | EXPORT_SYMBOL(pci_device_to_OF_node); |
821 | 801 | ||
822 | /* This routine is meant to be used early during boot, when the | ||
823 | * PCI bus numbers have not yet been assigned, and you need to | ||
824 | * issue PCI config cycles to an OF device. | ||
825 | * It could also be used to "fix" RTAS config cycles if you want | ||
826 | * to set pci_assign_all_buses to 1 and still use RTAS for PCI | ||
827 | * config cycles. | ||
828 | */ | ||
829 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | ||
830 | { | ||
831 | if (!have_of) | ||
832 | return NULL; | ||
833 | while(node) { | ||
834 | struct pci_controller* hose; | ||
835 | for (hose=hose_head;hose;hose=hose->next) | ||
836 | if (hose->arch_data == node) | ||
837 | return hose; | ||
838 | node=node->parent; | ||
839 | } | ||
840 | return NULL; | ||
841 | } | ||
842 | |||
843 | static int | 802 | static int |
844 | find_OF_pci_device_filter(struct device_node* node, void* data) | 803 | find_OF_pci_device_filter(struct device_node* node, void* data) |
845 | { | 804 | { |
@@ -1248,14 +1207,14 @@ pcibios_fixup_p2p_bridges(void) | |||
1248 | static int __init | 1207 | static int __init |
1249 | pcibios_init(void) | 1208 | pcibios_init(void) |
1250 | { | 1209 | { |
1251 | struct pci_controller *hose; | 1210 | struct pci_controller *hose, *tmp; |
1252 | struct pci_bus *bus; | 1211 | struct pci_bus *bus; |
1253 | int next_busno; | 1212 | int next_busno = 0; |
1254 | 1213 | ||
1255 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 1214 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
1256 | 1215 | ||
1257 | /* Scan all of the recorded PCI controllers. */ | 1216 | /* Scan all of the recorded PCI controllers. */ |
1258 | for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { | 1217 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1259 | if (pci_assign_all_buses) | 1218 | if (pci_assign_all_buses) |
1260 | hose->first_busno = next_busno; | 1219 | hose->first_busno = next_busno; |
1261 | hose->last_busno = 0xff; | 1220 | hose->last_busno = 0xff; |
@@ -1410,9 +1369,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1410 | static struct pci_controller* | 1369 | static struct pci_controller* |
1411 | pci_bus_to_hose(int bus) | 1370 | pci_bus_to_hose(int bus) |
1412 | { | 1371 | { |
1413 | struct pci_controller* hose = hose_head; | 1372 | struct pci_controller *hose, *tmp; |
1414 | 1373 | ||
1415 | for (; hose; hose = hose->next) | 1374 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) |
1416 | if (bus >= hose->first_busno && bus <= hose->last_busno) | 1375 | if (bus >= hose->first_busno && bus <= hose->last_busno) |
1417 | return hose; | 1376 | return hose; |
1418 | return NULL; | 1377 | return NULL; |
@@ -1462,9 +1421,9 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1462 | 1421 | ||
1463 | unsigned long pci_address_to_pio(phys_addr_t address) | 1422 | unsigned long pci_address_to_pio(phys_addr_t address) |
1464 | { | 1423 | { |
1465 | struct pci_controller* hose = hose_head; | 1424 | struct pci_controller *hose, *tmp; |
1466 | 1425 | ||
1467 | for (; hose; hose = hose->next) { | 1426 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1468 | unsigned int size = hose->io_resource.end - | 1427 | unsigned int size = hose->io_resource.end - |
1469 | hose->io_resource.start + 1; | 1428 | hose->io_resource.start + 1; |
1470 | if (address >= hose->io_base_phys && | 1429 | if (address >= hose->io_base_phys && |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 384d2752fe60..3b0f49ea4756 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -59,9 +59,6 @@ LIST_HEAD(hose_list); | |||
59 | 59 | ||
60 | static struct dma_mapping_ops *pci_dma_ops; | 60 | static struct dma_mapping_ops *pci_dma_ops; |
61 | 61 | ||
62 | /* XXX kill that some day ... */ | ||
63 | int global_phb_number; /* Global phb counter */ | ||
64 | |||
65 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) | 62 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) |
66 | { | 63 | { |
67 | pci_dma_ops = dma_ops; | 64 | pci_dma_ops = dma_ops; |
@@ -172,55 +169,6 @@ void pcibios_align_resource(void *data, struct resource *res, | |||
172 | res->start = start; | 169 | res->start = start; |
173 | } | 170 | } |
174 | 171 | ||
175 | static DEFINE_SPINLOCK(hose_spinlock); | ||
176 | |||
177 | /* | ||
178 | * pci_controller(phb) initialized common variables. | ||
179 | */ | ||
180 | static void __devinit pci_setup_pci_controller(struct pci_controller *hose) | ||
181 | { | ||
182 | memset(hose, 0, sizeof(struct pci_controller)); | ||
183 | |||
184 | spin_lock(&hose_spinlock); | ||
185 | hose->global_number = global_phb_number++; | ||
186 | list_add_tail(&hose->list_node, &hose_list); | ||
187 | spin_unlock(&hose_spinlock); | ||
188 | } | ||
189 | |||
190 | struct pci_controller * pcibios_alloc_controller(struct device_node *dev) | ||
191 | { | ||
192 | struct pci_controller *phb; | ||
193 | |||
194 | if (mem_init_done) | ||
195 | phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL); | ||
196 | else | ||
197 | phb = alloc_bootmem(sizeof (struct pci_controller)); | ||
198 | if (phb == NULL) | ||
199 | return NULL; | ||
200 | pci_setup_pci_controller(phb); | ||
201 | phb->arch_data = dev; | ||
202 | phb->is_dynamic = mem_init_done; | ||
203 | if (dev) { | ||
204 | int nid = of_node_to_nid(dev); | ||
205 | |||
206 | if (nid < 0 || !node_online(nid)) | ||
207 | nid = -1; | ||
208 | |||
209 | PHB_SET_NODE(phb, nid); | ||
210 | } | ||
211 | return phb; | ||
212 | } | ||
213 | |||
214 | void pcibios_free_controller(struct pci_controller *phb) | ||
215 | { | ||
216 | spin_lock(&hose_spinlock); | ||
217 | list_del(&phb->list_node); | ||
218 | spin_unlock(&hose_spinlock); | ||
219 | |||
220 | if (phb->is_dynamic) | ||
221 | kfree(phb); | ||
222 | } | ||
223 | |||
224 | void __devinit pcibios_claim_one_bus(struct pci_bus *b) | 172 | void __devinit pcibios_claim_one_bus(struct pci_bus *b) |
225 | { | 173 | { |
226 | struct pci_dev *dev; | 174 | struct pci_dev *dev; |
@@ -957,20 +905,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) | |||
957 | } | 905 | } |
958 | EXPORT_SYMBOL(pcibios_fixup_bus); | 906 | EXPORT_SYMBOL(pcibios_fixup_bus); |
959 | 907 | ||
960 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | ||
961 | { | ||
962 | if (!have_of) | ||
963 | return NULL; | ||
964 | while(node) { | ||
965 | struct pci_controller *hose, *tmp; | ||
966 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | ||
967 | if (hose->arch_data == node) | ||
968 | return hose; | ||
969 | node = node->parent; | ||
970 | } | ||
971 | return NULL; | ||
972 | } | ||
973 | |||
974 | unsigned long pci_address_to_pio(phys_addr_t address) | 908 | unsigned long pci_address_to_pio(phys_addr_t address) |
975 | { | 909 | { |
976 | struct pci_controller *hose, *tmp; | 910 | struct pci_controller *hose, *tmp; |
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h index 69ea865c01a4..e72c2a60853c 100644 --- a/include/asm-powerpc/pci-bridge.h +++ b/include/asm-powerpc/pci-bridge.h | |||
@@ -2,9 +2,11 @@ | |||
2 | #define _ASM_POWERPC_PCI_BRIDGE_H | 2 | #define _ASM_POWERPC_PCI_BRIDGE_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #ifndef CONFIG_PPC64 | ||
6 | #include <linux/ioport.h> | ||
7 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | #include <linux/list.h> | ||
7 | #include <linux/ioport.h> | ||
8 | |||
9 | #ifndef CONFIG_PPC64 | ||
8 | 10 | ||
9 | struct device_node; | 11 | struct device_node; |
10 | struct pci_controller; | 12 | struct pci_controller; |
@@ -14,8 +16,9 @@ struct pci_controller; | |||
14 | */ | 16 | */ |
15 | struct pci_controller { | 17 | struct pci_controller { |
16 | struct pci_bus *bus; | 18 | struct pci_bus *bus; |
19 | char is_dynamic; | ||
17 | void *arch_data; | 20 | void *arch_data; |
18 | struct pci_controller *next; | 21 | struct list_head list_node; |
19 | struct device *parent; | 22 | struct device *parent; |
20 | 23 | ||
21 | int first_busno; | 24 | int first_busno; |
@@ -84,8 +87,6 @@ extern void setup_grackle(struct pci_controller *hose); | |||
84 | 87 | ||
85 | #else | 88 | #else |
86 | 89 | ||
87 | #include <linux/pci.h> | ||
88 | #include <linux/list.h> | ||
89 | 90 | ||
90 | /* | 91 | /* |
91 | * This program is free software; you can redistribute it and/or | 92 | * This program is free software; you can redistribute it and/or |