diff options
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 174 |
1 files changed, 21 insertions, 153 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 55096195458f..242ac1ccae7d 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -18,32 +18,17 @@ | |||
18 | #include <linux/msi.h> | 18 | #include <linux/msi.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
21 | 23 | ||
22 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
23 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
24 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
25 | #include <asm/ebus.h> | ||
26 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
27 | #include <asm/apb.h> | 28 | #include <asm/apb.h> |
28 | 29 | ||
29 | #include "pci_impl.h" | 30 | #include "pci_impl.h" |
30 | 31 | ||
31 | #ifndef CONFIG_PCI | ||
32 | /* A "nop" PCI implementation. */ | ||
33 | asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, | ||
34 | unsigned long off, unsigned long len, | ||
35 | unsigned char *buf) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, | ||
40 | unsigned long off, unsigned long len, | ||
41 | unsigned char *buf) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | #else | ||
46 | |||
47 | /* List of all PCI controllers found in the system. */ | 32 | /* List of all PCI controllers found in the system. */ |
48 | struct pci_pbm_info *pci_pbm_root = NULL; | 33 | struct pci_pbm_info *pci_pbm_root = NULL; |
49 | 34 | ||
@@ -179,97 +164,6 @@ void pci_config_write32(u32 *addr, u32 val) | |||
179 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 164 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
180 | } | 165 | } |
181 | 166 | ||
182 | /* Probe for all PCI controllers in the system. */ | ||
183 | extern void sabre_init(struct device_node *, const char *); | ||
184 | extern void psycho_init(struct device_node *, const char *); | ||
185 | extern void schizo_init(struct device_node *, const char *); | ||
186 | extern void schizo_plus_init(struct device_node *, const char *); | ||
187 | extern void tomatillo_init(struct device_node *, const char *); | ||
188 | extern void sun4v_pci_init(struct device_node *, const char *); | ||
189 | extern void fire_pci_init(struct device_node *, const char *); | ||
190 | |||
191 | static struct { | ||
192 | char *model_name; | ||
193 | void (*init)(struct device_node *, const char *); | ||
194 | } pci_controller_table[] __initdata = { | ||
195 | { "SUNW,sabre", sabre_init }, | ||
196 | { "pci108e,a000", sabre_init }, | ||
197 | { "pci108e,a001", sabre_init }, | ||
198 | { "SUNW,psycho", psycho_init }, | ||
199 | { "pci108e,8000", psycho_init }, | ||
200 | { "SUNW,schizo", schizo_init }, | ||
201 | { "pci108e,8001", schizo_init }, | ||
202 | { "SUNW,schizo+", schizo_plus_init }, | ||
203 | { "pci108e,8002", schizo_plus_init }, | ||
204 | { "SUNW,tomatillo", tomatillo_init }, | ||
205 | { "pci108e,a801", tomatillo_init }, | ||
206 | { "SUNW,sun4v-pci", sun4v_pci_init }, | ||
207 | { "pciex108e,80f0", fire_pci_init }, | ||
208 | }; | ||
209 | #define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table) | ||
210 | |||
211 | static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) | ||
212 | { | ||
213 | int i; | ||
214 | |||
215 | for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { | ||
216 | if (!strncmp(model_name, | ||
217 | pci_controller_table[i].model_name, | ||
218 | namelen)) { | ||
219 | pci_controller_table[i].init(dp, model_name); | ||
220 | return 1; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) | ||
228 | { | ||
229 | struct device_node *dp; | ||
230 | int count = 0; | ||
231 | |||
232 | for_each_node_by_name(dp, "pci") { | ||
233 | struct property *prop; | ||
234 | int len; | ||
235 | |||
236 | prop = of_find_property(dp, "model", &len); | ||
237 | if (!prop) | ||
238 | prop = of_find_property(dp, "compatible", &len); | ||
239 | |||
240 | if (prop) { | ||
241 | const char *model = prop->value; | ||
242 | int item_len = 0; | ||
243 | |||
244 | /* Our value may be a multi-valued string in the | ||
245 | * case of some compatible properties. For sanity, | ||
246 | * only try the first one. | ||
247 | */ | ||
248 | while (model[item_len] && len) { | ||
249 | len--; | ||
250 | item_len++; | ||
251 | } | ||
252 | |||
253 | if (handler(model, item_len, dp)) | ||
254 | count++; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | return count; | ||
259 | } | ||
260 | |||
261 | /* Find each controller in the system, attach and initialize | ||
262 | * software state structure for each and link into the | ||
263 | * pci_pbm_root. Setup the controller enough such | ||
264 | * that bus scanning can be done. | ||
265 | */ | ||
266 | static void __init pci_controller_probe(void) | ||
267 | { | ||
268 | printk("PCI: Probing for controllers.\n"); | ||
269 | |||
270 | pci_controller_scan(pci_controller_init); | ||
271 | } | ||
272 | |||
273 | static int ofpci_verbose; | 167 | static int ofpci_verbose; |
274 | 168 | ||
275 | static int __init ofpci_debug(char *str) | 169 | static int __init ofpci_debug(char *str) |
@@ -348,11 +242,12 @@ static void pci_parse_of_addrs(struct of_device *op, | |||
348 | } | 242 | } |
349 | } | 243 | } |
350 | 244 | ||
351 | struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | 245 | static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, |
352 | struct device_node *node, | 246 | struct device_node *node, |
353 | struct pci_bus *bus, int devfn) | 247 | struct pci_bus *bus, int devfn) |
354 | { | 248 | { |
355 | struct dev_archdata *sd; | 249 | struct dev_archdata *sd; |
250 | struct of_device *op; | ||
356 | struct pci_dev *dev; | 251 | struct pci_dev *dev; |
357 | const char *type; | 252 | const char *type; |
358 | u32 class; | 253 | u32 class; |
@@ -366,14 +261,17 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
366 | sd->stc = &pbm->stc; | 261 | sd->stc = &pbm->stc; |
367 | sd->host_controller = pbm; | 262 | sd->host_controller = pbm; |
368 | sd->prom_node = node; | 263 | sd->prom_node = node; |
369 | sd->op = of_find_device_by_node(node); | 264 | sd->op = op = of_find_device_by_node(node); |
370 | sd->numa_node = pbm->numa_node; | 265 | sd->numa_node = pbm->numa_node; |
371 | 266 | ||
372 | sd = &sd->op->dev.archdata; | 267 | sd = &op->dev.archdata; |
373 | sd->iommu = pbm->iommu; | 268 | sd->iommu = pbm->iommu; |
374 | sd->stc = &pbm->stc; | 269 | sd->stc = &pbm->stc; |
375 | sd->numa_node = pbm->numa_node; | 270 | sd->numa_node = pbm->numa_node; |
376 | 271 | ||
272 | if (!strcmp(node->name, "ebus")) | ||
273 | of_propagate_archdata(op); | ||
274 | |||
377 | type = of_get_property(node, "device_type", NULL); | 275 | type = of_get_property(node, "device_type", NULL); |
378 | if (type == NULL) | 276 | if (type == NULL) |
379 | type = ""; | 277 | type = ""; |
@@ -425,7 +323,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
425 | dev->current_state = 4; /* unknown power state */ | 323 | dev->current_state = 4; /* unknown power state */ |
426 | dev->error_state = pci_channel_io_normal; | 324 | dev->error_state = pci_channel_io_normal; |
427 | 325 | ||
428 | if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { | 326 | if (!strcmp(node->name, "pci")) { |
429 | /* a PCI-PCI bridge */ | 327 | /* a PCI-PCI bridge */ |
430 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; | 328 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; |
431 | dev->rom_base_reg = PCI_ROM_ADDRESS1; | 329 | dev->rom_base_reg = PCI_ROM_ADDRESS1; |
@@ -775,15 +673,15 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) | |||
775 | pci_bus_register_of_sysfs(child_bus); | 673 | pci_bus_register_of_sysfs(child_bus); |
776 | } | 674 | } |
777 | 675 | ||
778 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | 676 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, |
677 | struct device *parent) | ||
779 | { | 678 | { |
780 | struct device_node *node = pbm->prom_node; | 679 | struct device_node *node = pbm->op->node; |
781 | struct pci_bus *bus; | 680 | struct pci_bus *bus; |
782 | 681 | ||
783 | printk("PCI: Scanning PBM %s\n", node->full_name); | 682 | printk("PCI: Scanning PBM %s\n", node->full_name); |
784 | 683 | ||
785 | /* XXX parent device? XXX */ | 684 | bus = pci_create_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm); |
786 | bus = pci_create_bus(NULL, pbm->pci_first_busno, pbm->pci_ops, pbm); | ||
787 | if (!bus) { | 685 | if (!bus) { |
788 | printk(KERN_ERR "Failed to create bus for %s\n", | 686 | printk(KERN_ERR "Failed to create bus for %s\n", |
789 | node->full_name); | 687 | node->full_name); |
@@ -802,32 +700,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | |||
802 | return bus; | 700 | return bus; |
803 | } | 701 | } |
804 | 702 | ||
805 | static void __init pci_scan_each_controller_bus(void) | ||
806 | { | ||
807 | struct pci_pbm_info *pbm; | ||
808 | |||
809 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) | ||
810 | pbm->scan_bus(pbm); | ||
811 | } | ||
812 | |||
813 | extern void power_init(void); | ||
814 | |||
815 | static int __init pcibios_init(void) | ||
816 | { | ||
817 | pci_controller_probe(); | ||
818 | if (pci_pbm_root == NULL) | ||
819 | return 0; | ||
820 | |||
821 | pci_scan_each_controller_bus(); | ||
822 | |||
823 | ebus_init(); | ||
824 | power_init(); | ||
825 | |||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | subsys_initcall(pcibios_init); | ||
830 | |||
831 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) | 703 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) |
832 | { | 704 | { |
833 | struct pci_pbm_info *pbm = pbus->sysdata; | 705 | struct pci_pbm_info *pbm = pbus->sysdata; |
@@ -1105,14 +977,14 @@ int pcibus_to_node(struct pci_bus *pbus) | |||
1105 | EXPORT_SYMBOL(pcibus_to_node); | 977 | EXPORT_SYMBOL(pcibus_to_node); |
1106 | #endif | 978 | #endif |
1107 | 979 | ||
1108 | /* Return the domain nuber for this pci bus */ | 980 | /* Return the domain number for this pci bus */ |
1109 | 981 | ||
1110 | int pci_domain_nr(struct pci_bus *pbus) | 982 | int pci_domain_nr(struct pci_bus *pbus) |
1111 | { | 983 | { |
1112 | struct pci_pbm_info *pbm = pbus->sysdata; | 984 | struct pci_pbm_info *pbm = pbus->sysdata; |
1113 | int ret; | 985 | int ret; |
1114 | 986 | ||
1115 | if (pbm == NULL || pbm->parent == NULL) { | 987 | if (!pbm) { |
1116 | ret = -ENXIO; | 988 | ret = -ENXIO; |
1117 | } else { | 989 | } else { |
1118 | ret = pbm->index; | 990 | ret = pbm->index; |
@@ -1126,7 +998,7 @@ EXPORT_SYMBOL(pci_domain_nr); | |||
1126 | int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) | 998 | int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) |
1127 | { | 999 | { |
1128 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 1000 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
1129 | int virt_irq; | 1001 | unsigned int virt_irq; |
1130 | 1002 | ||
1131 | if (!pbm->setup_msi_irq) | 1003 | if (!pbm->setup_msi_irq) |
1132 | return -EINVAL; | 1004 | return -EINVAL; |
@@ -1140,10 +1012,8 @@ void arch_teardown_msi_irq(unsigned int virt_irq) | |||
1140 | struct pci_dev *pdev = entry->dev; | 1012 | struct pci_dev *pdev = entry->dev; |
1141 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 1013 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
1142 | 1014 | ||
1143 | if (!pbm->teardown_msi_irq) | 1015 | if (pbm->teardown_msi_irq) |
1144 | return; | 1016 | pbm->teardown_msi_irq(virt_irq, pdev); |
1145 | |||
1146 | return pbm->teardown_msi_irq(virt_irq, pdev); | ||
1147 | } | 1017 | } |
1148 | #endif /* !(CONFIG_PCI_MSI) */ | 1018 | #endif /* !(CONFIG_PCI_MSI) */ |
1149 | 1019 | ||
@@ -1215,5 +1085,3 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
1215 | *start = rp->start - offset; | 1085 | *start = rp->start - offset; |
1216 | *end = rp->end - offset; | 1086 | *end = rp->end - offset; |
1217 | } | 1087 | } |
1218 | |||
1219 | #endif /* !(CONFIG_PCI) */ | ||