diff options
Diffstat (limited to 'drivers/firmware/google/vpd.c')
-rw-r--r-- | drivers/firmware/google/vpd.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 3ce813110d5e..78945729388e 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -116,11 +116,14 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, return VPD_OK; info = kzalloc(sizeof(*info), GFP_KERNEL); - info->key = kzalloc(key_len + 1, GFP_KERNEL); - if (!info->key) + if (!info) return -ENOMEM; - memcpy(info->key, key, key_len); + info->key = kstrndup(key, key_len, GFP_KERNEL); + if (!info->key) { + ret = -ENOMEM; + goto free_info; + } sysfs_bin_attr_init(&info->bin_attr); info->bin_attr.attr.name = info->key; @@ -132,15 +135,20 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, info->value = value; INIT_LIST_HEAD(&info->list); - list_add_tail(&info->list, &sec->attribs); ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr); - if (ret) { - kfree(info->key); - return ret; - } + if (ret) + goto free_info_key; + list_add_tail(&info->list, &sec->attribs); return 0; + +free_info_key: + kfree(info->key); +free_info: + kfree(info); + + return ret; } static void vpd_section_attrib_destroy(struct vpd_section *sec) @@ -149,8 +157,8 @@ static void vpd_section_attrib_destroy(struct vpd_section *sec) struct vpd_attrib_info *temp; list_for_each_entry_safe(info, temp, &sec->attribs, list) { - kfree(info->key); sysfs_remove_bin_file(sec->kobj, &info->bin_attr); + kfree(info->key); kfree(info); } } @@ -182,8 +190,7 @@ static int vpd_section_create_attribs(struct vpd_section *sec) static int vpd_section_init(const char *name, struct vpd_section *sec, phys_addr_t physaddr, size_t size) { - int ret; - int raw_len; + int err; sec->baseaddr = memremap(physaddr, size, MEMREMAP_WB); if (!sec->baseaddr) @@ -192,10 +199,11 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, sec->name = name; /* We want to export the raw partion with name ${name}_raw */ - raw_len = strlen(name) + 5; - sec->raw_name = kzalloc(raw_len, GFP_KERNEL); - strncpy(sec->raw_name, name, raw_len); - strncat(sec->raw_name, "_raw", raw_len); + sec->raw_name = kasprintf(GFP_KERNEL, "%s_raw", name); + if (!sec->raw_name) { + err = -ENOMEM; + goto err_iounmap; + } sysfs_bin_attr_init(&sec->bin_attr); sec->bin_attr.attr.name = sec->raw_name; @@ -204,14 +212,14 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, sec->bin_attr.read = vpd_section_read; sec->bin_attr.private = sec; - ret = sysfs_create_bin_file(vpd_kobj, &sec->bin_attr); - if (ret) - goto free_sec; + err = sysfs_create_bin_file(vpd_kobj, &sec->bin_attr); + if (err) + goto err_free_raw_name; sec->kobj = kobject_create_and_add(name, vpd_kobj); if (!sec->kobj) { - ret = -EINVAL; - goto sysfs_remove; + err = -EINVAL; + goto err_sysfs_remove; } INIT_LIST_HEAD(&sec->attribs); @@ -221,21 +229,20 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, return 0; -sysfs_remove: +err_sysfs_remove: sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); - -free_sec: +err_free_raw_name: kfree(sec->raw_name); +err_iounmap: iounmap(sec->baseaddr); - - return ret; + return err; } static int vpd_section_destroy(struct vpd_section *sec) { if (sec->enabled) { vpd_section_attrib_destroy(sec); - kobject_del(sec->kobj); + kobject_put(sec->kobj); sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); kfree(sec->raw_name); iounmap(sec->baseaddr); @@ -310,9 +317,6 @@ static int __init vpd_platform_init(void) if (!vpd_kobj) return -ENOMEM; - memset(&ro_vpd, 0, sizeof(ro_vpd)); - memset(&rw_vpd, 0, sizeof(rw_vpd)); - platform_driver_register(&vpd_driver); return 0; @@ -322,7 +326,7 @@ static void __exit vpd_platform_exit(void) { vpd_section_destroy(&ro_vpd); vpd_section_destroy(&rw_vpd); - kobject_del(vpd_kobj); + kobject_put(vpd_kobj); } module_init(vpd_platform_init); |