]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * QEMU Synchronous Serial Interface support | |
3 | * | |
4 | * Copyright (c) 2009 CodeSourcery. | |
5 | * Written by Paul Brook | |
6 | * | |
7 | * This code is licenced under the GNU GPL v2. | |
8 | */ | |
9 | ||
10 | #include "ssi.h" | |
11 | ||
12 | struct SSIBus { | |
13 | BusState qbus; | |
14 | }; | |
15 | ||
16 | static struct BusInfo ssi_bus_info = { | |
17 | .name = "SSI", | |
18 | .size = sizeof(SSIBus), | |
19 | }; | |
20 | ||
21 | static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info) | |
22 | { | |
23 | SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev); | |
24 | SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); | |
25 | SSIBus *bus; | |
26 | ||
27 | bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); | |
28 | if (QLIST_FIRST(&bus->qbus.children) != dev | |
29 | || QLIST_NEXT(dev, sibling) != NULL) { | |
30 | hw_error("Too many devices on SSI bus"); | |
31 | } | |
32 | ||
33 | s->info = info; | |
34 | return info->init(s); | |
35 | } | |
36 | ||
37 | void ssi_register_slave(SSISlaveInfo *info) | |
38 | { | |
39 | assert(info->qdev.size >= sizeof(SSISlave)); | |
40 | info->qdev.init = ssi_slave_init; | |
41 | info->qdev.bus_info = &ssi_bus_info; | |
42 | qdev_register(&info->qdev); | |
43 | } | |
44 | ||
45 | DeviceState *ssi_create_slave(SSIBus *bus, const char *name) | |
46 | { | |
47 | DeviceState *dev; | |
48 | dev = qdev_create(&bus->qbus, name); | |
49 | qdev_init_nofail(dev); | |
50 | return dev; | |
51 | } | |
52 | ||
53 | SSIBus *ssi_create_bus(DeviceState *parent, const char *name) | |
54 | { | |
55 | BusState *bus; | |
56 | bus = qbus_create(&ssi_bus_info, parent, name); | |
57 | return FROM_QBUS(SSIBus, bus); | |
58 | } | |
59 | ||
60 | uint32_t ssi_transfer(SSIBus *bus, uint32_t val) | |
61 | { | |
62 | DeviceState *dev; | |
63 | SSISlave *slave; | |
64 | dev = QLIST_FIRST(&bus->qbus.children); | |
65 | if (!dev) { | |
66 | return 0; | |
67 | } | |
68 | slave = SSI_SLAVE_FROM_QDEV(dev); | |
69 | return slave->info->transfer(slave, val); | |
70 | } |