@@ -50,6 +50,29 @@ struct ClkList {
QLIST_ENTRY(ClkList) node;
};
+typedef struct ClockInitElement {
+ const char *name; /* Name to give to the clock. */
+ size_t offset; /* Offset of the qemu_clk field in the object. */
+ qemu_clk_on_rate_update_cb cb;
+} ClockInitElement;
+
+#define DEVICE_CLOCK(_state, _field, _cb) { \
+ .name = #_field, \
+ .offset = offsetof(_state, _field), \
+ .cb = _cb \
+}
+
+#define DEVICE_CLOCK_END() { \
+ .name = NULL \
+}
+
+/**
+ * qemu_clk_init_device:
+ * @obj: the Object which need to be initialized.
+ * @array: the array of ClockInitElement to be used.
+ */
+void qemu_clk_init_device(Object *obj, ClockInitElement *array);
+
/**
* qemu_clk_attach_to_device:
* @dev: the device on which the clock need to be attached.
@@ -26,6 +26,7 @@
#include "hw/hw.h"
#include "qemu/log.h"
#include "qapi/error.h"
+#include "hw/qdev-core.h"
#ifndef DEBUG_QEMU_CLOCK
#define DEBUG_QEMU_CLOCK 0
@@ -37,6 +38,22 @@
} \
} while (0);
+void qemu_clk_init_device(Object *obj, ClockInitElement *array)
+{
+ qemu_clk *cur = NULL;
+
+ while (array->name != NULL) {
+ DPRINTF("init clock named %s\n", array->name);
+ cur = (((void *)obj) + array->offset);
+ *cur = QEMU_CLOCK(object_new(TYPE_CLOCK));
+ qemu_clk_attach_to_device(DEVICE(obj), *cur, array->name);
+ if (array->cb) {
+ qemu_clk_set_callback(*cur, array->cb, obj);
+ }
+ array++;
+ }
+}
+
void qemu_clk_refresh(qemu_clk clk)
{
qemu_clk_update_rate(clk, clk->in_rate);