diff options
Diffstat (limited to 'drivers/power/reset/htif-poweroff.c')
-rw-r--r-- | drivers/power/reset/htif-poweroff.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/power/reset/htif-poweroff.c b/drivers/power/reset/htif-poweroff.c new file mode 100644 index 0000000000..e24397f934 --- /dev/null +++ b/drivers/power/reset/htif-poweroff.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix + */ + +#include <common.h> +#include <driver.h> +#include <poweroff.h> +#include <asm/htif.h> + +static void __iomem *htif = IOMEM(HTIF_DEFAULT_BASE_ADDR); + +static void __noreturn riscvemu_poweroff(struct poweroff_handler *pwr) +{ + shutdown_barebox(); + + __htif_tohost(htif, HTIF_DEV_SYSCALL, 0, 1); + + __builtin_unreachable(); +} + +static int htif_poweroff_probe(struct device *dev) +{ + struct resource *iores; + + iores = dev_request_mem_resource(dev, 0); + if (!IS_ERR(iores)) + htif = IOMEM(iores->start); + else if (PTR_ERR(iores) != -ENOENT) + return PTR_ERR(iores); + + return poweroff_handler_register_fn(riscvemu_poweroff); +} + + +static const struct of_device_id htif_poweroff_of_match[] = { + { .compatible = "ucb,htif0" }, + {} +}; +MODULE_DEVICE_TABLE(of, htif_poweroff_of_match); + +static struct driver htif_poweroff_driver = { + .name = "htif-poweroff", + .of_compatible = htif_poweroff_of_match, + .probe = htif_poweroff_probe, +}; +coredevice_platform_driver(htif_poweroff_driver); |