From patchwork Wed Sep 4 12:55:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Damien Hedde X-Patchwork-Id: 11130231 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D3CC013B1 for ; Wed, 4 Sep 2019 13:18:49 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8E4212168B for ; Wed, 4 Sep 2019 13:18:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=greensocs.com header.i=@greensocs.com header.b="vJoaRRoD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8E4212168B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=greensocs.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:57734 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i5VBO-00010q-VF for patchwork-qemu-devel@patchwork.kernel.org; Wed, 04 Sep 2019 09:18:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53679) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i5Upd-0006Xq-WC for qemu-devel@nongnu.org; Wed, 04 Sep 2019 08:56:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i5Upc-0005bK-Cc for qemu-devel@nongnu.org; Wed, 04 Sep 2019 08:56:17 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:45960) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i5UpY-0005Xu-UU; Wed, 04 Sep 2019 08:56:13 -0400 Received: from crumble.bar.greensocs.com (crumble.bar.greensocs.com [172.16.11.102]) by beetle.greensocs.com (Postfix) with ESMTPS id 821B796F6A; Wed, 4 Sep 2019 12:56:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1567601772; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gdlTh3yyxOVxrasubJkegjXhqH/FOw0TXWBho063ltM=; b=vJoaRRoDYYVe144qOD97w4IdS4osxlKnocOOrdJB4UdUAouUXbwqrUsUBNdI44Gx9IIE9A IhsUTkN3MzUmpfSGRg0E5dNNnPuEhQc3ELkxk0FBJ4TMGmi6QMrVkbqpIcXqfvNDZojuRq 7430xJihcj8+EnSGpRDh1ovhwZ8HMp0= From: Damien Hedde To: qemu-devel@nongnu.org Date: Wed, 4 Sep 2019 14:55:27 +0200 Message-Id: <20190904125531.27545-6-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190904125531.27545-1-damien.hedde@greensocs.com> References: <20190904125531.27545-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1567601772; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gdlTh3yyxOVxrasubJkegjXhqH/FOw0TXWBho063ltM=; b=VZJJy4yaIh2A8LgJAd6huc7lrize3zQK99mcq78v2X7QGGE2x/VApmz3cR9HErMerx8rwW T6XHBn4Wj4SZh/OZKqGsQtH/eoBS0A1BvbX9sXaSc05IqbsNWUfQA6kL8JNSd57+h13cLX sljYKzfdtTfONwjkDSateqqeRvCqYTE= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1567601772; a=rsa-sha256; cv=none; b=nhS4/aSgHYx3589Dq0LCSflM3b6sQ6n94EeWiis8y7wGQn/pxtZ2S8hER/YH9amjG0Ittz XSYiEnNEJPSUo1WD70VCbJ37NHtG8yXCH6m8xvKgjxf9b+m2+zyimkqei+N+Z3jEcRacIV SueBAELtxFVwqysbdlKBPXFiKWYcqnI= ARC-Authentication-Results: i=1; beetle.greensocs.com; none X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [PATCH v6 5/9] qdev-clock: introduce an init array to ease the device construction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Damien Hedde , peter.maydell@linaro.org, berrange@redhat.com, ehabkost@redhat.com, alistair@alistair23.me, mark.burton@greensocs.com, pbonzini@redhat.com, qemu-arm@nongnu.org, marcandre.lureau@redhat.com, edgar.iglesias@gmail.com, philmd@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.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é --- hw/core/qdev-clock.c | 26 ++++++++++++++++ include/hw/qdev-clock.h | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index bebdd8fa15..32ad45c061 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -153,3 +153,29 @@ void qdev_connect_clock_out(DeviceState *dev, const char *name, ClockIn *clk, clock_connect(clk, clkout); } + +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->is_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; + } + } + } +} diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index c4ea912fdc..b6edb9421b 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -64,4 +64,71 @@ void qdev_connect_clock_out(DeviceState *dev, const char *name, ClockIn *clk, void qdev_pass_clock(DeviceState *dev, const char *name, DeviceState *container, const char *cont_name); +/** + * ClockInitElem: + * @name: name of the clock (can't be NULL) + * @is_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 ClockIn or ClockOut pointer in device + * state structure (0 means unused) + */ +struct ClockPortInitElem { + const char *name; + bool is_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(_is_output, _type, _devstate, _field, _callback) { \ + .name = (stringify(_field)), \ + .is_output = _is_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, \ + .is_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 */