ssi: change ssi_slave_init to be a realize ops

This enables qemu to handle late inits and report errors. All the SSI
slave routine names were changed accordingly. Code was modified to
handle errors when possible (m25p80 and ssi-sd)

Tested with the m25p80 slave object.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 1467138270-32481-2-git-send-email-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Cédric Le Goater 2016-07-04 13:06:37 +01:00 committed by Peter Maydell
parent f4b99537f1
commit 7673bb4cd3
10 changed files with 32 additions and 42 deletions

View File

@ -598,15 +598,13 @@ static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
return 0;
}
static int spitz_lcdtg_init(SSISlave *dev)
static void spitz_lcdtg_realize(SSISlave *dev, Error **errp)
{
SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
spitz_lcdtg = s;
s->bl_power = 0;
s->bl_intensity = 0x20;
return 0;
}
/* SSP devices */
@ -666,7 +664,7 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
}
static int corgi_ssp_init(SSISlave *d)
static void corgi_ssp_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
@ -675,8 +673,6 @@ static int corgi_ssp_init(SSISlave *d)
s->bus[0] = ssi_create_bus(dev, "ssi0");
s->bus[1] = ssi_create_bus(dev, "ssi1");
s->bus[2] = ssi_create_bus(dev, "ssi2");
return 0;
}
static void spitz_ssp_attach(PXA2xxState *cpu)
@ -1121,7 +1117,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = corgi_ssp_init;
k->realize = corgi_ssp_realize;
k->transfer = corgi_ssp_transfer;
dc->vmsd = &vmstate_corgi_ssp_regs;
}
@ -1150,7 +1146,7 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = spitz_lcdtg_init;
k->realize = spitz_lcdtg_realize;
k->transfer = spitz_lcdtg_transfer;
dc->vmsd = &vmstate_spitz_lcdtg_regs;
}

View File

@ -127,10 +127,9 @@ static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
return 0;
}
static int tosa_ssp_init(SSISlave *dev)
static void tosa_ssp_realize(SSISlave *dev, Error **errp)
{
/* Nothing to do. */
return 0;
}
#define TYPE_TOSA_DAC "tosa_dac"
@ -283,7 +282,7 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = tosa_ssp_init;
k->realize = tosa_ssp_realize;
k->transfer = tosa_ssp_tansfer;
}

View File

@ -151,14 +151,12 @@ static void z2_lcd_cs(void *opaque, int line, int level)
z2_lcd->selected = !level;
}
static int zipit_lcd_init(SSISlave *dev)
static void zipit_lcd_realize(SSISlave *dev, Error **errp)
{
ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
z->selected = 0;
z->enabled = 0;
z->pos = 0;
return 0;
}
static VMStateDescription vmstate_zipit_lcd_state = {
@ -181,7 +179,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = zipit_lcd_init;
k->realize = zipit_lcd_realize;
k->transfer = zipit_lcd_transfer;
dc->vmsd = &vmstate_zipit_lcd_state;
}

View File

@ -28,6 +28,7 @@
#include "hw/ssi/ssi.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qapi/error.h"
#ifndef M25P80_ERR_DEBUG
#define M25P80_ERR_DEBUG 0
@ -1132,7 +1133,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
return r;
}
static int m25p80_init(SSISlave *ss)
static void m25p80_realize(SSISlave *ss, Error **errp)
{
DriveInfo *dinfo;
Flash *s = M25P80(ss);
@ -1153,18 +1154,15 @@ static int m25p80_init(SSISlave *ss)
s->storage = blk_blockalign(s->blk, s->size);
/* FIXME: Move to late init */
if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
fprintf(stderr, "Failed to initialize SPI flash!\n");
return 1;
error_setg(errp, "failed to read the initial flash content");
return;
}
} else {
DB_PRINT_L(0, "No BDRV - binding to RAM\n");
s->storage = blk_blockalign(NULL, s->size);
memset(s->storage, 0xFF, s->size);
}
return 0;
}
static void m25p80_reset(DeviceState *d)
@ -1224,7 +1222,7 @@ static void m25p80_class_init(ObjectClass *klass, void *data)
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
M25P80Class *mc = M25P80_CLASS(klass);
k->init = m25p80_init;
k->realize = m25p80_realize;
k->transfer = m25p80_transfer8;
k->set_cs = m25p80_cs;
k->cs_polarity = SSI_CS_LOW;

View File

@ -133,7 +133,7 @@ static const VMStateDescription vmstate_ads7846 = {
}
};
static int ads7846_init(SSISlave *d)
static void ads7846_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
@ -152,14 +152,13 @@ static int ads7846_init(SSISlave *d)
ads7846_int_update(s);
vmstate_register(NULL, -1, &vmstate_ads7846, s);
return 0;
}
static void ads7846_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = ads7846_init;
k->realize = ads7846_realize;
k->transfer = ads7846_transfer;
}

View File

@ -361,7 +361,7 @@ static const GraphicHwOps ssd0323_ops = {
.gfx_update = ssd0323_update_display,
};
static int ssd0323_init(SSISlave *d)
static void ssd0323_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
@ -375,14 +375,13 @@ static int ssd0323_init(SSISlave *d)
register_savevm(dev, "ssd0323_oled", -1, 1,
ssd0323_save, ssd0323_load, s);
return 0;
}
static void ssd0323_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = ssd0323_init;
k->realize = ssd0323_realize;
k->transfer = ssd0323_transfer;
k->cs_polarity = SSI_CS_HIGH;
}

View File

@ -147,14 +147,14 @@ static int max111x_init(SSISlave *d, int inputs)
return 0;
}
static int max1110_init(SSISlave *dev)
static void max1110_realize(SSISlave *dev, Error **errp)
{
return max111x_init(dev, 8);
max111x_init(dev, 8);
}
static int max1111_init(SSISlave *dev)
static void max1111_realize(SSISlave *dev, Error **errp)
{
return max111x_init(dev, 4);
max111x_init(dev, 4);
}
void max111x_set_input(DeviceState *dev, int line, uint8_t value)
@ -183,7 +183,7 @@ static void max1110_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = max1110_init;
k->realize = max1110_realize;
}
static const TypeInfo max1110_info = {
@ -196,7 +196,7 @@ static void max1111_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = max1111_init;
k->realize = max1111_realize;
}
static const TypeInfo max1111_info = {

View File

@ -15,6 +15,7 @@
#include "sysemu/blockdev.h"
#include "hw/ssi/ssi.h"
#include "hw/sd/sd.h"
#include "qapi/error.h"
//#define DEBUG_SSI_SD 1
@ -249,7 +250,7 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
static int ssi_sd_init(SSISlave *d)
static void ssi_sd_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
@ -260,17 +261,17 @@ static int ssi_sd_init(SSISlave *d)
dinfo = drive_get_next(IF_SD);
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
if (s->sd == NULL) {
return -1;
error_setg(errp, "Device initialization failed.");
return;
}
register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
return 0;
}
static void ssi_sd_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = ssi_sd_init;
k->realize = ssi_sd_realize;
k->transfer = ssi_sd_transfer;
k->cs_polarity = SSI_CS_LOW;
}

View File

@ -54,7 +54,7 @@ static uint32_t ssi_transfer_raw_default(SSISlave *dev, uint32_t val)
return 0;
}
static int ssi_slave_init(DeviceState *dev)
static void ssi_slave_realize(DeviceState *dev, Error **errp)
{
SSISlave *s = SSI_SLAVE(dev);
SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
@ -64,7 +64,7 @@ static int ssi_slave_init(DeviceState *dev)
qdev_init_gpio_in_named(dev, ssi_cs_default, SSI_GPIO_CS, 1);
}
return ssc->init(s);
ssc->realize(s, errp);
}
static void ssi_slave_class_init(ObjectClass *klass, void *data)
@ -72,7 +72,7 @@ static void ssi_slave_class_init(ObjectClass *klass, void *data)
SSISlaveClass *ssc = SSI_SLAVE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
dc->init = ssi_slave_init;
dc->realize = ssi_slave_realize;
dc->bus_type = TYPE_SSI_BUS;
if (!ssc->transfer_raw) {
ssc->transfer_raw = ssi_transfer_raw_default;

View File

@ -37,7 +37,7 @@ enum SSICSMode {
struct SSISlaveClass {
DeviceClass parent_class;
int (*init)(SSISlave *dev);
void (*realize)(SSISlave *dev, Error **errp);
/* if you have standard or no CS behaviour, just override transfer.
* This is called when the device cs is active (true by default).