xref: /qemu/hw/gpio/gpio_pwr.c (revision 65cb7129f4160c7e07a0da107f888ec73ae96776)
1c9737765SMaxim Uvarov /*
2c9737765SMaxim Uvarov  * GPIO qemu power controller
3c9737765SMaxim Uvarov  *
4c9737765SMaxim Uvarov  * Copyright (c) 2020 Linaro Limited
5c9737765SMaxim Uvarov  *
6c9737765SMaxim Uvarov  * Author: Maxim Uvarov <maxim.uvarov@linaro.org>
7c9737765SMaxim Uvarov  *
8c9737765SMaxim Uvarov  * Virtual gpio driver which can be used on top of pl061
9c9737765SMaxim Uvarov  * to reboot and shutdown qemu virtual machine. One of use
10c9737765SMaxim Uvarov  * case is gpio driver for secure world application (ARM
11c9737765SMaxim Uvarov  * Trusted Firmware.).
12c9737765SMaxim Uvarov  *
13c9737765SMaxim Uvarov  * This work is licensed under the terms of the GNU GPL, version 2 or later.
14c9737765SMaxim Uvarov  * See the COPYING file in the top-level directory.
15c9737765SMaxim Uvarov  * SPDX-License-Identifier: GPL-2.0-or-later
16c9737765SMaxim Uvarov  */
17c9737765SMaxim Uvarov 
18c9737765SMaxim Uvarov /*
19c9737765SMaxim Uvarov  * QEMU interface:
20c9737765SMaxim Uvarov  * two named input GPIO lines:
21c9737765SMaxim Uvarov  *   'reset' : when asserted, trigger system reset
22c9737765SMaxim Uvarov  *   'shutdown' : when asserted, trigger system shutdown
23c9737765SMaxim Uvarov  */
24c9737765SMaxim Uvarov 
25c9737765SMaxim Uvarov #include "qemu/osdep.h"
26c9737765SMaxim Uvarov #include "hw/sysbus.h"
27*32cad1ffSPhilippe Mathieu-Daudé #include "system/runstate.h"
28c9737765SMaxim Uvarov 
29c9737765SMaxim Uvarov #define TYPE_GPIOPWR "gpio-pwr"
30c9737765SMaxim Uvarov OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
31c9737765SMaxim Uvarov 
32c9737765SMaxim Uvarov struct GPIO_PWR_State {
33c9737765SMaxim Uvarov     SysBusDevice parent_obj;
34c9737765SMaxim Uvarov };
35c9737765SMaxim Uvarov 
gpio_pwr_reset(void * opaque,int n,int level)36c9737765SMaxim Uvarov static void gpio_pwr_reset(void *opaque, int n, int level)
37c9737765SMaxim Uvarov {
38c9737765SMaxim Uvarov     if (level) {
39c9737765SMaxim Uvarov         qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
40c9737765SMaxim Uvarov     }
41c9737765SMaxim Uvarov }
42c9737765SMaxim Uvarov 
gpio_pwr_shutdown(void * opaque,int n,int level)43c9737765SMaxim Uvarov static void gpio_pwr_shutdown(void *opaque, int n, int level)
44c9737765SMaxim Uvarov {
45c9737765SMaxim Uvarov     if (level) {
46e3bcf57cSMaxim Uvarov         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
47c9737765SMaxim Uvarov     }
48c9737765SMaxim Uvarov }
49c9737765SMaxim Uvarov 
gpio_pwr_init(Object * obj)50c9737765SMaxim Uvarov static void gpio_pwr_init(Object *obj)
51c9737765SMaxim Uvarov {
52c9737765SMaxim Uvarov     DeviceState *dev = DEVICE(obj);
53c9737765SMaxim Uvarov 
54c9737765SMaxim Uvarov     qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
55c9737765SMaxim Uvarov     qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
56c9737765SMaxim Uvarov }
57c9737765SMaxim Uvarov 
58c9737765SMaxim Uvarov static const TypeInfo gpio_pwr_info = {
59c9737765SMaxim Uvarov     .name          = TYPE_GPIOPWR,
60c9737765SMaxim Uvarov     .parent        = TYPE_SYS_BUS_DEVICE,
61c9737765SMaxim Uvarov     .instance_size = sizeof(GPIO_PWR_State),
62c9737765SMaxim Uvarov     .instance_init = gpio_pwr_init,
63c9737765SMaxim Uvarov };
64c9737765SMaxim Uvarov 
gpio_pwr_register_types(void)65c9737765SMaxim Uvarov static void gpio_pwr_register_types(void)
66c9737765SMaxim Uvarov {
67c9737765SMaxim Uvarov     type_register_static(&gpio_pwr_info);
68c9737765SMaxim Uvarov }
69c9737765SMaxim Uvarov 
70c9737765SMaxim Uvarov type_init(gpio_pwr_register_types)
71