mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-30 08:07:59 +00:00

The EFI implementation of reset sits inside the driver and is called directly from outside the driver, breaking the normal driver-model conventions. Worse, it passed NULL as the device pointer, hoping that the called function won't use it, which breaks as soon as code is added to use it. Separate out the implementation to improve the situation enough to allow a future patch to add new sysreset features. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
75 lines
1.5 KiB
C
75 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
|
|
*
|
|
* Generic reset driver for x86 processor
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <sysreset.h>
|
|
#include <asm/io.h>
|
|
#include <asm/processor.h>
|
|
#include <efi_loader.h>
|
|
|
|
static int x86_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
|
{
|
|
int value;
|
|
|
|
switch (type) {
|
|
case SYSRESET_WARM:
|
|
value = SYS_RST | RST_CPU;
|
|
break;
|
|
case SYSRESET_COLD:
|
|
value = SYS_RST | RST_CPU | FULL_RST;
|
|
break;
|
|
default:
|
|
return -ENOSYS;
|
|
}
|
|
|
|
outb(value, IO_PORT_RESET);
|
|
|
|
return -EINPROGRESS;
|
|
}
|
|
|
|
#ifdef CONFIG_EFI_LOADER
|
|
void __efi_runtime EFIAPI efi_reset_system(
|
|
enum efi_reset_type reset_type,
|
|
efi_status_t reset_status,
|
|
unsigned long data_size, void *reset_data)
|
|
{
|
|
int value;
|
|
|
|
/*
|
|
* inline this code since we are not caused in the context of a
|
|
* udevice and passing NULL to x86_sysreset_request() is too horrible.
|
|
*/
|
|
if (reset_type == EFI_RESET_COLD ||
|
|
reset_type == EFI_RESET_PLATFORM_SPECIFIC)
|
|
value = SYS_RST | RST_CPU | FULL_RST;
|
|
else /* assume EFI_RESET_WARM since we cannot return an error */
|
|
value = SYS_RST | RST_CPU;
|
|
outb(value, IO_PORT_RESET);
|
|
|
|
/* TODO EFI_RESET_SHUTDOWN */
|
|
|
|
while (1) { }
|
|
}
|
|
#endif
|
|
|
|
|
|
static const struct udevice_id x86_sysreset_ids[] = {
|
|
{ .compatible = "x86,reset" },
|
|
{ }
|
|
};
|
|
|
|
static struct sysreset_ops x86_sysreset_ops = {
|
|
.request = x86_sysreset_request,
|
|
};
|
|
|
|
U_BOOT_DRIVER(x86_sysreset) = {
|
|
.name = "x86-sysreset",
|
|
.id = UCLASS_SYSRESET,
|
|
.of_match = x86_sysreset_ids,
|
|
.ops = &x86_sysreset_ops,
|
|
};
|