Add thunderbolt-root-port and its secondary thunderbolt-bus type. This is
the core Thunderbolt PCIe modelling piece. Devices behind the root port
remain normal QEMU PCI devices, while the root port controls
guest-visible link presence and hotplug signalling.

The connected QOM property allows the whole Thunderbolt port to be
disconnected or reconnected without changing endpoint device
implementations.

Signed-off-by: Dmitry R <[email protected]>
---
 hw/pci-bridge/meson.build             |   1 +
 hw/pci-bridge/thunderbolt_root_port.c | 565 ++++++++++++++++++++++++++
 2 files changed, 566 insertions(+)
 create mode 100644 hw/pci-bridge/thunderbolt_root_port.c

diff --git a/hw/pci-bridge/meson.build b/hw/pci-bridge/meson.build
index 2e0eb0d233..fd0698fb33 100644
--- a/hw/pci-bridge/meson.build
+++ b/hw/pci-bridge/meson.build
@@ -3,6 +3,7 @@ pci_ss.add(when: 'CONFIG_PCI_BRIDGE', if_true: 
files('pci_bridge_dev.c'))
 pci_ss.add(when: 'CONFIG_I82801B11', if_true: files('i82801b11.c'))
 pci_ss.add(when: 'CONFIG_IOH3420', if_true: files('ioh3420.c'))
 pci_ss.add(when: 'CONFIG_PCIE_PORT', if_true: files('pcie_root_port.c', 
'gen_pcie_root_port.c'))
+pci_ss.add(when: 'CONFIG_PCIE_PORT', if_true: files('thunderbolt_root_port.c'))
 pci_ss.add(when: 'CONFIG_PCIE_PCI_BRIDGE', if_true: files('pcie_pci_bridge.c'))
 pci_ss.add(when: 'CONFIG_PXB', if_true: files('pci_expander_bridge.c'),
                                if_false: files('pci_expander_bridge_stubs.c'))
diff --git a/hw/pci-bridge/thunderbolt_root_port.c 
b/hw/pci-bridge/thunderbolt_root_port.c
new file mode 100644
index 0000000000..625a5dba7e
--- /dev/null
+++ b/hw/pci-bridge/thunderbolt_root_port.c
@@ -0,0 +1,565 @@
+/*
+ * Thunderbolt PCI Express Root Port
+ *
+ * This root port creates a Thunderbolt-flavoured PCIe bus. Devices on that
+ * bus remain regular QEMU PCI devices; the Thunderbolt layer controls their
+ * guest-visible connection state.
+ *
+ * Copyright (C) 2026
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
+#include "hw/acpi/acpi_aml_interface.h"
+#include "hw/core/hotplug.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev-properties-system.h"
+#include "hw/pci/msix.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pcie_port.h"
+#include "migration/vmstate.h"
+#include "system/system.h"
+#include "qom/object.h"
+
+#define TYPE_THUNDERBOLT_ROOT_PORT "thunderbolt-root-port"
+#define TYPE_THUNDERBOLT_BUS "thunderbolt-bus"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ThunderboltRootPort, THUNDERBOLT_ROOT_PORT)
+
+#define THUNDERBOLT_ROOT_PORT_AER_OFFSET 0x100
+#define THUNDERBOLT_ROOT_PORT_ACS_OFFSET \
+    (THUNDERBOLT_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF)
+#define THUNDERBOLT_ROOT_PORT_MSIX_NR_VECTOR 1
+#define THUNDERBOLT_ROOT_DEFAULT_IO_RANGE 4096
+
+struct ThunderboltRootPort {
+    PCIESlot parent_obj;
+
+    bool migrate_msix;
+    PCIResReserve res_reserve;
+    bool connected;
+    DeviceListener listener;
+    Notifier machine_done;
+};
+
+static void thunderbolt_root_port_set_presence(PCIDevice *dev, bool present,
+                                               bool notify);
+static void thunderbolt_root_port_sync_connected(ThunderboltRootPort *trp,
+                                                 bool notify);
+
+static Aml *build_device_properties_dsd(Aml *properties)
+{
+    Aml *dsd;
+
+    dsd = aml_package(2);
+    aml_append(dsd, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
+    aml_append(dsd, properties);
+
+    return aml_name_decl("_DSD", dsd);
+}
+
+static void append_bool_property(Aml *properties, const char *name)
+{
+    Aml *property = aml_package(2);
+
+    aml_append(property, aml_string("%s", name));
+    aml_append(property, aml_int(1));
+    aml_append(properties, property);
+}
+
+static void build_thunderbolt_root_port_dsd(Aml *scope)
+{
+    Aml *properties;
+
+    properties = aml_package(2);
+    append_bool_property(properties, "PCI-Thunderbolt");
+    append_bool_property(properties, "pci-supports-link-change");
+
+    aml_append(scope, build_device_properties_dsd(properties));
+}
+
+static void build_thunderbolt_root_port_aml(AcpiDevAmlIf *adev, Aml *scope)
+{
+    build_thunderbolt_root_port_dsd(scope);
+    build_pci_bridge_aml(adev, scope);
+}
+
+static bool thunderbolt_root_port_get_connected(Object *obj, Error **errp)
+{
+    return THUNDERBOLT_ROOT_PORT(obj)->connected;
+}
+
+static void thunderbolt_root_port_set_connected(Object *obj, bool value,
+                                                Error **errp)
+{
+    ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+
+    if (trp->connected == value) {
+        return;
+    }
+
+    trp->connected = value;
+
+    if (!qdev_is_realized(DEVICE(obj))) {
+        return;
+    }
+
+    thunderbolt_root_port_sync_connected(trp, true);
+}
+
+static void thunderbolt_root_port_sync_connected(ThunderboltRootPort *trp,
+                                                 bool notify)
+{
+    PCIDevice *rp = PCI_DEVICE(trp);
+    PCIBus *bus = pci_bridge_get_sec_bus(PCI_BRIDGE(rp));
+    bool present = false;
+    int devfn;
+
+    for (devfn = 0; devfn < PCI_DEVFN_MAX; devfn++) {
+        PCIDevice *child = bus->devices[devfn];
+
+        if (!child) {
+            continue;
+        }
+
+        present = true;
+        if (trp->connected) {
+            pci_set_enabled(child, true);
+        }
+    }
+
+    if (trp->connected && present) {
+        thunderbolt_root_port_set_presence(rp, true, notify);
+    } else {
+        thunderbolt_root_port_set_presence(rp, false, notify);
+        for (devfn = 0; devfn < PCI_DEVFN_MAX; devfn++) {
+            PCIDevice *child = bus->devices[devfn];
+
+            if (child) {
+                pci_set_enabled(child, false);
+            }
+        }
+    }
+}
+
+static void thunderbolt_root_port_machine_done(Notifier *notifier, void *data)
+{
+    ThunderboltRootPort *trp = container_of(notifier, ThunderboltRootPort,
+                                            machine_done);
+
+    thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_device_realize(DeviceListener *listener,
+                                                 DeviceState *dev)
+{
+    ThunderboltRootPort *trp = container_of(listener, ThunderboltRootPort,
+                                           listener);
+    PCIBus *bus;
+
+    if (!dev->parent_bus ||
+        !object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE) ||
+        !object_dynamic_cast(OBJECT(dev->parent_bus), TYPE_THUNDERBOLT_BUS)) {
+        return;
+    }
+
+    bus = PCI_BUS(dev->parent_bus);
+    if (bus->parent_dev != PCI_DEVICE(trp)) {
+        return;
+    }
+
+    thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_instance_init(Object *obj)
+{
+    ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+
+    trp->connected = true;
+    object_property_add_bool(obj, "connected",
+                             thunderbolt_root_port_get_connected,
+                             thunderbolt_root_port_set_connected);
+}
+
+static void thunderbolt_root_port_set_presence(PCIDevice *dev, bool present,
+                                               bool notify)
+{
+    uint8_t *exp_cap = dev->config + dev->exp.exp_cap;
+    uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);
+
+    if (present) {
+        pcie_cap_slot_enable_power(dev);
+        pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+                                   PCI_EXP_SLTSTA_PDS);
+        if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
+            (lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
+            pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+                                       PCI_EXP_LNKSTA_DLLLA);
+        }
+    } else {
+        pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
+                                     PCI_EXP_SLTSTA_PDS);
+        if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
+            (lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
+            pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
+                                         PCI_EXP_LNKSTA_DLLLA);
+        }
+    }
+
+    if (notify) {
+        pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+                                   PCI_EXP_SLTSTA_PDC);
+        pcie_cap_slot_push_attention_button(dev);
+    }
+}
+
+static void thunderbolt_root_port_pre_plug(HotplugHandler *hotplug_dev,
+                                           DeviceState *dev, Error **errp)
+{
+    pcie_cap_slot_pre_plug_cb(hotplug_dev, dev, errp);
+}
+
+static void thunderbolt_root_port_plug(HotplugHandler *hotplug_dev,
+                                       DeviceState *dev, Error **errp)
+{
+    ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(hotplug_dev);
+
+    if (trp->connected) {
+        pcie_cap_slot_plug_cb(hotplug_dev, dev, errp);
+        return;
+    }
+
+    pci_set_enabled(PCI_DEVICE(dev), false);
+    thunderbolt_root_port_set_presence(PCI_DEVICE(hotplug_dev), false, false);
+}
+
+static void thunderbolt_root_port_unplug_request(HotplugHandler *hotplug_dev,
+                                                 DeviceState *dev,
+                                                 Error **errp)
+{
+    pcie_cap_slot_unplug_request_cb(hotplug_dev, dev, errp);
+}
+
+static void thunderbolt_root_port_unplug(HotplugHandler *hotplug_dev,
+                                         DeviceState *dev, Error **errp)
+{
+    pcie_cap_slot_unplug_cb(hotplug_dev, dev, errp);
+}
+
+static uint8_t thunderbolt_root_port_aer_vector(const PCIDevice *dev)
+{
+    return 0;
+}
+
+static void thunderbolt_root_port_aer_vector_update(PCIDevice *dev)
+{
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+
+    if (rpc->aer_vector) {
+        pcie_aer_root_set_vector(dev, rpc->aer_vector(dev));
+    }
+}
+
+static int thunderbolt_root_port_interrupts_init(PCIDevice *dev, Error **errp)
+{
+    int rc;
+
+    rc = msix_init_exclusive_bar(dev, THUNDERBOLT_ROOT_PORT_MSIX_NR_VECTOR,
+                                 0, errp);
+    if (rc < 0) {
+        assert(rc == -ENOTSUP);
+    } else {
+        msix_vector_use(dev, 0);
+    }
+
+    return rc;
+}
+
+static void thunderbolt_root_port_interrupts_uninit(PCIDevice *dev)
+{
+    msix_uninit_exclusive_bar(dev);
+}
+
+static void thunderbolt_root_port_write_config(PCIDevice *dev,
+                                               uint32_t address,
+                                               uint32_t val, int len)
+{
+    uint32_t root_cmd =
+        pci_get_long(dev->config + dev->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
+    uint16_t slt_ctl;
+    uint16_t slt_sta;
+
+    pcie_cap_slot_get(dev, &slt_ctl, &slt_sta);
+
+    pci_bridge_write_config(dev, address, val, len);
+    thunderbolt_root_port_aer_vector_update(dev);
+    pcie_cap_slot_write_config(dev, slt_ctl, slt_sta, address, val, len);
+    pcie_aer_write_config(dev, address, val, len);
+    pcie_aer_root_write_config(dev, address, val, len, root_cmd);
+}
+
+static void thunderbolt_root_port_reset_hold(Object *obj, ResetType type)
+{
+    ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+    PCIDevice *dev = PCI_DEVICE(obj);
+    DeviceState *qdev = DEVICE(obj);
+
+    thunderbolt_root_port_aer_vector_update(dev);
+    pcie_cap_root_reset(dev);
+    pcie_cap_deverr_reset(dev);
+    pcie_cap_slot_reset(dev);
+    pcie_cap_arifwd_reset(dev);
+    pcie_acs_reset(dev);
+    pcie_aer_root_reset(dev);
+    pci_bridge_reset(qdev);
+    pci_bridge_disable_base_limit(dev);
+    thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_realize_pci(PCIDevice *dev, Error **errp)
+{
+    PCIEPort *p = PCIE_PORT(dev);
+    PCIESlot *s = PCIE_SLOT(dev);
+    PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(dev);
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    int rc;
+
+    pci_config_set_interrupt_pin(dev->config, 1);
+    pci_bridge_initfn(dev, TYPE_THUNDERBOLT_BUS);
+    pcie_port_init_reg(dev);
+
+    rc = pci_bridge_ssvid_init(dev, rpc->ssvid_offset, dc->vendor_id,
+                               rpc->ssid, errp);
+    if (rc < 0) {
+        error_append_hint(errp, "Can't init SSV ID, error %d\n", rc);
+        goto err_bridge;
+    }
+
+    if (rpc->interrupts_init) {
+        rc = rpc->interrupts_init(dev, errp);
+        if (rc < 0) {
+            goto err_bridge;
+        }
+    }
+
+    rc = pcie_cap_init(dev, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT,
+                       p->port, errp);
+    if (rc < 0) {
+        error_append_hint(errp, "Can't add Root Port capability, "
+                          "error %d\n", rc);
+        goto err_int;
+    }
+
+    pcie_cap_arifwd_init(dev);
+    pcie_cap_deverr_init(dev);
+    pcie_cap_slot_init(dev, s);
+    qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))),
+                             OBJECT(dev));
+    pcie_cap_root_init(dev);
+
+    pcie_chassis_create(s->chassis);
+    rc = pcie_chassis_add_slot(s);
+    if (rc < 0) {
+        error_setg(errp, "Can't add chassis slot, error %d", rc);
+        goto err_pcie_cap;
+    }
+
+    rc = pcie_aer_init(dev, PCI_ERR_VER, rpc->aer_offset,
+                       PCI_ERR_SIZEOF, errp);
+    if (rc < 0) {
+        goto err;
+    }
+    pcie_aer_root_init(dev);
+    thunderbolt_root_port_aer_vector_update(dev);
+
+    if (rpc->acs_offset) {
+        pcie_acs_init(dev, rpc->acs_offset);
+    }
+
+    THUNDERBOLT_ROOT_PORT(dev)->listener.realize =
+        thunderbolt_root_port_device_realize;
+    device_listener_register(&THUNDERBOLT_ROOT_PORT(dev)->listener);
+
+    THUNDERBOLT_ROOT_PORT(dev)->machine_done.notify =
+        thunderbolt_root_port_machine_done;
+    qemu_add_machine_init_done_notifier(
+        &THUNDERBOLT_ROOT_PORT(dev)->machine_done);
+
+    return;
+
+err:
+    pcie_chassis_del_slot(s);
+err_pcie_cap:
+    pcie_cap_exit(dev);
+err_int:
+    if (rpc->interrupts_uninit) {
+        rpc->interrupts_uninit(dev);
+    }
+err_bridge:
+    pci_bridge_exitfn(dev);
+}
+
+static void thunderbolt_root_port_exit(PCIDevice *dev)
+{
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    PCIESlot *s = PCIE_SLOT(dev);
+
+    pcie_aer_exit(dev);
+    pcie_chassis_del_slot(s);
+    pcie_cap_exit(dev);
+    if (rpc->interrupts_uninit) {
+        rpc->interrupts_uninit(dev);
+    }
+    device_listener_unregister(&THUNDERBOLT_ROOT_PORT(dev)->listener);
+    qemu_remove_machine_init_done_notifier(
+        &THUNDERBOLT_ROOT_PORT(dev)->machine_done);
+    pci_bridge_exitfn(dev);
+}
+
+static void thunderbolt_root_port_realize(DeviceState *dev, Error **errp)
+{
+    ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(dev);
+    PCIESlot *slot = PCIE_SLOT(dev);
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    Error *local_err = NULL;
+    int rc;
+
+    rpc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    if (slot->hide_native_hotplug_cap &&
+        trp->res_reserve.io == (uint64_t)-1 && slot->hotplug) {
+        trp->res_reserve.io = THUNDERBOLT_ROOT_DEFAULT_IO_RANGE;
+    }
+
+    rc = pci_bridge_qemu_reserve_cap_init(PCI_DEVICE(dev), 0,
+                                          trp->res_reserve, errp);
+    if (rc < 0) {
+        rpc->parent_class.exit(PCI_DEVICE(dev));
+        return;
+    }
+
+    if (!trp->res_reserve.io) {
+        PCIDevice *pdev = PCI_DEVICE(dev);
+
+        pci_word_test_and_clear_mask(pdev->wmask + PCI_COMMAND,
+                                     PCI_COMMAND_IO);
+        pdev->wmask[PCI_IO_BASE] = 0;
+        pdev->wmask[PCI_IO_LIMIT] = 0;
+    }
+}
+
+static bool thunderbolt_root_port_test_migrate_msix(void *opaque,
+                                                    int version_id)
+{
+    ThunderboltRootPort *trp = opaque;
+
+    return trp->migrate_msix;
+}
+
+static const VMStateDescription vmstate_thunderbolt_root_port = {
+    .name = "thunderbolt-root-port",
+    .priority = MIG_PRI_PCI_BUS,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = pcie_cap_slot_post_load,
+    .fields = (const VMStateField[]) {
+        VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj.parent_obj,
+                           ThunderboltRootPort),
+        VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.parent_obj.exp.aer_log,
+                       ThunderboltRootPort, 0, vmstate_pcie_aer_log,
+                       PCIEAERLog),
+        VMSTATE_MSIX_TEST(parent_obj.parent_obj.parent_obj.parent_obj,
+                          ThunderboltRootPort,
+                          thunderbolt_root_port_test_migrate_msix),
+        VMSTATE_BOOL(connected, ThunderboltRootPort),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const Property thunderbolt_root_port_props[] = {
+    DEFINE_PROP_BOOL("x-migrate-msix", ThunderboltRootPort,
+                     migrate_msix, true),
+    DEFINE_PROP_UINT32("bus-reserve", ThunderboltRootPort,
+                       res_reserve.bus, -1),
+    DEFINE_PROP_SIZE("io-reserve", ThunderboltRootPort,
+                     res_reserve.io, -1),
+    DEFINE_PROP_SIZE("mem-reserve", ThunderboltRootPort,
+                     res_reserve.mem_non_pref, -1),
+    DEFINE_PROP_SIZE("pref32-reserve", ThunderboltRootPort,
+                     res_reserve.mem_pref_32, -1),
+    DEFINE_PROP_SIZE("pref64-reserve", ThunderboltRootPort,
+                     res_reserve.mem_pref_64, -1),
+    DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot,
+                                speed, PCIE_LINK_SPEED_16),
+    DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot,
+                                width, PCIE_LINK_WIDTH_32),
+};
+
+static void thunderbolt_root_port_class_init(ObjectClass *klass,
+                                             const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
+    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP;
+    k->config_write = thunderbolt_root_port_write_config;
+    k->realize = thunderbolt_root_port_realize_pci;
+    k->exit = thunderbolt_root_port_exit;
+    dc->desc = "Thunderbolt PCI Express Root Port";
+    dc->vmsd = &vmstate_thunderbolt_root_port;
+    device_class_set_props(dc, thunderbolt_root_port_props);
+    device_class_set_parent_realize(dc, thunderbolt_root_port_realize,
+                                    &rpc->parent_realize);
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    rc->phases.hold = thunderbolt_root_port_reset_hold;
+
+    hc->pre_plug = thunderbolt_root_port_pre_plug;
+    hc->plug = thunderbolt_root_port_plug;
+    hc->unplug = thunderbolt_root_port_unplug;
+    hc->unplug_request = thunderbolt_root_port_unplug_request;
+
+    rpc->aer_vector = thunderbolt_root_port_aer_vector;
+    rpc->interrupts_init = thunderbolt_root_port_interrupts_init;
+    rpc->interrupts_uninit = thunderbolt_root_port_interrupts_uninit;
+    rpc->aer_offset = THUNDERBOLT_ROOT_PORT_AER_OFFSET;
+    rpc->acs_offset = THUNDERBOLT_ROOT_PORT_ACS_OFFSET;
+    adevc->build_dev_aml = build_thunderbolt_root_port_aml;
+}
+
+static const TypeInfo thunderbolt_root_port_info = {
+    .name          = TYPE_THUNDERBOLT_ROOT_PORT,
+    .parent        = TYPE_PCIE_ROOT_PORT,
+    .instance_size = sizeof(ThunderboltRootPort),
+    .instance_init = thunderbolt_root_port_instance_init,
+    .class_init    = thunderbolt_root_port_class_init,
+    .interfaces = (const InterfaceInfo[]) {
+        { TYPE_ACPI_DEV_AML_IF },
+        { },
+    },
+};
+
+static const TypeInfo thunderbolt_bus_info = {
+    .name   = TYPE_THUNDERBOLT_BUS,
+    .parent = TYPE_PCIE_BUS,
+};
+
+static void thunderbolt_root_port_register_types(void)
+{
+    type_register_static(&thunderbolt_bus_info);
+    type_register_static(&thunderbolt_root_port_info);
+}
+
+type_init(thunderbolt_root_port_register_types)
-- 
2.47.3


Reply via email to