.. | .. |
---|
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[] = { |
---|