summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/efi/payload/image.c4
-rw-r--r--drivers/efi/efi-device.c28
-rw-r--r--include/efi/efi-device.h5
3 files changed, 37 insertions, 0 deletions
diff --git a/common/efi/payload/image.c b/common/efi/payload/image.c
index c1206cd6e2..e63da9ddf0 100644
--- a/common/efi/payload/image.c
+++ b/common/efi/payload/image.c
@@ -139,10 +139,14 @@ static int efi_execute_image(const char *file)
shutdown_barebox();
}
+ efi_pause_devices();
+
efiret = BS->start_image(handle, NULL, NULL);
if (EFI_ERROR(efiret))
pr_err("failed to StartImage: %s\n", efi_strerror(efiret));
+ efi_continue_devices();
+
if (!is_driver)
BS->unload_image(handle);
diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c
index 79cdd2ef27..955899b2d0 100644
--- a/drivers/efi/efi-device.c
+++ b/drivers/efi/efi-device.c
@@ -466,6 +466,34 @@ static int efi_init_devices(void)
}
core_initcall(efi_init_devices);
+void efi_pause_devices(void)
+{
+ struct device_d *dev;
+
+ bus_for_each_device(&efi_bus, dev) {
+ struct driver_d *drv = dev->driver;
+ struct efi_device *efidev = to_efi_device(dev);
+ struct efi_driver *efidrv = to_efi_driver(drv);
+
+ if (efidrv->dev_pause)
+ efidrv->dev_pause(efidev);
+ }
+}
+
+void efi_continue_devices(void)
+{
+ struct device_d *dev;
+
+ bus_for_each_device(&efi_bus, dev) {
+ struct driver_d *drv = dev->driver;
+ struct efi_device *efidev = to_efi_device(dev);
+ struct efi_driver *efidrv = to_efi_driver(drv);
+
+ if (efidrv->dev_continue)
+ efidrv->dev_continue(efidev);
+ }
+}
+
static void efi_devpath(efi_handle_t handle)
{
efi_status_t efiret;
diff --git a/include/efi/efi-device.h b/include/efi/efi-device.h
index cd8a374c32..b9714ffb74 100644
--- a/include/efi/efi-device.h
+++ b/include/efi/efi-device.h
@@ -16,6 +16,8 @@ struct efi_driver {
struct driver_d driver;
int (*probe)(struct efi_device *efidev);
void (*remove)(struct efi_device *efidev);
+ int (*dev_pause)(struct efi_device *efidev);
+ int (*dev_continue)(struct efi_device *efidev);
efi_guid_t guid;
};
@@ -46,6 +48,9 @@ int efi_connect_all(void);
void efi_register_devices(void);
struct efi_device *efi_get_bootsource(void);
+void efi_pause_devices(void);
+void efi_continue_devices(void);
+
static inline bool efi_device_has_guid(struct efi_device *efidev, efi_guid_t guid)
{
int i;