[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 12/31] qdev-clock: introduce an init array to ease the device cons
From: |
Peter Maydell |
Subject: |
[PULL 12/31] qdev-clock: introduce an init array to ease the device construction |
Date: |
Thu, 30 Apr 2020 12:51:23 +0100 |
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>
Reviewed-by: Alistair Francis <address@hidden>
Reviewed-by: Edgar E. Iglesias <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
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 b3b3a3e021c..a340f65ff90 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 62035aef830..a94cc444379 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.20.1
- [PULL 01/31] dma/xlnx-zdma: Fix descriptor loading (MEM) wrt endianness, (continued)
- [PULL 01/31] dma/xlnx-zdma: Fix descriptor loading (MEM) wrt endianness, Peter Maydell, 2020/04/30
- [PULL 03/31] nrf51: Fix last GPIO CNF address, Peter Maydell, 2020/04/30
- [PULL 02/31] dma/xlnx-zdma: Fix descriptor loading (REG) wrt endianness, Peter Maydell, 2020/04/30
- [PULL 05/31] Typo: Correct the name of CPU hotplug memory region, Peter Maydell, 2020/04/30
- [PULL 04/31] bugfix: Use gicr_typer in arm_gicv3_icc_reset, Peter Maydell, 2020/04/30
- [PULL 07/31] msf2: Add EMAC block to SmartFusion2 SoC, Peter Maydell, 2020/04/30
- [PULL 06/31] hw/net: Add Smartfusion2 emac block, Peter Maydell, 2020/04/30
- [PULL 08/31] tests/boot_linux_console: Add ethernet test to SmartFusion2, Peter Maydell, 2020/04/30
- [PULL 10/31] hw/core/clock-vmstate: define a vmstate entry for clock state, Peter Maydell, 2020/04/30
- [PULL 11/31] qdev: add clock input&output support to devices., Peter Maydell, 2020/04/30
- [PULL 12/31] qdev-clock: introduce an init array to ease the device construction,
Peter Maydell <=
- [PULL 09/31] hw/core/clock: introduce clock object, Peter Maydell, 2020/04/30
- [PULL 13/31] docs/clocks: add device's clock documentation, Peter Maydell, 2020/04/30
- [PULL 14/31] hw/misc/zynq_slcr: add clock generation for uarts, Peter Maydell, 2020/04/30
- [PULL 16/31] hw/arm/xilinx_zynq: connect uart clocks to slcr, Peter Maydell, 2020/04/30
- [PULL 15/31] hw/char/cadence_uart: add clock support, Peter Maydell, 2020/04/30
- [PULL 18/31] hw/arm: versal: Setup the ADMA with 128bit bus-width, Peter Maydell, 2020/04/30
- [PULL 19/31] Cadence: gem: fix wraparound in 64bit descriptors, Peter Maydell, 2020/04/30
- [PULL 20/31] net: cadence_gem: clear RX control descriptor, Peter Maydell, 2020/04/30
- [PULL 17/31] qdev-monitor: print the device's clock with info qtree, Peter Maydell, 2020/04/30