hw/ssi: Check for duplicate CS indexes
This to avoid indexes conflicts on the same SSI bus. Adapt machines using multiple devices on the same bus to avoid breakage. Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> Cc: Alistair Francis <alistair@alistair23.me> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
27a2c66c92
commit
a617e65f43
@ -1242,7 +1242,9 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
|
||||
qdev_get_child_bus(sddev, "sd-bus"),
|
||||
&error_fatal);
|
||||
|
||||
ssddev = ssi_create_peripheral(bus, "ssd0323");
|
||||
ssddev = qdev_new("ssd0323");
|
||||
qdev_prop_set_uint8(ssddev, "cs", 1);
|
||||
qdev_realize_and_unref(ssddev, bus, &error_fatal);
|
||||
|
||||
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
|
||||
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
|
||||
|
@ -164,6 +164,7 @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
|
||||
blk_by_legacy_dinfo(dinfo),
|
||||
&error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", j);
|
||||
qdev_realize_and_unref(flash_dev, BUS(spi), &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
@ -740,6 +740,7 @@ static void versal_virt_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
@ -201,6 +201,7 @@ static void xlnx_zcu102_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
@ -224,6 +225,7 @@ static void xlnx_zcu102_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
@ -192,6 +192,7 @@ petalogix_ml605_init(MachineState *machine)
|
||||
blk_by_legacy_dinfo(dinfo),
|
||||
&error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(dev, "cs", i);
|
||||
qdev_realize_and_unref(dev, BUS(spi), &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
|
||||
|
21
hw/ssi/ssi.c
21
hw/ssi/ssi.c
@ -42,10 +42,31 @@ DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool ssi_bus_check_address(BusState *b, DeviceState *dev, Error **errp)
|
||||
{
|
||||
SSIPeripheral *s = SSI_PERIPHERAL(dev);
|
||||
|
||||
if (ssi_get_cs(SSI_BUS(b), s->cs_index)) {
|
||||
error_setg(errp, "CS index '0x%x' in use by a %s device", s->cs_index,
|
||||
object_get_typename(OBJECT(dev)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ssi_bus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
BusClass *k = BUS_CLASS(klass);
|
||||
|
||||
k->check_address = ssi_bus_check_address;
|
||||
}
|
||||
|
||||
static const TypeInfo ssi_bus_info = {
|
||||
.name = TYPE_SSI_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
.instance_size = sizeof(SSIBus),
|
||||
.class_init = ssi_bus_class_init,
|
||||
};
|
||||
|
||||
static void ssi_cs_default(void *opaque, int n, int level)
|
||||
|
Loading…
Reference in New Issue
Block a user