| Index: hwaccess.c
|
| diff --git a/hwaccess.c b/hwaccess.c
|
| index 2afdad0635d1caf219b11d5b78b2641917bb49ae..61a06a70cdf23f6e4214059a65de355532afcfbd 100644
|
| --- a/hwaccess.c
|
| +++ b/hwaccess.c
|
| @@ -198,3 +198,71 @@ uint32_t mmio_le_readl(void *addr)
|
| {
|
| return le_to_cpu32(mmio_readl(addr));
|
| }
|
| +
|
| +enum mmio_write_type {
|
| + mmio_write_type_b,
|
| + mmio_write_type_w,
|
| + mmio_write_type_l,
|
| +};
|
| +
|
| +struct undo_mmio_write_data {
|
| + void *addr;
|
| + int reg;
|
| + enum mmio_write_type type;
|
| + union {
|
| + uint8_t bdata;
|
| + uint16_t wdata;
|
| + uint32_t ldata;
|
| + };
|
| +};
|
| +
|
| +void undo_mmio_write(void *p)
|
| +{
|
| + struct undo_mmio_write_data *data = p;
|
| + msg_pdbg("Restoring MMIO space at %p\n", data->addr);
|
| + switch (data->type) {
|
| + case mmio_write_type_b:
|
| + mmio_writeb(data->bdata, data->addr);
|
| + break;
|
| + case mmio_write_type_w:
|
| + mmio_writew(data->wdata, data->addr);
|
| + break;
|
| + case mmio_write_type_l:
|
| + mmio_writel(data->ldata, data->addr);
|
| + break;
|
| + }
|
| + /* p was allocated in register_undo_mmio_write. */
|
| + free(p);
|
| +}
|
| +
|
| +#define register_undo_mmio_write(a, c) \
|
| +{ \
|
| + struct undo_mmio_write_data *undo_mmio_write_data; \
|
| + undo_mmio_write_data = malloc(sizeof(struct undo_mmio_write_data)); \
|
| + undo_mmio_write_data->addr = a; \
|
| + undo_mmio_write_data->type = mmio_write_type_##c; \
|
| + undo_mmio_write_data->c##data = mmio_read##c(a); \
|
| + register_shutdown(undo_mmio_write, undo_mmio_write_data); \
|
| +}
|
| +
|
| +#define register_undo_mmio_writeb(a) register_undo_mmio_write(a, b)
|
| +#define register_undo_mmio_writew(a) register_undo_mmio_write(a, w)
|
| +#define register_undo_mmio_writel(a) register_undo_mmio_write(a, l)
|
| +
|
| +void rmmio_writeb(uint8_t val, void *addr)
|
| +{
|
| + register_undo_mmio_writeb(addr);
|
| + mmio_writeb(val, addr);
|
| +}
|
| +
|
| +void rmmio_writew(uint16_t val, void *addr)
|
| +{
|
| + register_undo_mmio_writew(addr);
|
| + mmio_writew(val, addr);
|
| +}
|
| +
|
| +void rmmio_writel(uint32_t val, void *addr)
|
| +{
|
| + register_undo_mmio_writel(addr);
|
| + mmio_writel(val, addr);
|
| +}
|
|
|