aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c52
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
697delprop: 697delprop:
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
728static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn) 728static 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}
759machine_arch_initcall(pseries, find_existing_ddw_windows);
760 760
761static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, 761static 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