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