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 <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Kay Sievers <[email protected]>
Cc: Jeremy Kerr <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Chun-Yi Lee <[email protected]>
Cc: Andy Whitcroft <[email protected]>
---

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 <[email protected]>
+ *
+ * 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to