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