]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/linux/memblock.h
Merge tag 'mmc-updates-for-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / include / linux / memblock.h
index 8a20a51ed42d9c53c1b57153106fe33a0a61d78c..b660e05b63d4fbc90e211d569f6d0229a2041fcc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 
 #define INIT_MEMBLOCK_REGIONS  128
+#define INIT_PHYSMEM_REGIONS   4
 
 /* Definition of memblock flags. */
 #define MEMBLOCK_HOTPLUG       0x1     /* hotpluggable region */
@@ -43,6 +44,9 @@ struct memblock {
        phys_addr_t current_limit;
        struct memblock_type memory;
        struct memblock_type reserved;
+#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
+       struct memblock_type physmem;
+#endif
 };
 
 extern struct memblock memblock;
@@ -71,6 +75,63 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size);
 void memblock_trim_memory(phys_addr_t align);
 int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
 int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
+
+/* Low level functions */
+int memblock_add_range(struct memblock_type *type,
+                      phys_addr_t base, phys_addr_t size,
+                      int nid, unsigned long flags);
+
+int memblock_remove_range(struct memblock_type *type,
+                         phys_addr_t base,
+                         phys_addr_t size);
+
+void __next_mem_range(u64 *idx, int nid, struct memblock_type *type_a,
+                     struct memblock_type *type_b, phys_addr_t *out_start,
+                     phys_addr_t *out_end, int *out_nid);
+
+void __next_mem_range_rev(u64 *idx, int nid, struct memblock_type *type_a,
+                         struct memblock_type *type_b, phys_addr_t *out_start,
+                         phys_addr_t *out_end, int *out_nid);
+
+/**
+ * for_each_mem_range - iterate through memblock areas from type_a and not
+ * included in type_b. Or just type_a if type_b is NULL.
+ * @i: u64 used as loop variable
+ * @type_a: ptr to memblock_type to iterate
+ * @type_b: ptr to memblock_type which excludes from the iteration
+ * @nid: node selector, %NUMA_NO_NODE for all nodes
+ * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
+ * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
+ * @p_nid: ptr to int for nid of the range, can be %NULL
+ */
+#define for_each_mem_range(i, type_a, type_b, nid,                     \
+                          p_start, p_end, p_nid)                       \
+       for (i = 0, __next_mem_range(&i, nid, type_a, type_b,           \
+                                    p_start, p_end, p_nid);            \
+            i != (u64)ULLONG_MAX;                                      \
+            __next_mem_range(&i, nid, type_a, type_b,                  \
+                             p_start, p_end, p_nid))
+
+/**
+ * for_each_mem_range_rev - reverse iterate through memblock areas from
+ * type_a and not included in type_b. Or just type_a if type_b is NULL.
+ * @i: u64 used as loop variable
+ * @type_a: ptr to memblock_type to iterate
+ * @type_b: ptr to memblock_type which excludes from the iteration
+ * @nid: node selector, %NUMA_NO_NODE for all nodes
+ * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
+ * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
+ * @p_nid: ptr to int for nid of the range, can be %NULL
+ */
+#define for_each_mem_range_rev(i, type_a, type_b, nid,                 \
+                              p_start, p_end, p_nid)                   \
+       for (i = (u64)ULLONG_MAX,                                       \
+                    __next_mem_range_rev(&i, nid, type_a, type_b,      \
+                                        p_start, p_end, p_nid);        \
+            i != (u64)ULLONG_MAX;                                      \
+            __next_mem_range_rev(&i, nid, type_a, type_b,              \
+                                 p_start, p_end, p_nid))
+
 #ifdef CONFIG_MOVABLE_NODE
 static inline bool memblock_is_hotpluggable(struct memblock_region *m)
 {
@@ -113,9 +174,6 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
             i >= 0; __next_mem_pfn_range(&i, nid, p_start, p_end, p_nid))
 #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
 
-void __next_free_mem_range(u64 *idx, int nid, phys_addr_t *out_start,
-                          phys_addr_t *out_end, int *out_nid);
-
 /**
  * for_each_free_mem_range - iterate through free memblock areas
  * @i: u64 used as loop variable
@@ -128,13 +186,8 @@ void __next_free_mem_range(u64 *idx, int nid, phys_addr_t *out_start,
  * soon as memblock is initialized.
  */
 #define for_each_free_mem_range(i, nid, p_start, p_end, p_nid)         \
-       for (i = 0,                                                     \
-            __next_free_mem_range(&i, nid, p_start, p_end, p_nid);     \
-            i != (u64)ULLONG_MAX;                                      \
-            __next_free_mem_range(&i, nid, p_start, p_end, p_nid))
-
-void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,
-                              phys_addr_t *out_end, int *out_nid);
+       for_each_mem_range(i, &memblock.memory, &memblock.reserved,     \
+                          nid, p_start, p_end, p_nid)
 
 /**
  * for_each_free_mem_range_reverse - rev-iterate through free memblock areas
@@ -148,10 +201,8 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,
  * order.  Available as soon as memblock is initialized.
  */
 #define for_each_free_mem_range_reverse(i, nid, p_start, p_end, p_nid) \
-       for (i = (u64)ULLONG_MAX,                                       \
-            __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid); \
-            i != (u64)ULLONG_MAX;                                      \
-            __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid))
+       for_each_mem_range_rev(i, &memblock.memory, &memblock.reserved, \
+                              nid, p_start, p_end, p_nid)
 
 static inline void memblock_set_region_flags(struct memblock_region *r,
                                             unsigned long flags)
@@ -221,6 +272,8 @@ static inline bool memblock_bottom_up(void) { return false; }
 #define MEMBLOCK_ALLOC_ANYWHERE        (~(phys_addr_t)0)
 #define MEMBLOCK_ALLOC_ACCESSIBLE      0
 
+phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
+                                       phys_addr_t start, phys_addr_t end);
 phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align,
                                phys_addr_t max_addr);
 phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align,