diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a0421ac46d4e..a48f12644239 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -695,9 +695,9 @@ static void remove_ddw(struct device_node *np) | |||
695 | np->full_name, ret, ddr_avail[2], liobn); | 695 | np->full_name, ret, ddr_avail[2], liobn); |
696 | 696 | ||
697 | delprop: | 697 | delprop: |
698 | ret = of_remove_property(np, win64); | 698 | ret = prom_remove_property(np, win64); |
699 | if (ret) | 699 | if (ret) |
700 | pr_warning("%s: failed to remove direct window property: %d\n" | 700 | pr_warning("%s: failed to remove direct window property: %d\n", |
701 | np->full_name, ret); | 701 | np->full_name, ret); |
702 | } | 702 | } |
703 | 703 | ||
@@ -725,38 +725,38 @@ static u64 dupe_ddw_if_already_created(struct pci_dev *dev, struct device_node * | |||
725 | return dma_addr; | 725 | return dma_addr; |
726 | } | 726 | } |
727 | 727 | ||
728 | static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn) | 728 | static int find_existing_ddw_windows(void) |
729 | { | 729 | { |
730 | struct device_node *dn; | ||
731 | struct pci_dn *pcidn; | ||
732 | int len; | 730 | int len; |
731 | struct device_node *pdn; | ||
733 | struct direct_window *window; | 732 | struct direct_window *window; |
734 | const struct dynamic_dma_window_prop *direct64; | 733 | const struct dynamic_dma_window_prop *direct64; |
735 | u64 dma_addr = 0; | ||
736 | 734 | ||
737 | dn = pci_device_to_OF_node(dev); | 735 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
738 | pcidn = PCI_DN(dn); | 736 | return 0; |
739 | direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len); | 737 | |
740 | if (direct64) { | 738 | for_each_node_with_property(pdn, DIRECT64_PROPNAME) { |
741 | if (len < sizeof(struct dynamic_dma_window_prop)) { | 739 | direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len); |
740 | if (!direct64) | ||
741 | continue; | ||
742 | |||
743 | window = kzalloc(sizeof(*window), GFP_KERNEL); | ||
744 | if (!window || len < sizeof(struct dynamic_dma_window_prop)) { | ||
745 | kfree(window); | ||
742 | remove_ddw(pdn); | 746 | remove_ddw(pdn); |
743 | } else { | 747 | continue; |
744 | window = kzalloc(sizeof(*window), GFP_KERNEL); | ||
745 | if (!window) { | ||
746 | remove_ddw(pdn); | ||
747 | } else { | ||
748 | window->device = pdn; | ||
749 | window->prop = direct64; | ||
750 | spin_lock(&direct_window_list_lock); | ||
751 | list_add(&window->list, &direct_window_list); | ||
752 | spin_unlock(&direct_window_list_lock); | ||
753 | dma_addr = direct64->dma_base; | ||
754 | } | ||
755 | } | 748 | } |
749 | |||
750 | window->device = pdn; | ||
751 | window->prop = direct64; | ||
752 | spin_lock(&direct_window_list_lock); | ||
753 | list_add(&window->list, &direct_window_list); | ||
754 | spin_unlock(&direct_window_list_lock); | ||
756 | } | 755 | } |
757 | 756 | ||
758 | return dma_addr; | 757 | return 0; |
759 | } | 758 | } |
759 | machine_arch_initcall(pseries, find_existing_ddw_windows); | ||
760 | 760 | ||
761 | static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, | 761 | static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, |
762 | struct ddw_query_response *query) | 762 | struct ddw_query_response *query) |
@@ -854,10 +854,6 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
854 | if (dma_addr != 0) | 854 | if (dma_addr != 0) |
855 | goto out_unlock; | 855 | goto out_unlock; |
856 | 856 | ||
857 | dma_addr = dupe_ddw_if_kexec(dev, pdn); | ||
858 | if (dma_addr != 0) | ||
859 | goto out_unlock; | ||
860 | |||
861 | /* | 857 | /* |
862 | * the ibm,ddw-applicable property holds the tokens for: | 858 | * the ibm,ddw-applicable property holds the tokens for: |
863 | * ibm,query-pe-dma-window | 859 | * ibm,query-pe-dma-window |