Move the discovery of windows previously setup from when the pci driver
calls set_dma_mask to an arch_initcall.
When kexecing into a kernel with dynamic dma windows allocated, we need
to find the windows early so that memory hot remove will be able to
delete the tces mapping the to be removed memory and memory hotplug add
will map the new memory into the window. We should not wait for the
driver to be loaded and the device to be probed. The iommu init hooks
are before kmalloc is setup, so defer to arch_initcall.
Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
np->full_name, ret, ddr_avail[2], liobn);
delprop:
np->full_name, ret, ddr_avail[2], liobn);
delprop:
- ret = of_remove_property(np, win64);
+ ret = prom_remove_property(np, win64);
- pr_warning("%s: failed to remove direct window property: %d\n"
+ pr_warning("%s: failed to remove direct window property: %d\n",
-static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn)
+static int find_existing_ddw_windows(void)
- struct device_node *dn;
- struct pci_dn *pcidn;
+ struct device_node *pdn;
struct direct_window *window;
const struct dynamic_dma_window_prop *direct64;
struct direct_window *window;
const struct dynamic_dma_window_prop *direct64;
- dn = pci_device_to_OF_node(dev);
- pcidn = PCI_DN(dn);
- direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
- if (direct64) {
- if (len < sizeof(struct dynamic_dma_window_prop)) {
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
+ return 0;
+
+ for_each_node_with_property(pdn, DIRECT64_PROPNAME) {
+ direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
+ if (!direct64)
+ continue;
+
+ window = kzalloc(sizeof(*window), GFP_KERNEL);
+ if (!window || len < sizeof(struct dynamic_dma_window_prop)) {
+ kfree(window);
- } else {
- window = kzalloc(sizeof(*window), GFP_KERNEL);
- if (!window) {
- remove_ddw(pdn);
- } else {
- window->device = pdn;
- window->prop = direct64;
- spin_lock(&direct_window_list_lock);
- list_add(&window->list, &direct_window_list);
- spin_unlock(&direct_window_list_lock);
- dma_addr = direct64->dma_base;
- }
+
+ window->device = pdn;
+ window->prop = direct64;
+ spin_lock(&direct_window_list_lock);
+ list_add(&window->list, &direct_window_list);
+ spin_unlock(&direct_window_list_lock);
+machine_arch_initcall(pseries, find_existing_ddw_windows);
static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail,
struct ddw_query_response *query)
static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail,
struct ddw_query_response *query)
if (dma_addr != 0)
goto out_unlock;
if (dma_addr != 0)
goto out_unlock;
- dma_addr = dupe_ddw_if_kexec(dev, pdn);
- if (dma_addr != 0)
- goto out_unlock;
-
/*
* the ibm,ddw-applicable property holds the tokens for:
* ibm,query-pe-dma-window
/*
* the ibm,ddw-applicable property holds the tokens for:
* ibm,query-pe-dma-window