@@ -1101,6 +1101,18 @@ static const MemoryRegionOps aspeed_smc_ops = {
1101
1101
.endianness = DEVICE_LITTLE_ENDIAN ,
1102
1102
};
1103
1103
1104
+ static void aspeed_smc_instance_init (Object * obj )
1105
+ {
1106
+ AspeedSMCState * s = ASPEED_SMC (obj );
1107
+ AspeedSMCClass * asc = ASPEED_SMC_GET_CLASS (s );
1108
+ int i ;
1109
+
1110
+ for (i = 0 ; i < asc -> max_peripherals ; i ++ ) {
1111
+ object_initialize_child (obj , "flash[*]" , & s -> flashes [i ],
1112
+ TYPE_ASPEED_SMC_FLASH );
1113
+ }
1114
+ }
1115
+
1104
1116
/*
1105
1117
* Initialize the custom address spaces for DMAs
1106
1118
*/
@@ -1123,7 +1135,6 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1123
1135
AspeedSMCState * s = ASPEED_SMC (dev );
1124
1136
AspeedSMCClass * asc = ASPEED_SMC_GET_CLASS (s );
1125
1137
int i ;
1126
- char name [32 ];
1127
1138
hwaddr offset = 0 ;
1128
1139
1129
1140
/* keep a copy under AspeedSMCState to speed up accesses */
@@ -1170,8 +1181,6 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1170
1181
& s -> mmio_flash , 0 , asc -> flash_window_size );
1171
1182
sysbus_init_mmio (sbd , & s -> mmio_flash_alias );
1172
1183
1173
- s -> flashes = g_new0 (AspeedSMCFlash , asc -> max_peripherals );
1174
-
1175
1184
/*
1176
1185
* Let's create a sub memory region for each possible peripheral. All
1177
1186
* have a configurable memory segment in the overall flash mapping
@@ -1182,12 +1191,17 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1182
1191
for (i = 0 ; i < asc -> max_peripherals ; ++ i ) {
1183
1192
AspeedSMCFlash * fl = & s -> flashes [i ];
1184
1193
1185
- snprintf (name , sizeof (name ), TYPE_ASPEED_SMC ".flash.%d" , i );
1194
+ if (!object_property_set_link (OBJECT (fl ), "controller" , OBJECT (s ),
1195
+ errp )) {
1196
+ return ;
1197
+ }
1198
+ if (!object_property_set_uint (OBJECT (fl ), "cs" , i , errp )) {
1199
+ return ;
1200
+ }
1201
+ if (!sysbus_realize (SYS_BUS_DEVICE (fl ), errp )) {
1202
+ return ;
1203
+ }
1186
1204
1187
- fl -> cs = i ;
1188
- fl -> controller = s ;
1189
- memory_region_init_io (& fl -> mmio , OBJECT (s ), & aspeed_smc_flash_ops ,
1190
- fl , name , asc -> segments [i ].size );
1191
1205
memory_region_add_subregion (& s -> mmio_flash , offset , & fl -> mmio );
1192
1206
offset += asc -> segments [i ].size ;
1193
1207
}
@@ -1231,12 +1245,57 @@ static void aspeed_smc_class_init(ObjectClass *klass, void *data)
1231
1245
static const TypeInfo aspeed_smc_info = {
1232
1246
.name = TYPE_ASPEED_SMC ,
1233
1247
.parent = TYPE_SYS_BUS_DEVICE ,
1248
+ .instance_init = aspeed_smc_instance_init ,
1234
1249
.instance_size = sizeof (AspeedSMCState ),
1235
1250
.class_size = sizeof (AspeedSMCClass ),
1236
1251
.class_init = aspeed_smc_class_init ,
1237
1252
.abstract = true,
1238
1253
};
1239
1254
1255
+ static void aspeed_smc_flash_realize (DeviceState * dev , Error * * errp )
1256
+ {
1257
+ AspeedSMCFlash * s = ASPEED_SMC_FLASH (dev );
1258
+ AspeedSMCClass * asc ;
1259
+ g_autofree char * name = g_strdup_printf (TYPE_ASPEED_SMC_FLASH ".%d" , s -> cs );
1260
+
1261
+ if (!s -> controller ) {
1262
+ error_setg (errp , TYPE_ASPEED_SMC_FLASH ": 'controller' link not set" );
1263
+ return ;
1264
+ }
1265
+
1266
+ asc = ASPEED_SMC_GET_CLASS (s -> controller );
1267
+
1268
+ /*
1269
+ * Use the default segment value to size the memory region. This
1270
+ * can be changed by FW at runtime.
1271
+ */
1272
+ memory_region_init_io (& s -> mmio , OBJECT (s ), & aspeed_smc_flash_ops ,
1273
+ s , name , asc -> segments [s -> cs ].size );
1274
+ sysbus_init_mmio (SYS_BUS_DEVICE (dev ), & s -> mmio );
1275
+ }
1276
+
1277
+ static Property aspeed_smc_flash_properties [] = {
1278
+ DEFINE_PROP_UINT8 ("cs" , AspeedSMCFlash , cs , 0 ),
1279
+ DEFINE_PROP_LINK ("controller" , AspeedSMCFlash , controller , TYPE_ASPEED_SMC ,
1280
+ AspeedSMCState * ),
1281
+ DEFINE_PROP_END_OF_LIST (),
1282
+ };
1283
+
1284
+ static void aspeed_smc_flash_class_init (ObjectClass * klass , void * data )
1285
+ {
1286
+ DeviceClass * dc = DEVICE_CLASS (klass );
1287
+
1288
+ dc -> desc = "Aspeed SMC Flash device region" ;
1289
+ dc -> realize = aspeed_smc_flash_realize ;
1290
+ device_class_set_props (dc , aspeed_smc_flash_properties );
1291
+ }
1292
+
1293
+ static const TypeInfo aspeed_smc_flash_info = {
1294
+ .name = TYPE_ASPEED_SMC_FLASH ,
1295
+ .parent = TYPE_SYS_BUS_DEVICE ,
1296
+ .instance_size = sizeof (AspeedSMCFlash ),
1297
+ .class_init = aspeed_smc_flash_class_init ,
1298
+ };
1240
1299
1241
1300
/*
1242
1301
* The Segment Registers of the AST2400 and AST2500 have a 8MB
@@ -1625,6 +1684,7 @@ static const TypeInfo aspeed_2600_spi2_info = {
1625
1684
1626
1685
static void aspeed_smc_register_types (void )
1627
1686
{
1687
+ type_register_static (& aspeed_smc_flash_info );
1628
1688
type_register_static (& aspeed_smc_info );
1629
1689
type_register_static (& aspeed_2400_smc_info );
1630
1690
type_register_static (& aspeed_2400_fmc_info );
0 commit comments