Skip to content

Commit 6026103

Browse files
committed
aspeed/i2c: QOMify AspeedI2CBus
Introduce an AspeedI2CBus SysBusDevice model and attach the associated memory region and IRQ to the newly instantiated objects. Before this change, the I2C bus IRQs were all attached to the SysBusDevice model of the I2C controller. Adapt the AST2600 SoC realize routine to take into account this change. Signed-off-by: Cédric Le Goater <[email protected]>
1 parent 33456a8 commit 6026103

File tree

3 files changed

+91
-25
lines changed

3 files changed

+91
-25
lines changed

hw/arm/aspeed_ast2600.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
337337
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
338338
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore),
339339
sc->irqmap[ASPEED_DEV_I2C] + i);
340-
/*
341-
* The AST2600 SoC has one IRQ per I2C bus. Skip the common
342-
* IRQ (AST2400 and AST2500) and connect all bussses.
343-
*/
344-
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), i + 1, irq);
340+
/* The AST2600 I2C controller has one IRQ per bus. */
341+
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
345342
}
346343

347344
/* FMC, The number of CS is set at the board level */

hw/i2c/aspeed_i2c.c

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -740,20 +740,20 @@ static const VMStateDescription aspeed_i2c_vmstate = {
740740

741741
static void aspeed_i2c_reset(DeviceState *dev)
742742
{
743-
int i;
744743
AspeedI2CState *s = ASPEED_I2C(dev);
745-
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
746744

747745
s->intr_status = 0;
746+
}
747+
748+
static void aspeed_i2c_instance_init(Object *obj)
749+
{
750+
AspeedI2CState *s = ASPEED_I2C(obj);
751+
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
752+
int i;
748753

749754
for (i = 0; i < aic->num_busses; i++) {
750-
s->busses[i].intr_ctrl = 0;
751-
s->busses[i].intr_status = 0;
752-
s->busses[i].cmd = 0;
753-
s->busses[i].buf = 0;
754-
s->busses[i].dma_addr = 0;
755-
s->busses[i].dma_len = 0;
756-
i2c_end_transfer(s->busses[i].bus);
755+
object_initialize_child(obj, "bus[*]", &s->busses[i],
756+
TYPE_ASPEED_I2C_BUS);
757757
}
758758
}
759759

@@ -791,17 +791,21 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
791791
sysbus_init_mmio(sbd, &s->iomem);
792792

793793
for (i = 0; i < aic->num_busses; i++) {
794-
char name[32];
794+
Object *bus = OBJECT(&s->busses[i]);
795795
int offset = i < aic->gap ? 1 : 5;
796796

797-
sysbus_init_irq(sbd, &s->busses[i].irq);
798-
snprintf(name, sizeof(name), "aspeed.i2c.%d", i);
799-
s->busses[i].controller = s;
800-
s->busses[i].id = i;
801-
s->busses[i].bus = i2c_init_bus(dev, name);
802-
memory_region_init_io(&s->busses[i].mr, OBJECT(dev),
803-
&aspeed_i2c_bus_ops, &s->busses[i], name,
804-
aic->reg_size);
797+
if (!object_property_set_link(bus, "controller", OBJECT(s), errp)) {
798+
return;
799+
}
800+
801+
if (!object_property_set_uint(bus, "bus-id", i, errp)) {
802+
return;
803+
}
804+
805+
if (!sysbus_realize(SYS_BUS_DEVICE(bus), errp)) {
806+
return;
807+
}
808+
805809
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
806810
&s->busses[i].mr);
807811
}
@@ -841,12 +845,72 @@ static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
841845
static const TypeInfo aspeed_i2c_info = {
842846
.name = TYPE_ASPEED_I2C,
843847
.parent = TYPE_SYS_BUS_DEVICE,
848+
.instance_init = aspeed_i2c_instance_init,
844849
.instance_size = sizeof(AspeedI2CState),
845850
.class_init = aspeed_i2c_class_init,
846851
.class_size = sizeof(AspeedI2CClass),
847852
.abstract = true,
848853
};
849854

855+
static void aspeed_i2c_bus_reset(DeviceState *dev)
856+
{
857+
AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
858+
859+
s->intr_ctrl = 0;
860+
s->intr_status = 0;
861+
s->cmd = 0;
862+
s->buf = 0;
863+
s->dma_addr = 0;
864+
s->dma_len = 0;
865+
i2c_end_transfer(s->bus);
866+
}
867+
868+
static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
869+
{
870+
AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
871+
AspeedI2CClass *aic;
872+
g_autofree char *name = g_strdup_printf(TYPE_ASPEED_I2C_BUS ".%d", s->id);
873+
874+
if (!s->controller) {
875+
error_setg(errp, TYPE_ASPEED_I2C_BUS ": 'controller' link not set");
876+
return;
877+
}
878+
879+
aic = ASPEED_I2C_GET_CLASS(s->controller);
880+
881+
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
882+
883+
s->bus = i2c_init_bus(dev, name);
884+
885+
memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i2c_bus_ops,
886+
s, name, aic->reg_size);
887+
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr);
888+
}
889+
890+
static Property aspeed_i2c_bus_properties[] = {
891+
DEFINE_PROP_UINT8("bus-id", AspeedI2CBus, id, 0),
892+
DEFINE_PROP_LINK("controller", AspeedI2CBus, controller, TYPE_ASPEED_I2C,
893+
AspeedI2CState *),
894+
DEFINE_PROP_END_OF_LIST(),
895+
};
896+
897+
static void aspeed_i2c_bus_class_init(ObjectClass *klass, void *data)
898+
{
899+
DeviceClass *dc = DEVICE_CLASS(klass);
900+
901+
dc->desc = "Aspeed I2C Bus";
902+
dc->realize = aspeed_i2c_bus_realize;
903+
dc->reset = aspeed_i2c_bus_reset;
904+
device_class_set_props(dc, aspeed_i2c_bus_properties);
905+
}
906+
907+
static const TypeInfo aspeed_i2c_bus_info = {
908+
.name = TYPE_ASPEED_I2C_BUS,
909+
.parent = TYPE_SYS_BUS_DEVICE,
910+
.instance_size = sizeof(AspeedI2CBus),
911+
.class_init = aspeed_i2c_bus_class_init,
912+
};
913+
850914
static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
851915
{
852916
return bus->controller->irq;
@@ -951,6 +1015,7 @@ static const TypeInfo aspeed_2600_i2c_info = {
9511015

9521016
static void aspeed_i2c_register_types(void)
9531017
{
1018+
type_register_static(&aspeed_i2c_bus_info);
9541019
type_register_static(&aspeed_i2c_info);
9551020
type_register_static(&aspeed_2400_i2c_info);
9561021
type_register_static(&aspeed_2500_i2c_info);

include/hw/i2c/aspeed_i2c.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
3636

3737
struct AspeedI2CState;
3838

39-
typedef struct AspeedI2CBus {
39+
#define TYPE_ASPEED_I2C_BUS "aspeed.i2c.bus"
40+
OBJECT_DECLARE_SIMPLE_TYPE(AspeedI2CBus, ASPEED_I2C_BUS)
41+
struct AspeedI2CBus {
42+
SysBusDevice parent_obj;
43+
4044
struct AspeedI2CState *controller;
4145

4246
MemoryRegion mr;
@@ -54,7 +58,7 @@ typedef struct AspeedI2CBus {
5458
uint32_t pool_ctrl;
5559
uint32_t dma_addr;
5660
uint32_t dma_len;
57-
} AspeedI2CBus;
61+
};
5862

5963
struct AspeedI2CState {
6064
SysBusDevice parent_obj;

0 commit comments

Comments
 (0)