Commit c701b35b42d50537122486e47006d1c6ce952240

Authored by pbrook
1 parent 75f482ae

Fix i2c save/restore.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4820 c046a42c-6fe2-441c-8c8c-71466251a162
hw/i2c.c
@@ -14,14 +14,38 @@ struct i2c_bus @@ -14,14 +14,38 @@ struct i2c_bus
14 { 14 {
15 i2c_slave *current_dev; 15 i2c_slave *current_dev;
16 i2c_slave *dev; 16 i2c_slave *dev;
  17 + int saved_address;
17 }; 18 };
18 19
  20 +static void i2c_bus_save(QEMUFile *f, void *opaque)
  21 +{
  22 + i2c_bus *bus = (i2c_bus *)opaque;
  23 +
  24 + qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : -1);
  25 +}
  26 +
  27 +static int i2c_bus_load(QEMUFile *f, void *opaque, int version_id)
  28 +{
  29 + i2c_bus *bus = (i2c_bus *)opaque;
  30 +
  31 + if (version_id != 1)
  32 + return -EINVAL;
  33 +
  34 + /* The bus is loaded before attached devices, so load and save the
  35 + current device id. Devices will check themselves as loaded. */
  36 + bus->saved_address = qemu_get_be32(f);
  37 + bus->current_dev = NULL;
  38 +
  39 + return 0;
  40 +}
  41 +
19 /* Create a new I2C bus. */ 42 /* Create a new I2C bus. */
20 i2c_bus *i2c_init_bus(void) 43 i2c_bus *i2c_init_bus(void)
21 { 44 {
22 i2c_bus *bus; 45 i2c_bus *bus;
23 46
24 bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus)); 47 bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
  48 + register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus);
25 return bus; 49 return bus;
26 } 50 }
27 51
@@ -37,6 +61,7 @@ i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size) @@ -37,6 +61,7 @@ i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size)
37 dev->address = address; 61 dev->address = address;
38 dev->next = bus->dev; 62 dev->next = bus->dev;
39 bus->dev = dev; 63 bus->dev = dev;
  64 + dev->bus = bus;
40 65
41 return dev; 66 return dev;
42 } 67 }
@@ -115,28 +140,6 @@ void i2c_nack(i2c_bus *bus) @@ -115,28 +140,6 @@ void i2c_nack(i2c_bus *bus)
115 dev->event(dev, I2C_NACK); 140 dev->event(dev, I2C_NACK);
116 } 141 }
117 142
118 -void i2c_bus_save(QEMUFile *f, i2c_bus *bus)  
119 -{  
120 - qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00);  
121 -}  
122 -  
123 -void i2c_bus_load(QEMUFile *f, i2c_bus *bus)  
124 -{  
125 - i2c_slave *dev;  
126 - uint8_t address = qemu_get_byte(f);  
127 -  
128 - if (address) {  
129 - for (dev = bus->dev; dev; dev = dev->next)  
130 - if (dev->address == address) {  
131 - bus->current_dev = dev;  
132 - return;  
133 - }  
134 -  
135 - fprintf(stderr, "%s: I2C slave with address %02x disappeared\n",  
136 - __FUNCTION__, address);  
137 - }  
138 -}  
139 -  
140 void i2c_slave_save(QEMUFile *f, i2c_slave *dev) 143 void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
141 { 144 {
142 qemu_put_byte(f, dev->address); 145 qemu_put_byte(f, dev->address);
@@ -145,4 +148,6 @@ void i2c_slave_save(QEMUFile *f, i2c_slave *dev) @@ -145,4 +148,6 @@ void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
145 void i2c_slave_load(QEMUFile *f, i2c_slave *dev) 148 void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
146 { 149 {
147 dev->address = qemu_get_byte(f); 150 dev->address = qemu_get_byte(f);
  151 + if (dev->bus->saved_address == dev->address)
  152 + dev->bus->current_dev = dev;
148 } 153 }
hw/i2c.h
@@ -30,6 +30,7 @@ struct i2c_slave @@ -30,6 +30,7 @@ struct i2c_slave
30 /* Remaining fields for internal use by the I2C code. */ 30 /* Remaining fields for internal use by the I2C code. */
31 int address; 31 int address;
32 void *next; 32 void *next;
  33 + i2c_bus *bus;
33 }; 34 };
34 35
35 i2c_bus *i2c_init_bus(void); 36 i2c_bus *i2c_init_bus(void);
@@ -41,8 +42,6 @@ void i2c_end_transfer(i2c_bus *bus); @@ -41,8 +42,6 @@ void i2c_end_transfer(i2c_bus *bus);
41 void i2c_nack(i2c_bus *bus); 42 void i2c_nack(i2c_bus *bus);
42 int i2c_send(i2c_bus *bus, uint8_t data); 43 int i2c_send(i2c_bus *bus, uint8_t data);
43 int i2c_recv(i2c_bus *bus); 44 int i2c_recv(i2c_bus *bus);
44 -void i2c_bus_save(QEMUFile *f, i2c_bus *bus);  
45 -void i2c_bus_load(QEMUFile *f, i2c_bus *bus);  
46 void i2c_slave_save(QEMUFile *f, i2c_slave *dev); 45 void i2c_slave_save(QEMUFile *f, i2c_slave *dev);
47 void i2c_slave_load(QEMUFile *f, i2c_slave *dev); 46 void i2c_slave_load(QEMUFile *f, i2c_slave *dev);
48 47
hw/pxa2xx.c
@@ -1466,7 +1466,6 @@ static void pxa2xx_i2c_save(QEMUFile *f, void *opaque) @@ -1466,7 +1466,6 @@ static void pxa2xx_i2c_save(QEMUFile *f, void *opaque)
1466 qemu_put_8s(f, &s->ibmr); 1466 qemu_put_8s(f, &s->ibmr);
1467 qemu_put_8s(f, &s->data); 1467 qemu_put_8s(f, &s->data);
1468 1468
1469 - i2c_bus_save(f, s->bus);  
1470 i2c_slave_save(f, &s->slave); 1469 i2c_slave_save(f, &s->slave);
1471 } 1470 }
1472 1471
@@ -1474,12 +1473,14 @@ static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id) @@ -1474,12 +1473,14 @@ static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id)
1474 { 1473 {
1475 struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque; 1474 struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;
1476 1475
  1476 + if (version_id != 1)
  1477 + return -EINVAL;
  1478 +
1477 qemu_get_be16s(f, &s->control); 1479 qemu_get_be16s(f, &s->control);
1478 qemu_get_be16s(f, &s->status); 1480 qemu_get_be16s(f, &s->status);
1479 qemu_get_8s(f, &s->ibmr); 1481 qemu_get_8s(f, &s->ibmr);
1480 qemu_get_8s(f, &s->data); 1482 qemu_get_8s(f, &s->data);
1481 1483
1482 - i2c_bus_load(f, s->bus);  
1483 i2c_slave_load(f, &s->slave); 1484 i2c_slave_load(f, &s->slave);
1484 return 0; 1485 return 0;
1485 } 1486 }
@@ -1488,6 +1489,7 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, @@ -1488,6 +1489,7 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
1488 qemu_irq irq, uint32_t page_size) 1489 qemu_irq irq, uint32_t page_size)
1489 { 1490 {
1490 int iomemtype; 1491 int iomemtype;
  1492 + /* FIXME: Should the slave device really be on a separate bus? */
1491 struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) 1493 struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *)
1492 i2c_slave_init(i2c_init_bus(), 0, sizeof(struct pxa2xx_i2c_s)); 1494 i2c_slave_init(i2c_init_bus(), 0, sizeof(struct pxa2xx_i2c_s));
1493 1495
@@ -1502,7 +1504,7 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, @@ -1502,7 +1504,7 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
1502 pxa2xx_i2c_writefn, s); 1504 pxa2xx_i2c_writefn, s);
1503 cpu_register_physical_memory(s->base & ~page_size, page_size, iomemtype); 1505 cpu_register_physical_memory(s->base & ~page_size, page_size, iomemtype);
1504 1506
1505 - register_savevm("pxa2xx_i2c", base, 0, 1507 + register_savevm("pxa2xx_i2c", base, 1,
1506 pxa2xx_i2c_save, pxa2xx_i2c_load, s); 1508 pxa2xx_i2c_save, pxa2xx_i2c_load, s);
1507 1509
1508 return s; 1510 return s;