xref: /openbmc/qemu/hw/usb/hcd-uhci-sysbus.c (revision 83698261)
1 /*
2  * QEMU USB UHCI Emulation
3  * Copyright (c) 2006 Openedhand Ltd.
4  * Copyright (c) 2010 CodeSourcery
5  * Copyright (c) 2024 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "hw/irq.h"
23 #include "qapi/error.h"
24 #include "qemu/module.h"
25 #include "qemu/timer.h"
26 #include "hw/usb.h"
27 #include "migration/vmstate.h"
28 #include "hw/sysbus.h"
29 #include "hw/qdev-dma.h"
30 #include "hw/qdev-properties.h"
31 #include "trace.h"
32 #include "hcd-uhci.h"
33 #include "hcd-uhci-sysbus.h"
34 
35 static void uhci_sysbus_reset(UHCIState *uhci)
36 {
37     uhci_state_reset(uhci);
38 }
39 
40 static void uhci_sysbus_realize(DeviceState *dev, Error **errp)
41 {
42     UHCISysBusState *s = SYSBUS_UHCI(dev);
43     UHCIState *uhci = &s->uhci;
44     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
45     Error *err = NULL;
46 
47     uhci->masterbus = s->masterbus;
48     uhci->firstport = s->firstport;
49     uhci->maxframes = s->maxframes;
50     uhci->frame_bandwidth = s->frame_bandwidth;
51     uhci->as = &address_space_memory;
52     uhci->uhci_reset = uhci_sysbus_reset;
53 
54     usb_uhci_init(uhci, dev, &err);
55 
56     if (err) {
57         error_propagate(errp, err);
58         return;
59     }
60     sysbus_init_irq(sbd, &uhci->irq);
61     sysbus_init_mmio(sbd, &uhci->mem);
62 }
63 
64 static void uhci_sysbus_reset_sysbus(DeviceState *dev)
65 {
66     UHCISysBusState *s = SYSBUS_UHCI(dev);
67     UHCIState *uhci = &s->uhci;
68 
69     uhci_sysbus_reset(uhci);
70 }
71 
72 static Property uhci_sysbus_properties[] = {
73     DEFINE_PROP_STRING("masterbus", UHCISysBusState, masterbus),
74     DEFINE_PROP_UINT32("firstport", UHCISysBusState, firstport, 0),
75     DEFINE_PROP_UINT32("bandwidth", UHCISysBusState, frame_bandwidth, 1280),
76     DEFINE_PROP_UINT32("maxframes", UHCISysBusState, maxframes, 128),
77     DEFINE_PROP_END_OF_LIST(),
78 };
79 
80 static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
81 {
82     DeviceClass *dc = DEVICE_CLASS(klass);
83 
84     dc->realize = uhci_sysbus_realize;
85     set_bit(DEVICE_CATEGORY_USB, dc->categories);
86     dc->desc = "UHCI USB Controller";
87     device_class_set_props(dc, uhci_sysbus_properties);
88     device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
89 }
90 
91 static const TypeInfo uhci_sysbus_types[] = {
92     {
93         .name          = TYPE_SYSBUS_UHCI,
94         .parent        = TYPE_SYS_BUS_DEVICE,
95         .instance_size = sizeof(UHCISysBusState),
96         .class_init    = uhci_sysbus_class_init,
97     },
98 };
99 
100 DEFINE_TYPES(uhci_sysbus_types);
101