| .. | .. |
|---|
| 239 | 239 | struct device *dev; |
|---|
| 240 | 240 | void __iomem *base; |
|---|
| 241 | 241 | void __iomem *config_base; |
|---|
| 242 | | - struct pci_bus *bus; |
|---|
| 243 | 242 | u32 config_mem; |
|---|
| 244 | | - u32 io_mem; |
|---|
| 245 | 243 | u32 non_pre_mem; |
|---|
| 246 | 244 | u32 pre_mem; |
|---|
| 247 | | - phys_addr_t io_bus_addr; |
|---|
| 248 | 245 | phys_addr_t non_pre_bus_addr; |
|---|
| 249 | 246 | phys_addr_t pre_bus_addr; |
|---|
| 250 | 247 | struct regmap *map; |
|---|
| .. | .. |
|---|
| 520 | 517 | } |
|---|
| 521 | 518 | |
|---|
| 522 | 519 | static int v3_pci_setup_resource(struct v3_pci *v3, |
|---|
| 523 | | - resource_size_t io_base, |
|---|
| 524 | 520 | struct pci_host_bridge *host, |
|---|
| 525 | 521 | struct resource_entry *win) |
|---|
| 526 | 522 | { |
|---|
| 527 | 523 | struct device *dev = v3->dev; |
|---|
| 528 | 524 | struct resource *mem; |
|---|
| 529 | 525 | struct resource *io; |
|---|
| 530 | | - int ret; |
|---|
| 531 | 526 | |
|---|
| 532 | 527 | switch (resource_type(win->res)) { |
|---|
| 533 | 528 | case IORESOURCE_IO: |
|---|
| 534 | 529 | io = win->res; |
|---|
| 535 | | - io->name = "V3 PCI I/O"; |
|---|
| 536 | | - v3->io_mem = io_base; |
|---|
| 537 | | - v3->io_bus_addr = io->start - win->offset; |
|---|
| 538 | | - dev_dbg(dev, "I/O window %pR, bus addr %pap\n", |
|---|
| 539 | | - io, &v3->io_bus_addr); |
|---|
| 540 | | - ret = devm_pci_remap_iospace(dev, io, io_base); |
|---|
| 541 | | - if (ret) { |
|---|
| 542 | | - dev_warn(dev, |
|---|
| 543 | | - "error %d: failed to map resource %pR\n", |
|---|
| 544 | | - ret, io); |
|---|
| 545 | | - return ret; |
|---|
| 546 | | - } |
|---|
| 530 | + |
|---|
| 547 | 531 | /* Setup window 2 - PCI I/O */ |
|---|
| 548 | | - writel(v3_addr_to_lb_base2(v3->io_mem) | |
|---|
| 532 | + writel(v3_addr_to_lb_base2(pci_pio_to_address(io->start)) | |
|---|
| 549 | 533 | V3_LB_BASE2_ENABLE, |
|---|
| 550 | 534 | v3->base + V3_LB_BASE2); |
|---|
| 551 | | - writew(v3_addr_to_lb_map2(v3->io_bus_addr), |
|---|
| 535 | + writew(v3_addr_to_lb_map2(io->start - win->offset), |
|---|
| 552 | 536 | v3->base + V3_LB_MAP2); |
|---|
| 553 | 537 | break; |
|---|
| 554 | 538 | case IORESOURCE_MEM: |
|---|
| .. | .. |
|---|
| 600 | 584 | } |
|---|
| 601 | 585 | break; |
|---|
| 602 | 586 | case IORESOURCE_BUS: |
|---|
| 603 | | - dev_dbg(dev, "BUS %pR\n", win->res); |
|---|
| 604 | | - host->busnr = win->res->start; |
|---|
| 605 | 587 | break; |
|---|
| 606 | 588 | default: |
|---|
| 607 | 589 | dev_info(dev, "Unknown resource type %lu\n", |
|---|
| .. | .. |
|---|
| 613 | 595 | } |
|---|
| 614 | 596 | |
|---|
| 615 | 597 | static int v3_get_dma_range_config(struct v3_pci *v3, |
|---|
| 616 | | - struct of_pci_range *range, |
|---|
| 598 | + struct resource_entry *entry, |
|---|
| 617 | 599 | u32 *pci_base, u32 *pci_map) |
|---|
| 618 | 600 | { |
|---|
| 619 | 601 | struct device *dev = v3->dev; |
|---|
| 620 | | - u64 cpu_end = range->cpu_addr + range->size - 1; |
|---|
| 621 | | - u64 pci_end = range->pci_addr + range->size - 1; |
|---|
| 602 | + u64 cpu_addr = entry->res->start; |
|---|
| 603 | + u64 cpu_end = entry->res->end; |
|---|
| 604 | + u64 pci_end = cpu_end - entry->offset; |
|---|
| 605 | + u64 pci_addr = entry->res->start - entry->offset; |
|---|
| 622 | 606 | u32 val; |
|---|
| 623 | 607 | |
|---|
| 624 | | - if (range->pci_addr & ~V3_PCI_BASE_M_ADR_BASE) { |
|---|
| 608 | + if (pci_addr & ~V3_PCI_BASE_M_ADR_BASE) { |
|---|
| 625 | 609 | dev_err(dev, "illegal range, only PCI bits 31..20 allowed\n"); |
|---|
| 626 | 610 | return -EINVAL; |
|---|
| 627 | 611 | } |
|---|
| 628 | | - val = ((u32)range->pci_addr) & V3_PCI_BASE_M_ADR_BASE; |
|---|
| 612 | + val = ((u32)pci_addr) & V3_PCI_BASE_M_ADR_BASE; |
|---|
| 629 | 613 | *pci_base = val; |
|---|
| 630 | 614 | |
|---|
| 631 | | - if (range->cpu_addr & ~V3_PCI_MAP_M_MAP_ADR) { |
|---|
| 615 | + if (cpu_addr & ~V3_PCI_MAP_M_MAP_ADR) { |
|---|
| 632 | 616 | dev_err(dev, "illegal range, only CPU bits 31..20 allowed\n"); |
|---|
| 633 | 617 | return -EINVAL; |
|---|
| 634 | 618 | } |
|---|
| 635 | | - val = ((u32)range->cpu_addr) & V3_PCI_MAP_M_MAP_ADR; |
|---|
| 619 | + val = ((u32)cpu_addr) & V3_PCI_MAP_M_MAP_ADR; |
|---|
| 636 | 620 | |
|---|
| 637 | | - switch (range->size) { |
|---|
| 621 | + switch (resource_size(entry->res)) { |
|---|
| 638 | 622 | case SZ_1M: |
|---|
| 639 | 623 | val |= V3_LB_BASE_ADR_SIZE_1MB; |
|---|
| 640 | 624 | break; |
|---|
| .. | .. |
|---|
| 674 | 658 | default: |
|---|
| 675 | 659 | dev_err(v3->dev, "illegal dma memory chunk size\n"); |
|---|
| 676 | 660 | return -EINVAL; |
|---|
| 677 | | - break; |
|---|
| 678 | 661 | } |
|---|
| 679 | 662 | val |= V3_PCI_MAP_M_REG_EN | V3_PCI_MAP_M_ENABLE; |
|---|
| 680 | 663 | *pci_map = val; |
|---|
| .. | .. |
|---|
| 682 | 665 | dev_dbg(dev, |
|---|
| 683 | 666 | "DMA MEM CPU: 0x%016llx -> 0x%016llx => " |
|---|
| 684 | 667 | "PCI: 0x%016llx -> 0x%016llx base %08x map %08x\n", |
|---|
| 685 | | - range->cpu_addr, cpu_end, |
|---|
| 686 | | - range->pci_addr, pci_end, |
|---|
| 668 | + cpu_addr, cpu_end, |
|---|
| 669 | + pci_addr, pci_end, |
|---|
| 687 | 670 | *pci_base, *pci_map); |
|---|
| 688 | 671 | |
|---|
| 689 | 672 | return 0; |
|---|
| .. | .. |
|---|
| 692 | 675 | static int v3_pci_parse_map_dma_ranges(struct v3_pci *v3, |
|---|
| 693 | 676 | struct device_node *np) |
|---|
| 694 | 677 | { |
|---|
| 695 | | - struct of_pci_range range; |
|---|
| 696 | | - struct of_pci_range_parser parser; |
|---|
| 678 | + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(v3); |
|---|
| 697 | 679 | struct device *dev = v3->dev; |
|---|
| 680 | + struct resource_entry *entry; |
|---|
| 698 | 681 | int i = 0; |
|---|
| 699 | 682 | |
|---|
| 700 | | - if (of_pci_dma_range_parser_init(&parser, np)) { |
|---|
| 701 | | - dev_err(dev, "missing dma-ranges property\n"); |
|---|
| 702 | | - return -EINVAL; |
|---|
| 703 | | - } |
|---|
| 704 | | - |
|---|
| 705 | | - /* |
|---|
| 706 | | - * Get the dma-ranges from the device tree |
|---|
| 707 | | - */ |
|---|
| 708 | | - for_each_of_pci_range(&parser, &range) { |
|---|
| 683 | + resource_list_for_each_entry(entry, &bridge->dma_ranges) { |
|---|
| 709 | 684 | int ret; |
|---|
| 710 | 685 | u32 pci_base, pci_map; |
|---|
| 711 | 686 | |
|---|
| 712 | | - ret = v3_get_dma_range_config(v3, &range, &pci_base, &pci_map); |
|---|
| 687 | + ret = v3_get_dma_range_config(v3, entry, &pci_base, &pci_map); |
|---|
| 713 | 688 | if (ret) |
|---|
| 714 | 689 | return ret; |
|---|
| 715 | 690 | |
|---|
| .. | .. |
|---|
| 732 | 707 | { |
|---|
| 733 | 708 | struct device *dev = &pdev->dev; |
|---|
| 734 | 709 | struct device_node *np = dev->of_node; |
|---|
| 735 | | - resource_size_t io_base; |
|---|
| 736 | 710 | struct resource *regs; |
|---|
| 737 | 711 | struct resource_entry *win; |
|---|
| 738 | 712 | struct v3_pci *v3; |
|---|
| .. | .. |
|---|
| 741 | 715 | u16 val; |
|---|
| 742 | 716 | int irq; |
|---|
| 743 | 717 | int ret; |
|---|
| 744 | | - LIST_HEAD(res); |
|---|
| 745 | 718 | |
|---|
| 746 | 719 | host = devm_pci_alloc_host_bridge(dev, sizeof(*v3)); |
|---|
| 747 | 720 | if (!host) |
|---|
| 748 | 721 | return -ENOMEM; |
|---|
| 749 | 722 | |
|---|
| 750 | | - host->dev.parent = dev; |
|---|
| 751 | 723 | host->ops = &v3_pci_ops; |
|---|
| 752 | | - host->busnr = 0; |
|---|
| 753 | | - host->msi = NULL; |
|---|
| 754 | | - host->map_irq = of_irq_parse_and_map_pci; |
|---|
| 755 | | - host->swizzle_irq = pci_common_swizzle; |
|---|
| 756 | 724 | v3 = pci_host_bridge_priv(host); |
|---|
| 757 | 725 | host->sysdata = v3; |
|---|
| 758 | 726 | v3->dev = dev; |
|---|
| .. | .. |
|---|
| 793 | 761 | if (IS_ERR(v3->config_base)) |
|---|
| 794 | 762 | return PTR_ERR(v3->config_base); |
|---|
| 795 | 763 | |
|---|
| 796 | | - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, |
|---|
| 797 | | - &io_base); |
|---|
| 798 | | - if (ret) |
|---|
| 799 | | - return ret; |
|---|
| 800 | | - |
|---|
| 801 | | - ret = devm_request_pci_bus_resources(dev, &res); |
|---|
| 802 | | - if (ret) |
|---|
| 803 | | - return ret; |
|---|
| 804 | | - |
|---|
| 805 | 764 | /* Get and request error IRQ resource */ |
|---|
| 806 | 765 | irq = platform_get_irq(pdev, 0); |
|---|
| 807 | | - if (irq <= 0) { |
|---|
| 808 | | - dev_err(dev, "unable to obtain PCIv3 error IRQ\n"); |
|---|
| 809 | | - return -ENODEV; |
|---|
| 810 | | - } |
|---|
| 766 | + if (irq < 0) |
|---|
| 767 | + return irq; |
|---|
| 768 | + |
|---|
| 811 | 769 | ret = devm_request_irq(dev, irq, v3_irq, 0, |
|---|
| 812 | 770 | "PCIv3 error", v3); |
|---|
| 813 | 771 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 852 | 810 | writew(val, v3->base + V3_PCI_CMD); |
|---|
| 853 | 811 | |
|---|
| 854 | 812 | /* Get the I/O and memory ranges from DT */ |
|---|
| 855 | | - resource_list_for_each_entry(win, &res) { |
|---|
| 856 | | - ret = v3_pci_setup_resource(v3, io_base, host, win); |
|---|
| 813 | + resource_list_for_each_entry(win, &host->windows) { |
|---|
| 814 | + ret = v3_pci_setup_resource(v3, host, win); |
|---|
| 857 | 815 | if (ret) { |
|---|
| 858 | 816 | dev_err(dev, "error setting up resources\n"); |
|---|
| 859 | 817 | return ret; |
|---|
| .. | .. |
|---|
| 931 | 889 | val |= V3_SYSTEM_M_LOCK; |
|---|
| 932 | 890 | writew(val, v3->base + V3_SYSTEM); |
|---|
| 933 | 891 | |
|---|
| 934 | | - list_splice_init(&res, &host->windows); |
|---|
| 935 | | - ret = pci_scan_root_bus_bridge(host); |
|---|
| 936 | | - if (ret) { |
|---|
| 937 | | - dev_err(dev, "failed to register host: %d\n", ret); |
|---|
| 938 | | - return ret; |
|---|
| 939 | | - } |
|---|
| 940 | | - v3->bus = host->bus; |
|---|
| 941 | | - |
|---|
| 942 | | - pci_bus_assign_resources(v3->bus); |
|---|
| 943 | | - pci_bus_add_devices(v3->bus); |
|---|
| 944 | | - |
|---|
| 945 | | - return 0; |
|---|
| 892 | + return pci_host_probe(host); |
|---|
| 946 | 893 | } |
|---|
| 947 | 894 | |
|---|
| 948 | 895 | static const struct of_device_id v3_pci_of_match[] = { |
|---|