From patchwork Mon Mar 25 11:01:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Damien Hedde X-Patchwork-Id: 10868801 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5682D13B5 for ; Mon, 25 Mar 2019 11:05:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42191290BA for ; Mon, 25 Mar 2019 11:05:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 35D83290DF; Mon, 25 Mar 2019 11:05:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4FFEE290BA for ; Mon, 25 Mar 2019 11:05:18 +0000 (UTC) Received: from localhost ([127.0.0.1]:40528 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h8NPp-0007Wp-6y for patchwork-qemu-devel@patchwork.kernel.org; Mon, 25 Mar 2019 07:05:17 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h8NNF-0005BD-QB for qemu-devel@nongnu.org; Mon, 25 Mar 2019 07:02:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h8NND-0007ti-Pd for qemu-devel@nongnu.org; Mon, 25 Mar 2019 07:02:37 -0400 Received: from greensocs.com ([193.104.36.180]:38352) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h8NN8-0007oK-Nj; Mon, 25 Mar 2019 07:02:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id DF99E7D78B7; Mon, 25 Mar 2019 12:02:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1553511746; bh=clq3gvkosMEvBafp8I7Dl74ggYCNhXMTvzQ/+rm5LXM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=qPhPEFIi5efDn5FvBKbaEvu6DIdW8wOxPOJgZS/xiUZs7qgkl+avMHJ+IuCm6gw1Z W8sdfBWy1G6imzBQEBoh8ZWFl29Ofpl25qmQ9nXZM5jDHyNFIuZaUSifVFSknrdLm4 q4yv9WjAp48N2qwaMJ58yQEZxEn0LsuQyxedsbYE= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=UUfytm+M; dkim=pass (1024-bit key) header.d=greensocs.com header.b=UUfytm+M Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zapesw92xvvE; Mon, 25 Mar 2019 12:02:26 +0100 (CET) Received: by greensocs.com (Postfix, from userid 998) id 9D18A7D78A2; Mon, 25 Mar 2019 12:02:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1553511743; bh=clq3gvkosMEvBafp8I7Dl74ggYCNhXMTvzQ/+rm5LXM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UUfytm+MquilzR9zQJ7NG1FEinwlC8TA2ikP0pkoXNILexKX/N+6yt1mEwV46sHrr Thh+DeaRSvDh9SY4g2PXHIWrouFC1HrkCL4cR5ispjqfdILBzFso6w0Q6bIbpVFR+B QfWTM8rdROdDTm/pLkJ/iS5ss1j3ZywxxzLRSVmQ= Received: from kouign-amann.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id E182A7D7887; Mon, 25 Mar 2019 12:02:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1553511743; bh=clq3gvkosMEvBafp8I7Dl74ggYCNhXMTvzQ/+rm5LXM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UUfytm+MquilzR9zQJ7NG1FEinwlC8TA2ikP0pkoXNILexKX/N+6yt1mEwV46sHrr Thh+DeaRSvDh9SY4g2PXHIWrouFC1HrkCL4cR5ispjqfdILBzFso6w0Q6bIbpVFR+B QfWTM8rdROdDTm/pLkJ/iS5ss1j3ZywxxzLRSVmQ= From: Damien Hedde To: qemu-devel@nongnu.org Date: Mon, 25 Mar 2019 12:01:49 +0100 Message-Id: <5a0f7fc13cd69586dba5475edf5a6bec46559858.1553510737.git.damien.hedde@greensocs.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [RFC PATCH 06/17] Add function to control reset with gpio inputs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, mark.burton@greensocs.com, Damien Hedde , qemu-arm@nongnu.org, alistair.francis@wdc.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, philmd@redhat.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP It adds the possibility to add 2 gpios to control the warm and cold reset. With theses ios, the reset can be maintained during some time. Each io is associated with a state to detect level changes. The cold reset io function is named power_gate as it is really the meaning of this io. Signed-off-by: Damien Hedde --- hw/core/qdev-vmstate.c | 2 ++ hw/core/qdev.c | 57 ++++++++++++++++++++++++++++++++++++++++++ include/hw/qdev-core.h | 44 ++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/hw/core/qdev-vmstate.c b/hw/core/qdev-vmstate.c index a9834f1a1c..dec6a72f75 100644 --- a/hw/core/qdev-vmstate.c +++ b/hw/core/qdev-vmstate.c @@ -20,6 +20,8 @@ const struct VMStateDescription device_vmstate_reset = { .minimum_version_id = 0, .fields = (VMStateField[]) { VMSTATE_UINT32(resetting, DeviceState), + VMSTATE_BOOL(cold_reset_input.state, DeviceState), + VMSTATE_BOOL(warm_reset_input.state, DeviceState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 884a49efa4..8dae26d957 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -464,6 +464,61 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) qdev_init_gpio_in_named(dev, handler, NULL, n); } +static void device_reset_handler(DeviceState *dev, bool cold, bool level) +{ + DeviceResetInputState *dris; + + dris = cold ? &dev->cold_reset_input : &dev->warm_reset_input; + + if (level == dris->state) { + /* io state has not changed */ + return; + } + + dris->state = level; + switch (dris->type) { + case DEVICE_ACTIVE_LOW: + level = !level; + case DEVICE_ACTIVE_HIGH: + if (level) { + resettable_assert_reset(OBJECT(dev), cold); + } else { + resettable_deassert_reset(OBJECT(dev)); + } + break; + } +} + +static void device_cold_reset_handler(void *opaque, int n, int level) +{ + device_reset_handler((DeviceState *) opaque, true, level); +} + +static void device_warm_reset_handler(void *opaque, int n, int level) +{ + device_reset_handler((DeviceState *) opaque, false, level); +} + +void qdev_init_reset_gpio_in_named(DeviceState *dev, const char *name, + bool cold, DeviceActiveType type) +{ + qemu_irq_handler handler; + + if (cold) { + assert(!dev->cold_reset_input.exists); + dev->cold_reset_input.exists = true; + dev->cold_reset_input.type = type; + handler = device_cold_reset_handler; + } else { + assert(!dev->warm_reset_input.exists); + dev->warm_reset_input.exists = true; + dev->warm_reset_input.type = type; + handler = device_warm_reset_handler; + } + + qdev_init_gpio_in_named(dev, handler, name, 1); +} + void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n) { @@ -1021,6 +1076,8 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->realized = false; dev->resetting = 0; + dev->cold_reset_input.exists = false; + dev->warm_reset_input.exists = false; object_property_add_bool(obj, "realized", device_get_realized, device_set_realized, NULL); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index baad2e7066..db997cc47d 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -130,6 +130,17 @@ struct NamedGPIOList { QLIST_ENTRY(NamedGPIOList) node; }; +typedef enum DeviceActiveType { + DEVICE_ACTIVE_LOW, + DEVICE_ACTIVE_HIGH, +} DeviceActiveType; + +typedef struct DeviceResetInputState { + bool exists; + DeviceActiveType type; + bool state; +} DeviceResetInputState; + /** * DeviceState: * @realized: Indicates whether the device has been fully constructed. @@ -157,6 +168,8 @@ struct DeviceState { int instance_id_alias; int alias_required_for_version; uint32_t resetting; + DeviceResetInputState cold_reset_input; + DeviceResetInputState warm_reset_input; }; struct DeviceListener { @@ -361,6 +374,37 @@ static inline void qdev_init_gpio_in_named(DeviceState *dev, void qdev_pass_gpios(DeviceState *dev, DeviceState *container, const char *name); +/** + * qdev_init_reset_gpio_in_named: + * Create a gpio controlling the warm or cold reset of the device. + * @cold specify whether it triggers cold or warm reset + * @type what kind of reset io it is + */ +void qdev_init_reset_gpio_in_named(DeviceState *dev, const char *name, + bool cold, DeviceActiveType type); + +/** + * qdev_init_warm_reset_gpio: + * Create a reset input to control the device warm reset. + */ +static inline void qdev_init_warm_reset_gpio(DeviceState *dev, + const char *name, + DeviceActiveType type) +{ + qdev_init_reset_gpio_in_named(dev, name, false, type); +} + +/** + * qdev_init_power_gate_gpio: + * Create a power gate input to control the device cold reset. + */ +static inline void qdev_init_power_gate_gpio(DeviceState *dev, + const char *name, + DeviceActiveType type) +{ + qdev_init_reset_gpio_in_named(dev, name, true, type); +} + BusState *qdev_get_parent_bus(DeviceState *dev); /*** BUS API. ***/