aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/pci.c119
-rw-r--r--arch/sparc64/kernel/pci_impl.h9
-rw-r--r--arch/sparc64/kernel/pci_psycho.c7
-rw-r--r--arch/sparc64/kernel/pci_sabre.c12
-rw-r--r--arch/sparc64/kernel/pci_schizo.c6
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c6
6 files changed, 129 insertions, 30 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 914a216da339..ec5f85b030ef 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -368,7 +368,8 @@ static void pci_parse_of_addrs(struct of_device *op,
368 368
369struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, 369struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
370 struct device_node *node, 370 struct device_node *node,
371 struct pci_bus *bus, int devfn) 371 struct pci_bus *bus, int devfn,
372 int host_controller)
372{ 373{
373 struct dev_archdata *sd; 374 struct dev_archdata *sd;
374 struct pci_dev *dev; 375 struct pci_dev *dev;
@@ -400,47 +401,62 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
400 dev->devfn = devfn; 401 dev->devfn = devfn;
401 dev->multifunction = 0; /* maybe a lie? */ 402 dev->multifunction = 0; /* maybe a lie? */
402 403
403 dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); 404 if (host_controller) {
404 dev->device = of_getintprop_default(node, "device-id", 0xffff); 405 dev->vendor = 0x108e;
405 dev->subsystem_vendor = 406 dev->device = 0x8000;
406 of_getintprop_default(node, "subsystem-vendor-id", 0); 407 dev->subsystem_vendor = 0x0000;
407 dev->subsystem_device = 408 dev->subsystem_device = 0x0000;
408 of_getintprop_default(node, "subsystem-id", 0); 409 dev->cfg_size = 256;
409 410 } else {
410 dev->cfg_size = pci_cfg_space_size(dev); 411 dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
411 412 dev->device = of_getintprop_default(node, "device-id", 0xffff);
413 dev->subsystem_vendor =
414 of_getintprop_default(node, "subsystem-vendor-id", 0);
415 dev->subsystem_device =
416 of_getintprop_default(node, "subsystem-id", 0);
417
418 dev->cfg_size = pci_cfg_space_size(dev);
419 }
412 sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), 420 sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
413 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 421 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
414 422
415 /* dev->class = of_getintprop_default(node, "class-code", 0); */ 423 if (host_controller) {
416 /* We can't actually use the firmware value, we have to read what 424 dev->class = PCI_CLASS_BRIDGE_HOST << 8;
417 * is in the register right now. One reason is that in the case 425 } else {
418 * of IDE interfaces the firmware can sample the value before the 426 /* We can't actually use the firmware value, we have
419 * the IDE interface is programmed into native mode. 427 * to read what is in the register right now. One
420 */ 428 * reason is that in the case of IDE interfaces the
421 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); 429 * firmware can sample the value before the the IDE
422 dev->class = class >> 8; 430 * interface is programmed into native mode.
423 431 */
432 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
433 dev->class = class >> 8;
434 }
424 printk(" class: 0x%x\n", dev->class); 435 printk(" class: 0x%x\n", dev->class);
425 436
426 dev->current_state = 4; /* unknown power state */ 437 dev->current_state = 4; /* unknown power state */
427 dev->error_state = pci_channel_io_normal; 438 dev->error_state = pci_channel_io_normal;
428 439
429 if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { 440 if (host_controller) {
430 /* a PCI-PCI bridge */
431 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; 441 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
432 dev->rom_base_reg = PCI_ROM_ADDRESS1; 442 dev->rom_base_reg = PCI_ROM_ADDRESS1;
433 } else if (!strcmp(type, "cardbus")) { 443 dev->irq = PCI_IRQ_NONE;
434 dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
435 } else { 444 } else {
436 dev->hdr_type = PCI_HEADER_TYPE_NORMAL; 445 if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
437 dev->rom_base_reg = PCI_ROM_ADDRESS; 446 /* a PCI-PCI bridge */
447 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
448 dev->rom_base_reg = PCI_ROM_ADDRESS1;
449 } else if (!strcmp(type, "cardbus")) {
450 dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
451 } else {
452 dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
453 dev->rom_base_reg = PCI_ROM_ADDRESS;
438 454
439 dev->irq = sd->op->irqs[0]; 455 dev->irq = sd->op->irqs[0];
440 if (dev->irq == 0xffffffff) 456 if (dev->irq == 0xffffffff)
441 dev->irq = PCI_IRQ_NONE; 457 dev->irq = PCI_IRQ_NONE;
458 }
442 } 459 }
443
444 pci_parse_of_addrs(sd->op, node, dev); 460 pci_parse_of_addrs(sd->op, node, dev);
445 461
446 printk(" adding to system ...\n"); 462 printk(" adding to system ...\n");
@@ -632,7 +648,7 @@ static void __init pci_of_scan_bus(struct pci_pbm_info *pbm,
632 devfn = (reg[0] >> 8) & 0xff; 648 devfn = (reg[0] >> 8) & 0xff;
633 649
634 /* create a new pci_dev for this device */ 650 /* create a new pci_dev for this device */
635 dev = of_create_pci_dev(pbm, child, bus, devfn); 651 dev = of_create_pci_dev(pbm, child, bus, devfn, 0);
636 if (!dev) 652 if (!dev)
637 continue; 653 continue;
638 printk("PCI: dev header type: %x\n", dev->hdr_type); 654 printk("PCI: dev header type: %x\n", dev->hdr_type);
@@ -677,10 +693,49 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus)
677 pci_bus_register_of_sysfs(child_bus); 693 pci_bus_register_of_sysfs(child_bus);
678} 694}
679 695
696int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
697 unsigned int devfn,
698 int where, int size,
699 u32 *value)
700{
701 static u8 fake_pci_config[] = {
702 0x8e, 0x10, /* Vendor: 0x108e (Sun) */
703 0x00, 0x80, /* Device: 0x8000 (PBM) */
704 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */
705 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */
706 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */
707 0x00, /* Cacheline: 0x00 */
708 0x40, /* Latency: 0x40 */
709 0x00, /* Header-Type: 0x00 normal */
710 };
711
712 *value = 0;
713 if (where >= 0 && where < sizeof(fake_pci_config) &&
714 (where + size) >= 0 &&
715 (where + size) < sizeof(fake_pci_config) &&
716 size <= sizeof(u32)) {
717 while (size--) {
718 *value <<= 8;
719 *value |= fake_pci_config[where + size];
720 }
721 }
722
723 return PCIBIOS_SUCCESSFUL;
724}
725
726int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
727 unsigned int devfn,
728 int where, int size,
729 u32 value)
730{
731 return PCIBIOS_SUCCESSFUL;
732}
733
680struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) 734struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm)
681{ 735{
682 struct pci_controller_info *p = pbm->parent; 736 struct pci_controller_info *p = pbm->parent;
683 struct device_node *node = pbm->prom_node; 737 struct device_node *node = pbm->prom_node;
738 struct pci_dev *host_pdev;
684 struct pci_bus *bus; 739 struct pci_bus *bus;
685 740
686 printk("PCI: Scanning PBM %s\n", node->full_name); 741 printk("PCI: Scanning PBM %s\n", node->full_name);
@@ -698,6 +753,10 @@ struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm)
698 bus->resource[0] = &pbm->io_space; 753 bus->resource[0] = &pbm->io_space;
699 bus->resource[1] = &pbm->mem_space; 754 bus->resource[1] = &pbm->mem_space;
700 755
756 /* Create the dummy host bridge and link it in. */
757 host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1);
758 bus->self = host_pdev;
759
701 pci_of_scan_bus(pbm, node, bus); 760 pci_of_scan_bus(pbm, node, bus);
702 pci_bus_add_devices(bus); 761 pci_bus_add_devices(bus);
703 pci_bus_register_of_sysfs(bus); 762 pci_bus_register_of_sysfs(bus);
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h
index c6714548d823..1208583fcb83 100644
--- a/arch/sparc64/kernel/pci_impl.h
+++ b/arch/sparc64/kernel/pci_impl.h
@@ -20,6 +20,15 @@ extern int pci_num_controllers;
20extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); 20extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
21extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); 21extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
22 22
23extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
24 unsigned int devfn,
25 int where, int size,
26 u32 *value);
27extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
28 unsigned int devfn,
29 int where, int size,
30 u32 value);
31
23/* Error reporting support. */ 32/* Error reporting support. */
24extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); 33extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
25extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); 34extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 2e5d40a26dbd..154c03290d5d 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -118,6 +118,10 @@ static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
118 u16 tmp16; 118 u16 tmp16;
119 u8 tmp8; 119 u8 tmp8;
120 120
121 if (bus_dev == pbm->pci_bus && devfn == 0x00)
122 return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
123 size, value);
124
121 switch (size) { 125 switch (size) {
122 case 1: 126 case 1:
123 *value = 0xff; 127 *value = 0xff;
@@ -171,6 +175,9 @@ static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
171 unsigned char bus = bus_dev->number; 175 unsigned char bus = bus_dev->number;
172 u32 *addr; 176 u32 *addr;
173 177
178 if (bus_dev == pbm->pci_bus && devfn == 0x00)
179 return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
180 size, value);
174 addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); 181 addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
175 if (!addr) 182 if (!addr)
176 return PCIBIOS_SUCCESSFUL; 183 return PCIBIOS_SUCCESSFUL;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 1bd7fc7c05e6..a2f129d29c20 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -319,6 +319,12 @@ static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
319static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, 319static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn,
320 int where, int size, u32 *value) 320 int where, int size, u32 *value)
321{ 321{
322 struct pci_pbm_info *pbm = bus->sysdata;
323
324 if (bus == pbm->pci_bus && devfn == 0x00)
325 return pci_host_bridge_read_pci_cfg(bus, devfn, where,
326 size, value);
327
322 if (!bus->number && sabre_out_of_range(devfn)) { 328 if (!bus->number && sabre_out_of_range(devfn)) {
323 switch (size) { 329 switch (size) {
324 case 1: 330 case 1:
@@ -435,6 +441,12 @@ static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
435static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, 441static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn,
436 int where, int size, u32 value) 442 int where, int size, u32 value)
437{ 443{
444 struct pci_pbm_info *pbm = bus->sysdata;
445
446 if (bus == pbm->pci_bus && devfn == 0x00)
447 return pci_host_bridge_write_pci_cfg(bus, devfn, where,
448 size, value);
449
438 if (bus->number) 450 if (bus->number)
439 return __sabre_write_pci_cfg(bus, devfn, where, size, value); 451 return __sabre_write_pci_cfg(bus, devfn, where, size, value);
440 452
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index f1f105af8d3c..322cdbf50eff 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -125,6 +125,9 @@ static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
125 u16 tmp16; 125 u16 tmp16;
126 u8 tmp8; 126 u8 tmp8;
127 127
128 if (bus_dev == pbm->pci_bus && devfn == 0x00)
129 return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
130 size, value);
128 switch (size) { 131 switch (size) {
129 case 1: 132 case 1:
130 *value = 0xff; 133 *value = 0xff;
@@ -178,6 +181,9 @@ static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
178 unsigned char bus = bus_dev->number; 181 unsigned char bus = bus_dev->number;
179 u32 *addr; 182 u32 *addr;
180 183
184 if (bus_dev == pbm->pci_bus && devfn == 0x00)
185 return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
186 size, value);
181 addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); 187 addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
182 if (!addr) 188 if (!addr)
183 return PCIBIOS_SUCCESSFUL; 189 return PCIBIOS_SUCCESSFUL;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index a8c12c1e8039..52bd4563492d 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -612,6 +612,9 @@ static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
612 unsigned int func = PCI_FUNC(devfn); 612 unsigned int func = PCI_FUNC(devfn);
613 unsigned long ret; 613 unsigned long ret;
614 614
615 if (bus_dev == pbm->pci_bus && devfn == 0x00)
616 return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
617 size, value);
615 if (pci_sun4v_out_of_range(pbm, bus, device, func)) { 618 if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
616 ret = ~0UL; 619 ret = ~0UL;
617 } else { 620 } else {
@@ -650,6 +653,9 @@ static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
650 unsigned int func = PCI_FUNC(devfn); 653 unsigned int func = PCI_FUNC(devfn);
651 unsigned long ret; 654 unsigned long ret;
652 655
656 if (bus_dev == pbm->pci_bus && devfn == 0x00)
657 return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
658 size, value);
653 if (pci_sun4v_out_of_range(pbm, bus, device, func)) { 659 if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
654 /* Do nothing. */ 660 /* Do nothing. */
655 } else { 661 } else {