[RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus

Guenter Roeck posted 8 patches 2 months, 2 weeks ago
There is a newer version of this series
[RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus
Posted by Guenter Roeck 2 months, 2 weeks ago
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 hw/arm/Kconfig           |   1 +
 hw/usb/Kconfig           |   4 ++
 hw/usb/hcd-uhci-sysbus.c | 100 +++++++++++++++++++++++++++++++++++++++
 hw/usb/hcd-uhci-sysbus.h |  23 +++++++++
 hw/usb/meson.build       |   1 +
 5 files changed, 129 insertions(+)
 create mode 100644 hw/usb/hcd-uhci-sysbus.c
 create mode 100644 hw/usb/hcd-uhci-sysbus.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1ad60da7aa..8b1253fae5 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -606,6 +606,7 @@ config ASPEED_SOC
     select PMBUS
     select MAX31785
     select FSI_APB2OPB_ASPEED
+    select USB_UHCI_SYSBUS
 
 config MPS2
     bool
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 7d034738ce..fe5375050c 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -11,6 +11,10 @@ config USB_UHCI_PCI
     depends on PCI
     select USB_UHCI
 
+config USB_UHCI_SYSBUS
+    bool
+    select USB_UHCI
+
 config USB_OHCI
     bool
     select USB
diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
new file mode 100644
index 0000000000..6f2428cc15
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -0,0 +1,100 @@
+/*
+ * QEMU USB UHCI Emulation
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 CodeSourcery
+ * Copyright (c) 2024 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-dma.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+#include "hcd-uhci.h"
+#include "hcd-uhci-sysbus.h"
+
+static void uhci_sysbus_reset(UHCIState *uhci)
+{
+    uhci_state_reset(uhci);
+}
+
+static void uhci_sysbus_realize(DeviceState *dev, Error **errp)
+{
+    UHCISysBusState *s = SYSBUS_UHCI(dev);
+    UHCIState *uhci = &s->uhci;
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    Error *err = NULL;
+
+    uhci->masterbus = s->masterbus;
+    uhci->firstport = s->firstport;
+    uhci->maxframes = s->maxframes;
+    uhci->frame_bandwidth = s->frame_bandwidth;
+    uhci->as = &address_space_memory;
+    uhci->uhci_reset = uhci_sysbus_reset;
+
+    usb_uhci_init(uhci, dev, &err);
+
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_init_irq(sbd, &uhci->irq);
+    sysbus_init_mmio(sbd, &uhci->mem);
+}
+
+static void uhci_sysbus_reset_sysbus(DeviceState *dev)
+{
+    UHCISysBusState *s = SYSBUS_UHCI(dev);
+    UHCIState *uhci = &s->uhci;
+
+    uhci_sysbus_reset(uhci);
+}
+
+static Property uhci_sysbus_properties[] = {
+    DEFINE_PROP_STRING("masterbus", UHCISysBusState, masterbus),
+    DEFINE_PROP_UINT32("firstport", UHCISysBusState, firstport, 0),
+    DEFINE_PROP_UINT32("bandwidth", UHCISysBusState, frame_bandwidth, 1280),
+    DEFINE_PROP_UINT32("maxframes", UHCISysBusState, maxframes, 128),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = uhci_sysbus_realize;
+    set_bit(DEVICE_CATEGORY_USB, dc->categories);
+    dc->desc = "UHCI USB Controller";
+    device_class_set_props(dc, uhci_sysbus_properties);
+    dc->reset = uhci_sysbus_reset_sysbus;
+}
+
+static const TypeInfo uhci_sysbus_types[] = {
+    {
+        .name          = TYPE_SYSBUS_UHCI,
+        .parent        = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(UHCISysBusState),
+        .class_init    = uhci_sysbus_class_init,
+    },
+};
+
+DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hcd-uhci-sysbus.h
new file mode 100644
index 0000000000..c491b9fc92
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.h
@@ -0,0 +1,23 @@
+#ifndef HW_USB_HCD_UHCI_SYSBUS_H
+#define HW_USB_HCD_UHCI_SYSBUS_H
+
+#include "hcd-uhci.h"
+
+#define TYPE_SYSBUS_UHCI "sysbus-uhci"
+
+OBJECT_DECLARE_SIMPLE_TYPE(UHCISysBusState, SYSBUS_UHCI)
+
+struct UHCISysBusState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+    UHCIState uhci;
+
+    char *masterbus;
+    uint32_t firstport;
+    uint32_t frame_bandwidth;
+    uint32_t maxframes;
+    uint32_t num_ports;
+};
+
+#endif /* HW_USB_HCD_UHCI_SYSBUS_H */
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index a41b54ac02..b0dd4b5169 100644
--- a/hw/usb/meson.build
+++ b/hw/usb/meson.build
@@ -14,6 +14,7 @@ system_ss.add(when: 'CONFIG_USB', if_true: files(
 # usb host adapters
 system_ss.add(when: 'CONFIG_USB_UHCI', if_true: files('hcd-uhci.c'))
 system_ss.add(when: 'CONFIG_USB_UHCI_PCI', if_true: files('hcd-uhci-pci.c'))
+system_ss.add(when: 'CONFIG_USB_UHCI_SYSBUS', if_true: files('hcd-uhci-sysbus.c'))
 system_ss.add(when: 'CONFIG_USB_OHCI', if_true: files('hcd-ohci.c'))
 system_ss.add(when: 'CONFIG_USB_OHCI_PCI', if_true: files('hcd-ohci-pci.c'))
 system_ss.add(when: 'CONFIG_USB_OHCI_SYSBUS', if_true: files('hcd-ohci-sysbus.c'))
-- 
2.45.2