static int __init efisubsys_init()

in efi/efi.c [359:437]


static int __init efisubsys_init(void)
{
	int error;

	if (!efi_enabled(EFI_RUNTIME_SERVICES))
		efi.runtime_supported_mask = 0;

	if (!efi_enabled(EFI_BOOT))
		return 0;

	if (efi.runtime_supported_mask) {
		/*
		 * Since we process only one efi_runtime_service() at a time, an
		 * ordered workqueue (which creates only one execution context)
		 * should suffice for all our needs.
		 */
		efi_rts_wq = alloc_ordered_workqueue("efi_rts_wq", 0);
		if (!efi_rts_wq) {
			pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n");
			clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
			efi.runtime_supported_mask = 0;
			return 0;
		}
	}

	if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES))
		platform_device_register_simple("rtc-efi", 0, NULL, 0);

	/* We register the efi directory at /sys/firmware/efi */
	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
	if (!efi_kobj) {
		pr_err("efi: Firmware registration failed.\n");
		destroy_workqueue(efi_rts_wq);
		return -ENOMEM;
	}

	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
				      EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
		error = generic_ops_register();
		if (error)
			goto err_put;
		efivar_ssdt_load();
		platform_device_register_simple("efivars", 0, NULL, 0);
	}

	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
	if (error) {
		pr_err("efi: Sysfs attribute export failed with error %d.\n",
		       error);
		goto err_unregister;
	}

	error = efi_runtime_map_init(efi_kobj);
	if (error)
		goto err_remove_group;

	/* and the standard mountpoint for efivarfs */
	error = sysfs_create_mount_point(efi_kobj, "efivars");
	if (error) {
		pr_err("efivars: Subsystem registration failed.\n");
		goto err_remove_group;
	}

	if (efi_enabled(EFI_DBG) && efi_enabled(EFI_PRESERVE_BS_REGIONS))
		efi_debugfs_init();

	return 0;

err_remove_group:
	sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
err_unregister:
	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
				      EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
		generic_ops_unregister();
err_put:
	kobject_put(efi_kobj);
	destroy_workqueue(efi_rts_wq);
	return error;
}