This registers /sys/firmware/efi{,/efivars} whenever EFI is enabled and the system supports it. This allows *) userspace to check for the existence of /sys/firmware/efi as a way to determine whether or it is running on an EFI system. *) 'mount -t efivarfs none /sys/firmware/efi/efivars' without manually loading any modules. For what it is worth, this makes efivars 'just work' under systemd, even when compiled as a module. v2: only create /sys/firmware/efi/efivars if the module is being compiled, and move extern's to efi.h Signed-off-by: Tom Gundersen <teg@xxxxxxx> Cc: Matt Fleming <matt.fleming@xxxxxxxxx> Cc: Kay Sievers <kay@xxxxxxxx> Cc: Jeremy Kerr <jeremy.kerr@xxxxxxxxxxxxx> Cc: Matthew Garrett <mjg59@xxxxxxxxxxxxx> Cc: Chun-Yi Lee <jlee@xxxxxxxx> Cc: Andy Whitcroft <apw@xxxxxxxxxxxxx> --- Hi guys, Please disregard the previous patch, sorry for the noise. Cheers, Tom drivers/firmware/Makefile | 1 + drivers/firmware/efisubsys.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ drivers/firmware/efivars.c | 30 ++++-------------------- include/linux/efi.h | 4 ++++ 4 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 drivers/firmware/efisubsys.c diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 5a7e273..e89c5da 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DMI) += dmi_scan.o obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o obj-$(CONFIG_EDD) += edd.o +obj-$(CONFIG_EFI) += efisubsys.o obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_PCDP) += pcdp.o obj-$(CONFIG_DELL_RBU) += dell_rbu.o diff --git a/drivers/firmware/efisubsys.c b/drivers/firmware/efisubsys.c new file mode 100644 index 0000000..29233f0 --- /dev/null +++ b/drivers/firmware/efisubsys.c @@ -0,0 +1,54 @@ +/* + * efi.c - EFI subsystem + * + * Copyright (C) 2013 Tom Gundersen <teg@xxxxxxx> + * + * This code registers /sys/firmware/efi{,/efivars} when EFI is supported, + * allowing the efivarfs to be mounted or the efivars module to be loaded. + * The existance of /sys/firmware/efi may also be used by userspace to + * determine that the system supports EFI. + * + * This file is released under the GPLv2. + */ + +#include <linux/kobject.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/efi.h> + +struct kobject *efi_kobj; +EXPORT_SYMBOL_GPL(efi_kobj); +struct kobject *efivars_kobj; +EXPORT_SYMBOL_GPL(efivars_kobj); + +/* + * We register the efi subsystem with the firmware subsystem and the + * efivars subsystem with the efi subsystem. + */ +static int __init efisubsys_init(void) +{ + if (!efi_enabled) + return 0; + + /* We register the efi directory at /sys/firmware/efi */ + efi_kobj = kobject_create_and_add("efi", firmware_kobj); + if (!efi_kobj) { + pr_err("efivars: Firmware registration failed.\n"); + return -ENOMEM; + } + +#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) + /* and the mountpoint for efivarfs at /sys/firmware/efi/efivars */ + efivars_kobj = kobject_create_and_add("efivars", efi_kobj); + if (!efivars_kobj) { + pr_err("efivars: Subsystem registration failed.\n"); + kobject_put(efi_kobj); + return -ENOMEM; + } +#endif /* CONFIG_EFI_VARS */ + + return 0; +} + +subsys_initcall(efisubsys_init); diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index b7cff5c..b47db7b 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -1528,8 +1528,6 @@ static struct attribute_group efi_subsys_attr_group = { .attrs = efi_subsys_attrs, }; -static struct kobject *efi_kobj; - /* * efivar_create_sysfs_entry() * Requires: @@ -1708,13 +1706,7 @@ int register_efivars(struct efivars *efivars, goto out; } - efivars->kobject = kobject_create_and_add("efivars", parent_kobj); - if (!efivars->kobject) { - pr_err("efivars: Subsystem registration failed.\n"); - error = -ENOMEM; - kset_unregister(efivars->kset); - goto out; - } + efivars->kobject = efivars_kobj; /* * Per EFI spec, the maximum storage allocated for both @@ -1768,11 +1760,7 @@ out: EXPORT_SYMBOL_GPL(register_efivars); /* - * For now we register the efi subsystem with the firmware subsystem - * and the vars subsystem with the efi subsystem. In the future, it - * might make sense to split off the efi subsystem into its own - * driver, but for now only efivars will register with it, so just - * include it here. + * We register the vars subsystem with the efi subsystem. */ static int __init @@ -1786,21 +1774,15 @@ efivars_init(void) if (!efi_enabled) return 0; - /* For now we'll register the efi directory at /sys/firmware/efi */ - efi_kobj = kobject_create_and_add("efi", firmware_kobj); - if (!efi_kobj) { - printk(KERN_ERR "efivars: Firmware registration failed.\n"); - return -ENOMEM; - } - ops.get_variable = efi.get_variable; ops.set_variable = efi.set_variable; ops.get_next_variable = efi.get_next_variable; ops.query_variable_info = efi.query_variable_info; error = register_efivars(&__efivars, &ops, efi_kobj); + if (error) - goto err_put; + goto err_unregister; /* Don't forget the systab entry */ error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); @@ -1815,8 +1797,6 @@ efivars_init(void) err_unregister: unregister_efivars(&__efivars); -err_put: - kobject_put(efi_kobj); return error; } @@ -1825,10 +1805,8 @@ efivars_exit(void) { if (efi_enabled) { unregister_efivars(&__efivars); - kobject_put(efi_kobj); } } module_init(efivars_init); module_exit(efivars_exit); - diff --git a/include/linux/efi.h b/include/linux/efi.h index 8b84916..c9e3a26 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -707,6 +707,8 @@ static inline void memrange_efi_to_native(u64 *addr, u64 *npages) *addr &= PAGE_MASK; } +extern struct kobject *efi_kobj; + #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) /* * EFI Variable support. @@ -746,6 +748,8 @@ int register_efivars(struct efivars *efivars, struct kobject *parent_kobj); void unregister_efivars(struct efivars *efivars); +extern struct kobject *efivars_kobj; + #endif /* CONFIG_EFI_VARS */ #endif /* _LINUX_EFI_H */ -- 1.8.1.1 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html