|
@@ -84,20 +84,23 @@ static struct kobj_type memmap_ktype = {
|
|
|
*/
|
|
|
|
|
|
/*
|
|
|
- * Firmware memory map entries
|
|
|
+ * Firmware memory map entries. No locking is needed because the
|
|
|
+ * firmware_map_add() and firmware_map_add_early() functions are called
|
|
|
+ * in firmware initialisation code in one single thread of execution.
|
|
|
*/
|
|
|
static LIST_HEAD(map_entries);
|
|
|
|
|
|
/**
|
|
|
- * Common implementation of firmware_map_add() and firmware_map_add_early()
|
|
|
- * which expects a pre-allocated struct firmware_map_entry.
|
|
|
- *
|
|
|
+ * firmware_map_add_entry() - Does the real work to add a firmware memmap entry.
|
|
|
* @start: Start of the memory range.
|
|
|
* @end: End of the memory range (inclusive).
|
|
|
* @type: Type of the memory range.
|
|
|
* @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised
|
|
|
* entry.
|
|
|
- */
|
|
|
+ *
|
|
|
+ * Common implementation of firmware_map_add() and firmware_map_add_early()
|
|
|
+ * which expects a pre-allocated struct firmware_map_entry.
|
|
|
+ **/
|
|
|
static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
|
|
|
const char *type,
|
|
|
struct firmware_map_entry *entry)
|
|
@@ -115,33 +118,52 @@ static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * See <linux/firmware-map.h> for documentation.
|
|
|
- */
|
|
|
+/**
|
|
|
+ * firmware_map_add() - Adds a firmware mapping entry.
|
|
|
+ * @start: Start of the memory range.
|
|
|
+ * @end: End of the memory range (inclusive).
|
|
|
+ * @type: Type of the memory range.
|
|
|
+ *
|
|
|
+ * This function uses kmalloc() for memory
|
|
|
+ * allocation. Use firmware_map_add_early() if you want to use the bootmem
|
|
|
+ * allocator.
|
|
|
+ *
|
|
|
+ * That function must be called before late_initcall.
|
|
|
+ *
|
|
|
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
|
|
|
+ **/
|
|
|
int firmware_map_add(resource_size_t start, resource_size_t end,
|
|
|
const char *type)
|
|
|
{
|
|
|
struct firmware_map_entry *entry;
|
|
|
|
|
|
entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
|
|
|
- WARN_ON(!entry);
|
|
|
if (!entry)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
return firmware_map_add_entry(start, end, type, entry);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * See <linux/firmware-map.h> for documentation.
|
|
|
- */
|
|
|
+/**
|
|
|
+ * firmware_map_add_early() - Adds a firmware mapping entry.
|
|
|
+ * @start: Start of the memory range.
|
|
|
+ * @end: End of the memory range (inclusive).
|
|
|
+ * @type: Type of the memory range.
|
|
|
+ *
|
|
|
+ * Adds a firmware mapping entry. This function uses the bootmem allocator
|
|
|
+ * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
|
|
|
+ *
|
|
|
+ * That function must be called before late_initcall.
|
|
|
+ *
|
|
|
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
|
|
|
+ **/
|
|
|
int __init firmware_map_add_early(resource_size_t start, resource_size_t end,
|
|
|
const char *type)
|
|
|
{
|
|
|
struct firmware_map_entry *entry;
|
|
|
|
|
|
entry = alloc_bootmem_low(sizeof(struct firmware_map_entry));
|
|
|
- WARN_ON(!entry);
|
|
|
- if (!entry)
|
|
|
+ if (WARN_ON(!entry))
|
|
|
return -ENOMEM;
|
|
|
|
|
|
return firmware_map_add_entry(start, end, type, entry);
|
|
@@ -183,7 +205,10 @@ static ssize_t memmap_attr_show(struct kobject *kobj,
|
|
|
/*
|
|
|
* Initialises stuff and adds the entries in the map_entries list to
|
|
|
* sysfs. Important is that firmware_map_add() and firmware_map_add_early()
|
|
|
- * must be called before late_initcall.
|
|
|
+ * must be called before late_initcall. That's just because that function
|
|
|
+ * is called as late_initcall() function, which means that if you call
|
|
|
+ * firmware_map_add() or firmware_map_add_early() afterwards, the entries
|
|
|
+ * are not added to sysfs.
|
|
|
*/
|
|
|
static int __init memmap_init(void)
|
|
|
{
|
|
@@ -192,13 +217,13 @@ static int __init memmap_init(void)
|
|
|
struct kset *memmap_kset;
|
|
|
|
|
|
memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
|
|
|
- WARN_ON(!memmap_kset);
|
|
|
- if (!memmap_kset)
|
|
|
+ if (WARN_ON(!memmap_kset))
|
|
|
return -ENOMEM;
|
|
|
|
|
|
list_for_each_entry(entry, &map_entries, list) {
|
|
|
entry->kobj.kset = memmap_kset;
|
|
|
- kobject_add(&entry->kobj, NULL, "%d", i++);
|
|
|
+ if (kobject_add(&entry->kobj, NULL, "%d", i++))
|
|
|
+ kobject_put(&entry->kobj);
|
|
|
}
|
|
|
|
|
|
return 0;
|