diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 130 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_common.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_impl.h | 9 |
3 files changed, 33 insertions, 112 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index dbf2fc2f4d87..112b09f16f36 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -350,8 +350,7 @@ static void pci_parse_of_addrs(struct of_device *op, | |||
350 | 350 | ||
351 | struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | 351 | struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, |
352 | struct device_node *node, | 352 | struct device_node *node, |
353 | struct pci_bus *bus, int devfn, | 353 | struct pci_bus *bus, int devfn) |
354 | int host_controller) | ||
355 | { | 354 | { |
356 | struct dev_archdata *sd; | 355 | struct dev_archdata *sd; |
357 | struct pci_dev *dev; | 356 | struct pci_dev *dev; |
@@ -390,43 +389,28 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
390 | dev->devfn = devfn; | 389 | dev->devfn = devfn; |
391 | dev->multifunction = 0; /* maybe a lie? */ | 390 | dev->multifunction = 0; /* maybe a lie? */ |
392 | 391 | ||
393 | if (host_controller) { | 392 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); |
394 | if (tlb_type != hypervisor) { | 393 | dev->device = of_getintprop_default(node, "device-id", 0xffff); |
395 | pci_read_config_word(dev, PCI_VENDOR_ID, | 394 | dev->subsystem_vendor = |
396 | &dev->vendor); | 395 | of_getintprop_default(node, "subsystem-vendor-id", 0); |
397 | pci_read_config_word(dev, PCI_DEVICE_ID, | 396 | dev->subsystem_device = |
398 | &dev->device); | 397 | of_getintprop_default(node, "subsystem-id", 0); |
399 | } else { | 398 | |
400 | dev->vendor = PCI_VENDOR_ID_SUN; | 399 | dev->cfg_size = pci_cfg_space_size(dev); |
401 | dev->device = 0x80f0; | 400 | |
402 | } | 401 | /* We can't actually use the firmware value, we have |
403 | dev->cfg_size = 256; | 402 | * to read what is in the register right now. One |
404 | dev->class = PCI_CLASS_BRIDGE_HOST << 8; | 403 | * reason is that in the case of IDE interfaces the |
405 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | 404 | * firmware can sample the value before the the IDE |
406 | 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); | 405 | * interface is programmed into native mode. |
407 | } else { | 406 | */ |
408 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); | 407 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); |
409 | dev->device = of_getintprop_default(node, "device-id", 0xffff); | 408 | dev->class = class >> 8; |
410 | dev->subsystem_vendor = | 409 | dev->revision = class & 0xff; |
411 | of_getintprop_default(node, "subsystem-vendor-id", 0); | 410 | |
412 | dev->subsystem_device = | 411 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), |
413 | of_getintprop_default(node, "subsystem-id", 0); | 412 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); |
414 | |||
415 | dev->cfg_size = pci_cfg_space_size(dev); | ||
416 | |||
417 | /* We can't actually use the firmware value, we have | ||
418 | * to read what is in the register right now. One | ||
419 | * reason is that in the case of IDE interfaces the | ||
420 | * firmware can sample the value before the the IDE | ||
421 | * interface is programmed into native mode. | ||
422 | */ | ||
423 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); | ||
424 | dev->class = class >> 8; | ||
425 | dev->revision = class & 0xff; | ||
426 | 413 | ||
427 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | ||
428 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
429 | } | ||
430 | if (ofpci_verbose) | 414 | if (ofpci_verbose) |
431 | printk(" class: 0x%x device name: %s\n", | 415 | printk(" class: 0x%x device name: %s\n", |
432 | dev->class, pci_name(dev)); | 416 | dev->class, pci_name(dev)); |
@@ -441,26 +425,21 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
441 | dev->current_state = 4; /* unknown power state */ | 425 | dev->current_state = 4; /* unknown power state */ |
442 | dev->error_state = pci_channel_io_normal; | 426 | dev->error_state = pci_channel_io_normal; |
443 | 427 | ||
444 | if (host_controller) { | 428 | if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { |
429 | /* a PCI-PCI bridge */ | ||
445 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; | 430 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; |
446 | dev->rom_base_reg = PCI_ROM_ADDRESS1; | 431 | dev->rom_base_reg = PCI_ROM_ADDRESS1; |
447 | dev->irq = PCI_IRQ_NONE; | 432 | } else if (!strcmp(type, "cardbus")) { |
433 | dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; | ||
448 | } else { | 434 | } else { |
449 | if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { | 435 | dev->hdr_type = PCI_HEADER_TYPE_NORMAL; |
450 | /* a PCI-PCI bridge */ | 436 | dev->rom_base_reg = PCI_ROM_ADDRESS; |
451 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; | ||
452 | dev->rom_base_reg = PCI_ROM_ADDRESS1; | ||
453 | } else if (!strcmp(type, "cardbus")) { | ||
454 | dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; | ||
455 | } else { | ||
456 | dev->hdr_type = PCI_HEADER_TYPE_NORMAL; | ||
457 | dev->rom_base_reg = PCI_ROM_ADDRESS; | ||
458 | 437 | ||
459 | dev->irq = sd->op->irqs[0]; | 438 | dev->irq = sd->op->irqs[0]; |
460 | if (dev->irq == 0xffffffff) | 439 | if (dev->irq == 0xffffffff) |
461 | dev->irq = PCI_IRQ_NONE; | 440 | dev->irq = PCI_IRQ_NONE; |
462 | } | ||
463 | } | 441 | } |
442 | |||
464 | pci_parse_of_addrs(sd->op, node, dev); | 443 | pci_parse_of_addrs(sd->op, node, dev); |
465 | 444 | ||
466 | if (ofpci_verbose) | 445 | if (ofpci_verbose) |
@@ -749,7 +728,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | |||
749 | prev_devfn = devfn; | 728 | prev_devfn = devfn; |
750 | 729 | ||
751 | /* create a new pci_dev for this device */ | 730 | /* create a new pci_dev for this device */ |
752 | dev = of_create_pci_dev(pbm, child, bus, devfn, 0); | 731 | dev = of_create_pci_dev(pbm, child, bus, devfn); |
753 | if (!dev) | 732 | if (!dev) |
754 | continue; | 733 | continue; |
755 | if (ofpci_verbose) | 734 | if (ofpci_verbose) |
@@ -796,48 +775,9 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) | |||
796 | pci_bus_register_of_sysfs(child_bus); | 775 | pci_bus_register_of_sysfs(child_bus); |
797 | } | 776 | } |
798 | 777 | ||
799 | int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, | ||
800 | unsigned int devfn, | ||
801 | int where, int size, | ||
802 | u32 *value) | ||
803 | { | ||
804 | static u8 fake_pci_config[] = { | ||
805 | 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ | ||
806 | 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ | ||
807 | 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ | ||
808 | 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ | ||
809 | 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ | ||
810 | 0x00, /* Cacheline: 0x00 */ | ||
811 | 0x40, /* Latency: 0x40 */ | ||
812 | 0x00, /* Header-Type: 0x00 normal */ | ||
813 | }; | ||
814 | |||
815 | *value = 0; | ||
816 | if (where >= 0 && where < sizeof(fake_pci_config) && | ||
817 | (where + size) >= 0 && | ||
818 | (where + size) < sizeof(fake_pci_config) && | ||
819 | size <= sizeof(u32)) { | ||
820 | while (size--) { | ||
821 | *value <<= 8; | ||
822 | *value |= fake_pci_config[where + size]; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | return PCIBIOS_SUCCESSFUL; | ||
827 | } | ||
828 | |||
829 | int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, | ||
830 | unsigned int devfn, | ||
831 | int where, int size, | ||
832 | u32 value) | ||
833 | { | ||
834 | return PCIBIOS_SUCCESSFUL; | ||
835 | } | ||
836 | |||
837 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | 778 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) |
838 | { | 779 | { |
839 | struct device_node *node = pbm->prom_node; | 780 | struct device_node *node = pbm->prom_node; |
840 | struct pci_dev *host_pdev; | ||
841 | struct pci_bus *bus; | 781 | struct pci_bus *bus; |
842 | 782 | ||
843 | printk("PCI: Scanning PBM %s\n", node->full_name); | 783 | printk("PCI: Scanning PBM %s\n", node->full_name); |
@@ -855,10 +795,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | |||
855 | bus->resource[0] = &pbm->io_space; | 795 | bus->resource[0] = &pbm->io_space; |
856 | bus->resource[1] = &pbm->mem_space; | 796 | bus->resource[1] = &pbm->mem_space; |
857 | 797 | ||
858 | /* Create the dummy host bridge and link it in. */ | ||
859 | host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); | ||
860 | bus->self = host_pdev; | ||
861 | |||
862 | pci_of_scan_bus(pbm, node, bus); | 798 | pci_of_scan_bus(pbm, node, bus); |
863 | pci_bus_add_devices(bus); | 799 | pci_bus_add_devices(bus); |
864 | pci_bus_register_of_sysfs(bus); | 800 | pci_bus_register_of_sysfs(bus); |
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 923e0bcc3bfd..19fa621d6a60 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | |||
264 | unsigned int func = PCI_FUNC(devfn); | 264 | unsigned int func = PCI_FUNC(devfn); |
265 | unsigned long ret; | 265 | unsigned long ret; |
266 | 266 | ||
267 | if (!bus && devfn == 0x00) | ||
268 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
269 | size, value); | ||
270 | if (config_out_of_range(pbm, bus, devfn, where)) { | 267 | if (config_out_of_range(pbm, bus, devfn, where)) { |
271 | ret = ~0UL; | 268 | ret = ~0UL; |
272 | } else { | 269 | } else { |
@@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | |||
300 | unsigned int func = PCI_FUNC(devfn); | 297 | unsigned int func = PCI_FUNC(devfn); |
301 | unsigned long ret; | 298 | unsigned long ret; |
302 | 299 | ||
303 | if (!bus && devfn == 0x00) | ||
304 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
305 | size, value); | ||
306 | if (config_out_of_range(pbm, bus, devfn, where)) { | 300 | if (config_out_of_range(pbm, bus, devfn, where)) { |
307 | /* Do nothing. */ | 301 | /* Do nothing. */ |
308 | } else { | 302 | } else { |
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 218bac4ff79b..c385d126be11 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm); | |||
167 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); | 167 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); |
168 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); | 168 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); |
169 | 169 | ||
170 | extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, | ||
171 | unsigned int devfn, | ||
172 | int where, int size, | ||
173 | u32 *value); | ||
174 | extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, | ||
175 | unsigned int devfn, | ||
176 | int where, int size, | ||
177 | u32 value); | ||
178 | |||
179 | /* Error reporting support. */ | 170 | /* Error reporting support. */ |
180 | extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); | 171 | extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); |
181 | extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); | 172 | extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); |