diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
index a187524..a7bdc21 100644
--- a/arch/arm/plat-orion/addr-map.c
+++ b/arch/arm/plat-orion/addr-map.c
@@ -108,6 +108,81 @@ static void orion_disable_cpu_win(const struct orion_addr_map_cfg *cfg,
 	}
 }
 
+static int orion_window_is_free(const struct orion_addr_map_cfg *cfg,
+				const int win)
+{
+	void __iomem *addr = cfg->win_cfg_base(cfg, win);
+	u32 ctrl = readl(addr + WIN_CTRL_OFF);
+	return !(ctrl & WIN_CTRL_ENABLE);
+}
+
+/*
+ * Find an unused address decoding window, and enable it according to
+ * the arguments passed (base, size, target, attributes, remap).
+ */
+int orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
+			const u32 base, const u32 size,
+			const u8 target, const u8 attr, const u32 remap)
+{
+	int win;
+
+	/*
+	 * If we don't need to remap, try to first allocate a window
+	 * that doesn't have remapping capabilities, since those are
+	 * pretty limited in number.
+	 */
+	if (remap == ORION_ADDR_MAP_NO_REMAP) {
+		for (win = cfg->remappable_wins; win < cfg->num_wins; win++)
+			if (orion_window_is_free(cfg, win))
+				break;
+
+		if (win < cfg->num_wins) {
+			orion_setup_cpu_win(cfg, win, base, size, target, attr, remap);
+			return 0;
+		}
+	}
+
+	/*
+	 * We need a remap window, or we haven't found a non-remap
+	 * capable window.
+	 */
+	for (win = 0; win < cfg->num_wins; win++)
+		if (orion_window_is_free(cfg, win))
+			break;
+
+	if (win < cfg->num_wins) {
+		orion_setup_cpu_win(cfg, win, base, size, target, attr, remap);
+		return 0;
+	}
+
+	/* No window found */
+	return -ENOMEM;
+}
+
+/*
+ * Free an address decoding window, given its base address.
+ */
+int orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
+		       const u32 base)
+{
+	int win;
+
+	for (win = 0; win < cfg->num_wins; win++) {
+		void __iomem *addr = cfg->win_cfg_base(cfg, win);
+		u32 winbase = readl(addr + WIN_BASE_OFF);
+
+		if (orion_window_is_free(cfg, win))
+			continue;
+
+		if (winbase == (base & 0xffff0000)) {
+			orion_disable_cpu_win(cfg, win);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 /*
  * Configure a number of windows.
  */
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h
index a5b21a9..fc46878 100644
--- a/arch/arm/plat-orion/include/plat/addr-map.h
+++ b/arch/arm/plat-orion/include/plat/addr-map.h
@@ -51,6 +51,13 @@ void orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
 			 const u32 size, const u8 target,
 			 const u8 attr, const u32 remap);
 
+int orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg,
+			const u32 base, const u32 size,
+			const u8 target, const u8 attr, const u32 remap);
+
+int orion_free_cpu_win(const struct orion_addr_map_cfg *cfg,
+		       const u32 base);
+
 void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
 					const void __iomem *ddr_window_cpu_base);
 #endif
