summaryrefslogtreecommitdiff
path: root/drivers/firmware/google
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-02-04 00:16:40 +0400
committerMatt Fleming <matt.fleming@intel.com>2013-04-17 16:23:59 +0400
commite14ab23dde12b80db4c94b684a2e485b72b16af3 (patch)
treeb9c7e3ec35e67d90fc05908ed3387e4018e2c7ba /drivers/firmware/google
parent4423d779af2a8f1fbd01aeca5c56522efce7262f (diff)
downloadlinux-e14ab23dde12b80db4c94b684a2e485b72b16af3.tar.xz
efivars: efivar_entry API
There isn't really a formal interface for dealing with EFI variables or struct efivar_entry. Historically, this has led to various bits of code directly accessing the generic EFI variable ops, which inherently ties it to specific EFI variable operations instead of indirectly using whatever ops were registered with register_efivars(). This lead to the efivarfs code only working with the generic EFI variable ops and not CONFIG_GOOGLE_SMI. Encapsulate everything that needs to access '__efivars' inside an efivar_entry_* API and use the new API in the pstore, sysfs and efivarfs code. Much of the efivars code had to be rewritten to use this new API. For instance, it is now up to the users of the API to build the initial list of EFI variables in their efivar_init() callback function. The variable list needs to be passed to efivar_init() which allows us to keep work arounds for things like implementation bugs in GetNextVariable() in a central location. Allowing users of the API to use a callback function to build the list greatly benefits the efivarfs code which needs to allocate inodes and dentries for every variable. It previously did this in a racy way because the code ran without holding the variable spinlock. Both the sysfs and efivarfs code maintain their own lists which means the two interfaces can be running simultaneously without interference, though it should be noted that because no synchronisation is performed it is very easy to create inconsistencies. efibootmgr doesn't currently use efivarfs and users are likely to also require the old sysfs interface, so it makes sense to allow both to be built. Reviewed-by: Tom Gundersen <teg@jklm.no> Tested-by: Tom Gundersen <teg@jklm.no> Cc: Seiji Aguchi <seiji.aguchi@hds.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Jeremy Kerr <jk@ozlabs.org> Cc: Tony Luck <tony.luck@intel.com> Cc: Mike Waychison <mikew@google.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware/google')
-rw-r--r--drivers/firmware/google/gsmi.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
index c409a7577afc..757b2d92d5b0 100644
--- a/drivers/firmware/google/gsmi.c
+++ b/drivers/firmware/google/gsmi.c
@@ -882,12 +882,19 @@ static __init int gsmi_init(void)
goto out_remove_bin_file;
}
- ret = register_efivars(&efivars, &efivar_ops, gsmi_kobj);
+ ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj);
if (ret) {
printk(KERN_INFO "gsmi: Failed to register efivars\n");
goto out_remove_sysfs_files;
}
+ ret = efivars_sysfs_init();
+ if (ret) {
+ printk(KERN_INFO "gsmi: Failed to create efivars files\n");
+ efivars_unregister(&efivars);
+ goto out_remove_sysfs_files;
+ }
+
register_reboot_notifier(&gsmi_reboot_notifier);
register_die_notifier(&gsmi_die_notifier);
atomic_notifier_chain_register(&panic_notifier_list,
@@ -919,7 +926,7 @@ static void __exit gsmi_exit(void)
unregister_die_notifier(&gsmi_die_notifier);
atomic_notifier_chain_unregister(&panic_notifier_list,
&gsmi_panic_notifier);
- unregister_efivars(&efivars);
+ efivars_unregister(&efivars);
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);