All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Hedde <damien.hedde@greensocs.com>
To: qemu-devel@nongnu.org
Cc: Damien Hedde <damien.hedde@greensocs.com>,
	peter.maydell@linaro.org,
	"Edgar E . Iglesias" <edgar.iglesias@xilinx.com>,
	berrange@redhat.com, ehabkost@redhat.com, pbonzini@redhat.com,
	alistair@alistair23.me, mark.burton@greensocs.com,
	qemu-arm@nongnu.org, Alistair Francis <alistair.francis@wdc.com>,
	marcandre.lureau@redhat.com, edgar.iglesias@gmail.com,
	philmd@redhat.com
Subject: [PATCH v9 4/9] qdev-clock: introduce an init array to ease the device construction
Date: Mon,  6 Apr 2020 15:52:46 +0200	[thread overview]
Message-ID: <20200406135251.157596-5-damien.hedde@greensocs.com> (raw)
In-Reply-To: <20200406135251.157596-1-damien.hedde@greensocs.com>

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 <damien.hedde@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
--

v7:
 + update ClockIn/Out types
 + remove the QDEV_CLOCK_IN_NOFIELD macro
 + remove leading underscores in macro arguments (Peter)
 + updated some comments (Peter)
 + removed trivial asserts (Peter)
---
 include/hw/qdev-clock.h | 55 +++++++++++++++++++++++++++++++++++++++++
 hw/core/qdev-clock.c    | 17 +++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
index b3b3a3e021..a340f65ff9 100644
--- a/include/hw/qdev-clock.h
+++ b/include/hw/qdev-clock.h
@@ -101,4 +101,59 @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name,
  */
 void qdev_finalize_clocklist(DeviceState *dev);
 
+/**
+ * ClockPortInitElem:
+ * @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 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(devstate, field) \
+    (offsetof(devstate, field) + \
+     type_check(Clock *, typeof_field(devstate, field)))
+
+#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \
+    .name = (stringify(field)), \
+    .is_output = out_not_in, \
+    .callback = cb, \
+    .offset = clock_offset_value(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 Clock*)
+ * @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, devstate, field, callback)
+
+#define QDEV_CLOCK_OUT(devstate, field) \
+    QDEV_CLOCK(true, devstate, field, NULL)
+
+#define QDEV_CLOCK_END { .name = NULL }
+
+typedef struct ClockPortInitElem ClockPortInitArray[];
+
+/**
+ * qdev_init_clocks:
+ * @dev: the device to add clocks to
+ * @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 62035aef83..a94cc44437 100644
--- a/hw/core/qdev-clock.c
+++ b/hw/core/qdev-clock.c
@@ -116,6 +116,23 @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
     return ncl->clock;
 }
 
+void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
+{
+    const struct ClockPortInitElem *elem;
+
+    for (elem = &clocks[0]; elem->name != NULL; elem++) {
+        Clock **clkp;
+        /* offset cannot be inside the DeviceState part */
+        assert(elem->offset > sizeof(DeviceState));
+        clkp = (Clock **)(((void *) dev) + elem->offset);
+        if (elem->is_output) {
+            *clkp = qdev_init_clock_out(dev, elem->name);
+        } else {
+            *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev);
+        }
+    }
+}
+
 static NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name)
 {
     NamedClockList *ncl;
-- 
2.26.0



  parent reply	other threads:[~2020-04-06 13:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-06 13:52 [PATCH v9 0/9] Clock framework API Damien Hedde
2020-04-06 13:52 ` [PATCH v9 1/9] hw/core/clock: introduce clock object Damien Hedde
2020-04-17 14:39   ` Peter Maydell
2020-04-06 13:52 ` [PATCH v9 2/9] hw/core/clock-vmstate: define a vmstate entry for clock state Damien Hedde
2020-04-06 13:52 ` [PATCH v9 3/9] qdev: add clock input&output support to devices Damien Hedde
2020-04-06 13:52 ` Damien Hedde [this message]
2020-04-06 13:52 ` [PATCH v9 5/9] docs/clocks: add device's clock documentation Damien Hedde
2020-04-07  5:07   ` Markus Armbruster
2020-04-08 10:06     ` Damien Hedde
2020-04-14  7:15       ` Markus Armbruster
2020-04-17 15:52   ` Peter Maydell
2020-04-17 16:52     ` Damien Hedde
2020-04-06 13:52 ` [PATCH v9 6/9] hw/misc/zynq_slcr: add clock generation for uarts Damien Hedde
2020-04-06 13:52 ` [PATCH v9 7/9] hw/char/cadence_uart: add clock support Damien Hedde
2020-04-06 13:52 ` [PATCH v9 8/9] hw/arm/xilinx_zynq: connect uart clocks to slcr Damien Hedde
2020-04-06 13:52 ` [PATCH v9 9/9] qdev-monitor: print the device's clock with info qtree Damien Hedde
2020-04-17 17:45 ` [PATCH v9 0/9] Clock framework API Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200406135251.157596-5-damien.hedde@greensocs.com \
    --to=damien.hedde@greensocs.com \
    --cc=alistair.francis@wdc.com \
    --cc=alistair@alistair23.me \
    --cc=berrange@redhat.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=edgar.iglesias@xilinx.com \
    --cc=ehabkost@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mark.burton@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.