From patchwork Tue Oct 2 14:24:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Damien Hedde X-Patchwork-Id: 977902 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=greensocs.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=greensocs.com header.i=@greensocs.com header.b="S5C/yARp"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=greensocs.com header.i=@greensocs.com header.b="bSjz8aJP"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=greensocs.com header.i=@greensocs.com header.b="bSjz8aJP"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42PhjT6jNRz9s3l for ; Wed, 3 Oct 2018 00:43:41 +1000 (AEST) Received: from localhost ([::1]:44051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ltj-0002z7-GR for incoming@patchwork.ozlabs.org; Tue, 02 Oct 2018 10:43:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmw-0005Kf-7H for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004QL-LV for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:35 -0400 Received: from greensocs.com ([193.104.36.180]:53819) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ld9-0004L0-C3; Tue, 02 Oct 2018 10:26:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 0D1BCC7AC5; Tue, 2 Oct 2018 16:26:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490368; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=S5C/yARp6sbzYiPmKWH904uFdaULGLR3XPoDyrmfu4YRjY5U2FRxAscGqMMdXzoWq 88vEhbvk+V73dW9tGkMQOINnMIripGsSsbebnPLCASLLw1n0v7ux+1pYbjJ3Rjrhmu RXoLE9Wirv/DdCUSeCNf76muama9SSknpFZGPYO4= 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=bSjz8aJP; dkim=pass (1024-bit key) header.d=greensocs.com header.b=bSjz8aJP 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 nedi4oqLr3lv; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id A9BD0442AF8; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bSjz8aJPTPYj/m0e1Rf8yO1mS4CQDPRO2ABo1q7Qn1Y3Ca4YBqbvE+fE8uLU+d62b ZW1LAuYQt0D0PTpJ095jT8wgvuT154bzC4gSMdk2wYzMOGM+8EDMNL4YcKzibec1Cn R7sa4flfYJm9zDoWlPx+rrix4cS90izeD7Qy0SAU= Received: from kouign-amann.hive.antfield.fr (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 24E41442AE7; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bSjz8aJPTPYj/m0e1Rf8yO1mS4CQDPRO2ABo1q7Qn1Y3Ca4YBqbvE+fE8uLU+d62b ZW1LAuYQt0D0PTpJ095jT8wgvuT154bzC4gSMdk2wYzMOGM+8EDMNL4YcKzibec1Cn R7sa4flfYJm9zDoWlPx+rrix4cS90izeD7Qy0SAU= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:38 +0200 Message-Id: <20181002142443.30976-5-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> 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] [PATCH v5 4/9] qdev-clock: introduce an init array to ease the device construction 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, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Introduce a function and macro helpers to setup several clocks in a device from a static array description. An element of the array describes the clock (name and direction) as well as the related callback and an optional offset to store the created object pointer in the device state structure. The array must be terminated by a special element QDEV_CLOCK_END. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daudé --- include/hw/qdev-clock.h | 67 +++++++++++++++++++++++++++++++++++++++++ hw/core/qdev-clock.c | 26 ++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index d76aa9f479..fba907dee2 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -59,4 +59,71 @@ void qdev_connect_clock(DeviceState *dev, const char *name, DeviceState *driver, const char *driver_name, Error **errp); +/** + * ClockInitElem: + * @name: name of the clock (can't be NULL) + * @output: indicates whether the clock is input or output + * @callback: for inputs, optional callback to be called on clock's update + * with device as opaque + * @offset: optional offset to store the clock pointer in device'state + * structure (0 means unused) + */ +struct ClockPortInitElem { + const char *name; + bool output; + ClockCallback *callback; + size_t offset; +}; + +#define clock_offset_value(_type, _devstate, _field) \ + (offsetof(_devstate, _field) + \ + type_check(_type *, typeof_field(_devstate, _field))) + +#define QDEV_CLOCK(_output, _type, _devstate, _field, _callback) { \ + .name = (stringify(_field)), \ + .output = _output, \ + .callback = _callback, \ + .offset = clock_offset_value(_type, _devstate, _field), \ +} + +/** + * QDEV_CLOCK_(IN|OUT): + * @_devstate: structure type. @dev argument of qdev_init_clocks below must be + * a pointer to that same type. + * @_field: a field in @_devstate (must be ClockIn* or ClockOut*) + * @_callback: (for input only) callback (or NULL) to be called with the device + * state as argument + * + * The name of the clock will be derived from @_field + */ +#define QDEV_CLOCK_IN(_devstate, _field, _callback) \ + QDEV_CLOCK(false, ClockIn, _devstate, _field, _callback) + +#define QDEV_CLOCK_OUT(_devstate, _field) \ + QDEV_CLOCK(true, ClockOut, _devstate, _field, NULL) + +/** + * QDEV_CLOCK_IN_NOFIELD: + * @_name: name of the clock + * @_callback: callback (or NULL) to be called with the device state as argument + */ +#define QDEV_CLOCK_IN_NOFIELD(_name, _callback) { \ + .name = _name, \ + .output = false, \ + .callback = _callback, \ + .offset = 0, \ +} + +#define QDEV_CLOCK_END { .name = NULL } + +typedef struct ClockPortInitElem ClockPortInitArray[]; + +/** + * qdev_init_clocks: + * @dev: the device to add clocks + * @clocks: a QDEV_CLOCK_END-terminated array which contains the + * clocks information. + */ +void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks); + #endif /* QDEV_CLOCK_H */ diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index f0e4839aed..08afe3983d 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -138,3 +138,29 @@ void qdev_connect_clock(DeviceState *dev, const char *name, clock_connect(ncl->in , drv_ncl->out); } + +void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks) +{ + const struct ClockPortInitElem *elem; + + assert(dev); + assert(clocks); + + for (elem = &clocks[0]; elem->name != NULL; elem++) { + /* offset cannot be inside the DeviceState part */ + assert(elem->offset == 0 || elem->offset > sizeof(DeviceState)); + if (elem->output) { + ClockOut *clk; + clk = qdev_init_clock_out(dev, elem->name); + if (elem->offset) { + *(ClockOut **)(((void *) dev) + elem->offset) = clk; + } + } else { + ClockIn *clk; + clk = qdev_init_clock_in(dev, elem->name, elem->callback, dev); + if (elem->offset) { + *(ClockIn **)(((void *) dev) + elem->offset) = clk; + } + } + } +}