[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 5/9] qdev-clock: introduce an init array to ease
From: |
damien . hedde |
Subject: |
[Qemu-devel] [PATCH v6 5/9] qdev-clock: introduce an init array to ease the device construction |
Date: |
Wed, 4 Sep 2019 11:38:39 +0200 |
From: Damien Hedde <address@hidden>
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 <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
---
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 */
--
2.22.0
- [Qemu-devel] [PATCH v6 0/9] Clock framework API, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 9/9] hw/arm/xilinx_zynq: connect uart clocks to slcr, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 2/9] hw/core/clock-vmstate: define a vmstate entry for clock state, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 8/9] hw/char/cadence_uart: add clock support, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 3/9] qdev: add clock input&output support to devices., damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 7/9] hw/misc/zynq_slcr: add clock generation for uarts, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 4/9] qdev-monitor: print the device's clock with info qtree, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 5/9] qdev-clock: introduce an init array to ease the device construction,
damien . hedde <=
- [Qemu-devel] [PATCH v6 6/9] docs/clocks: add device's clock documentation, damien . hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 1/9] hw/core/clock: introduce clock objects, damien . hedde, 2019/09/04
- Re: [Qemu-devel] [PATCH v6 0/9] Clock framework API, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 0/9] Clock framework API, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 2/9] hw/core/clock-vmstate: define a vmstate entry for clock state, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 1/9] hw/core/clock: introduce clock objects, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 4/9] qdev-monitor: print the device's clock with info qtree, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 5/9] qdev-clock: introduce an init array to ease the device construction, Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 3/9] qdev: add clock input&output support to devices., Damien Hedde, 2019/09/04
- [Qemu-devel] [PATCH v6 9/9] hw/arm/xilinx_zynq: connect uart clocks to slcr, Damien Hedde, 2019/09/04