diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-09-05 11:28:08 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-09-05 11:28:08 -0400 |
commit | c346a54a6f5a68eb4d9e97b69c3905fbda34d0fc (patch) | |
tree | d7eb539cbf83a326bb07915ffc4c39033a349157 /drivers/pci/host | |
parent | 3e3e406e3807235906ee0b7c697664ea6dfd88de (diff) | |
parent | 8ddebc4103e6544bd31f0c97e55491387717a124 (diff) |
Merge branch 'pci/host-designware' into pci/host-imx6
* pci/host-designware:
PCI: designware: Remove pci_assign_unassigned_resources() from dw_pcie_host_init()
PCI: designware: Use pci_create_root_bus() instead of pci_scan_root_bus()
PCI: designware: Parse bus-range property from devicetree
PCI: designware: Add support for v3.65 hardware
Diffstat (limited to 'drivers/pci/host')
-rw-r--r-- | drivers/pci/host/pcie-designware.c | 79 | ||||
-rw-r--r-- | drivers/pci/host/pcie-designware.h | 3 |
2 files changed, 55 insertions, 27 deletions
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 52bd3a143563..538bbf310e44 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -425,7 +425,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
425 | struct resource *cfg_res; | 425 | struct resource *cfg_res; |
426 | u32 val, na, ns; | 426 | u32 val, na, ns; |
427 | const __be32 *addrp; | 427 | const __be32 *addrp; |
428 | int i, index; | 428 | int i, index, ret; |
429 | 429 | ||
430 | /* Find the address cell size and the number of cells in order to get | 430 | /* Find the address cell size and the number of cells in order to get |
431 | * the untranslated address. | 431 | * the untranslated address. |
@@ -500,6 +500,16 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
500 | } | 500 | } |
501 | } | 501 | } |
502 | 502 | ||
503 | ret = of_pci_parse_bus_range(np, &pp->busn); | ||
504 | if (ret < 0) { | ||
505 | pp->busn.name = np->name; | ||
506 | pp->busn.start = 0; | ||
507 | pp->busn.end = 0xff; | ||
508 | pp->busn.flags = IORESOURCE_BUS; | ||
509 | dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", | ||
510 | ret, &pp->busn); | ||
511 | } | ||
512 | |||
503 | if (!pp->dbi_base) { | 513 | if (!pp->dbi_base) { |
504 | pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, | 514 | pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, |
505 | resource_size(&pp->cfg)); | 515 | resource_size(&pp->cfg)); |
@@ -511,17 +521,24 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
511 | 521 | ||
512 | pp->mem_base = pp->mem.start; | 522 | pp->mem_base = pp->mem.start; |
513 | 523 | ||
514 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, | ||
515 | pp->config.cfg0_size); | ||
516 | if (!pp->va_cfg0_base) { | 524 | if (!pp->va_cfg0_base) { |
517 | dev_err(pp->dev, "error with ioremap in function\n"); | 525 | pp->cfg0_base = pp->cfg.start; |
518 | return -ENOMEM; | 526 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, |
527 | pp->config.cfg0_size); | ||
528 | if (!pp->va_cfg0_base) { | ||
529 | dev_err(pp->dev, "error with ioremap in function\n"); | ||
530 | return -ENOMEM; | ||
531 | } | ||
519 | } | 532 | } |
520 | pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base, | 533 | |
521 | pp->config.cfg1_size); | ||
522 | if (!pp->va_cfg1_base) { | 534 | if (!pp->va_cfg1_base) { |
523 | dev_err(pp->dev, "error with ioremap\n"); | 535 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; |
524 | return -ENOMEM; | 536 | pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base, |
537 | pp->config.cfg1_size); | ||
538 | if (!pp->va_cfg1_base) { | ||
539 | dev_err(pp->dev, "error with ioremap\n"); | ||
540 | return -ENOMEM; | ||
541 | } | ||
525 | } | 542 | } |
526 | 543 | ||
527 | if (of_property_read_u32(np, "num-lanes", &pp->lanes)) { | 544 | if (of_property_read_u32(np, "num-lanes", &pp->lanes)) { |
@@ -530,16 +547,22 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
530 | } | 547 | } |
531 | 548 | ||
532 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 549 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
533 | pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, | 550 | if (!pp->ops->msi_host_init) { |
534 | MAX_MSI_IRQS, &msi_domain_ops, | 551 | pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, |
535 | &dw_pcie_msi_chip); | 552 | MAX_MSI_IRQS, &msi_domain_ops, |
536 | if (!pp->irq_domain) { | 553 | &dw_pcie_msi_chip); |
537 | dev_err(pp->dev, "irq domain init failed\n"); | 554 | if (!pp->irq_domain) { |
538 | return -ENXIO; | 555 | dev_err(pp->dev, "irq domain init failed\n"); |
539 | } | 556 | return -ENXIO; |
557 | } | ||
540 | 558 | ||
541 | for (i = 0; i < MAX_MSI_IRQS; i++) | 559 | for (i = 0; i < MAX_MSI_IRQS; i++) |
542 | irq_create_mapping(pp->irq_domain, i); | 560 | irq_create_mapping(pp->irq_domain, i); |
561 | } else { | ||
562 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); | ||
563 | if (ret < 0) | ||
564 | return ret; | ||
565 | } | ||
543 | } | 566 | } |
544 | 567 | ||
545 | if (pp->ops->host_init) | 568 | if (pp->ops->host_init) |
@@ -558,7 +581,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
558 | dw_pci.private_data = (void **)&pp; | 581 | dw_pci.private_data = (void **)&pp; |
559 | 582 | ||
560 | pci_common_init_dev(pp->dev, &dw_pci); | 583 | pci_common_init_dev(pp->dev, &dw_pci); |
561 | pci_assign_unassigned_resources(); | ||
562 | #ifdef CONFIG_PCI_DOMAINS | 584 | #ifdef CONFIG_PCI_DOMAINS |
563 | dw_pci.domain++; | 585 | dw_pci.domain++; |
564 | #endif | 586 | #endif |
@@ -781,6 +803,7 @@ static int dw_pcie_setup(int nr, struct pci_sys_data *sys) | |||
781 | 803 | ||
782 | sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr; | 804 | sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr; |
783 | pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); | 805 | pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); |
806 | pci_add_resource(&sys->resources, &pp->busn); | ||
784 | 807 | ||
785 | return 1; | 808 | return 1; |
786 | } | 809 | } |
@@ -790,14 +813,16 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) | |||
790 | struct pci_bus *bus; | 813 | struct pci_bus *bus; |
791 | struct pcie_port *pp = sys_to_pcie(sys); | 814 | struct pcie_port *pp = sys_to_pcie(sys); |
792 | 815 | ||
793 | if (pp) { | 816 | pp->root_bus_nr = sys->busnr; |
794 | pp->root_bus_nr = sys->busnr; | 817 | bus = pci_create_root_bus(pp->dev, sys->busnr, |
795 | bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops, | 818 | &dw_pcie_ops, sys, &sys->resources); |
796 | sys, &sys->resources); | 819 | if (!bus) |
797 | } else { | 820 | return NULL; |
798 | bus = NULL; | 821 | |
799 | BUG(); | 822 | pci_scan_child_bus(bus); |
800 | } | 823 | |
824 | if (bus && pp->ops->scan_bus) | ||
825 | pp->ops->scan_bus(pp); | ||
801 | 826 | ||
802 | return bus; | 827 | return bus; |
803 | } | 828 | } |
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index daf81f922cda..a476e60993cb 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h | |||
@@ -48,6 +48,7 @@ struct pcie_port { | |||
48 | struct resource cfg; | 48 | struct resource cfg; |
49 | struct resource io; | 49 | struct resource io; |
50 | struct resource mem; | 50 | struct resource mem; |
51 | struct resource busn; | ||
51 | struct pcie_port_info config; | 52 | struct pcie_port_info config; |
52 | int irq; | 53 | int irq; |
53 | u32 lanes; | 54 | u32 lanes; |
@@ -74,6 +75,8 @@ struct pcie_host_ops { | |||
74 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | 75 | void (*msi_set_irq)(struct pcie_port *pp, int irq); |
75 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | 76 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); |
76 | u32 (*get_msi_data)(struct pcie_port *pp); | 77 | u32 (*get_msi_data)(struct pcie_port *pp); |
78 | void (*scan_bus)(struct pcie_port *pp); | ||
79 | int (*msi_host_init)(struct pcie_port *pp, struct msi_chip *chip); | ||
77 | }; | 80 | }; |
78 | 81 | ||
79 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); | 82 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); |