static phys_addr_t ddw_memory_hotplug_max(void)
 {
-       resource_size_t max_addr = memory_hotplug_max();
-       struct device_node *memory;
+       resource_size_t max_addr;
 
-       for_each_node_by_type(memory, "memory") {
-               struct resource res;
-
-               if (of_address_to_resource(memory, 0, &res))
-                       continue;
-
-               max_addr = max_t(resource_size_t, max_addr, res.end + 1);
-       }
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+       max_addr = hot_add_drconf_memory_max();
+#else
+       max_addr = memblock_end_of_DRAM();
+#endif
 
        return max_addr;
 }
 
        if (direct_mapping) {
                /* DDW maps the whole partition, so enable direct DMA mapping */
-               ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
+               ret = walk_system_ram_range(0, ddw_memory_hotplug_max() >> PAGE_SHIFT,
                                            win64->value, tce_setrange_multi_pSeriesLP_walk);
                if (ret) {
                        dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n",
        struct memory_notify *arg = data;
        int ret = 0;
 
+       /* This notifier can get called when onlining persistent memory as well.
+        * TCEs are not pre-mapped for persistent memory. Persistent memory will
+        * always be above ddw_memory_hotplug_max()
+        */
+
        switch (action) {
        case MEM_GOING_ONLINE:
                spin_lock(&dma_win_list_lock);
                list_for_each_entry(window, &dma_win_list, list) {
-                       if (window->direct) {
+                       if (window->direct && (arg->start_pfn << PAGE_SHIFT) <
+                               ddw_memory_hotplug_max()) {
                                ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn,
                                                arg->nr_pages, window->prop);
                        }
        case MEM_OFFLINE:
                spin_lock(&dma_win_list_lock);
                list_for_each_entry(window, &dma_win_list, list) {
-                       if (window->direct) {
+                       if (window->direct && (arg->start_pfn << PAGE_SHIFT) <
+                               ddw_memory_hotplug_max()) {
                                ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn,
                                                arg->nr_pages, window->prop);
                        }