ssi: Add slave autoconnect helper
Added helper function to automatically connect SPI slaves based on the QOM child nodes of a device. A SSI master device can call this routine to automatically hook-up all child nodes to its SPI bus. Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Acked-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
fcb5629d3e
commit
b4ae3cfa57
33
hw/ssi.c
33
hw/ssi.c
@ -139,3 +139,36 @@ static void ssi_slave_register_types(void)
|
||||
}
|
||||
|
||||
type_init(ssi_slave_register_types)
|
||||
|
||||
typedef struct SSIAutoConnectArg {
|
||||
qemu_irq **cs_linep;
|
||||
SSIBus *bus;
|
||||
} SSIAutoConnectArg;
|
||||
|
||||
static int ssi_auto_connect_slave(Object *child, void *opaque)
|
||||
{
|
||||
SSIAutoConnectArg *arg = opaque;
|
||||
SSISlave *dev = (SSISlave *)object_dynamic_cast(child, TYPE_SSI_SLAVE);
|
||||
qemu_irq cs_line;
|
||||
|
||||
if (!dev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
|
||||
qdev_set_parent_bus(DEVICE(dev), &arg->bus->qbus);
|
||||
**arg->cs_linep = cs_line;
|
||||
(*arg->cs_linep)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssi_auto_connect_slaves(DeviceState *parent, qemu_irq *cs_line,
|
||||
SSIBus *bus)
|
||||
{
|
||||
SSIAutoConnectArg arg = {
|
||||
.cs_linep = &cs_line,
|
||||
.bus = bus
|
||||
};
|
||||
|
||||
object_child_foreach(OBJECT(parent), ssi_auto_connect_slave, &arg);
|
||||
}
|
||||
|
4
hw/ssi.h
4
hw/ssi.h
@ -83,6 +83,10 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name);
|
||||
|
||||
uint32_t ssi_transfer(SSIBus *bus, uint32_t val);
|
||||
|
||||
/* Automatically connect all children nodes a spi controller as slaves */
|
||||
void ssi_auto_connect_slaves(DeviceState *parent, qemu_irq *cs_lines,
|
||||
SSIBus *bus);
|
||||
|
||||
/* max111x.c */
|
||||
void max111x_set_input(DeviceState *dev, int line, uint8_t value);
|
||||
|
||||
|
@ -320,8 +320,12 @@ static int xilinx_spi_init(SysBusDevice *dev)
|
||||
XilinxSPI *s = FROM_SYSBUS(typeof(*s), dev);
|
||||
|
||||
DB_PRINT("\n");
|
||||
|
||||
s->spi = ssi_create_bus(&dev->qdev, "spi");
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
s->cs_lines = g_new(qemu_irq, s->num_cs);
|
||||
ssi_auto_connect_slaves(DEVICE(s), s->cs_lines, s->spi);
|
||||
for (i = 0; i < s->num_cs; ++i) {
|
||||
sysbus_init_irq(dev, &s->cs_lines[i]);
|
||||
}
|
||||
@ -331,8 +335,6 @@ static int xilinx_spi_init(SysBusDevice *dev)
|
||||
|
||||
s->irqline = -1;
|
||||
|
||||
s->spi = ssi_create_bus(&dev->qdev, "spi");
|
||||
|
||||
fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
|
||||
fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
|
||||
|
||||
|
@ -289,6 +289,9 @@ static int xilinx_spips_init(SysBusDevice *dev)
|
||||
|
||||
DB_PRINT("inited device model\n");
|
||||
|
||||
s->spi = ssi_create_bus(&dev->qdev, "spi");
|
||||
|
||||
ssi_auto_connect_slaves(DEVICE(s), s->cs_lines, s->spi);
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
for (i = 0; i < NUM_CS_LINES; ++i) {
|
||||
sysbus_init_irq(dev, &s->cs_lines[i]);
|
||||
@ -298,7 +301,6 @@ static int xilinx_spips_init(SysBusDevice *dev)
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
s->irqline = -1;
|
||||
s->spi = ssi_create_bus(&dev->qdev, "spi");
|
||||
|
||||
fifo8_create(&s->rx_fifo, RXFF_A);
|
||||
fifo8_create(&s->tx_fifo, TXFF_A);
|
||||
|
Loading…
Reference in New Issue
Block a user