diff options
Diffstat (limited to 'drivers/firmware/memmap.c')
| -rw-r--r-- | drivers/firmware/memmap.c | 61 | 
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 001622eb86f..3bf8ee120d4 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -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;  |