diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index cceab3e..8de8625 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -179,7 +179,7 @@ static const MemoryRegionOps PPC_XCSR_ops = {
 /* Fake super-io ports for PREP platform (Intel 82378ZB) */
 typedef struct sysctrl_t {
     qemu_irq reset_irq;
-    M48t59State *nvram;
+    DeviceState *nvram;
     uint8_t state;
     uint8_t syscontrol;
     int contiguous_map;
@@ -233,12 +233,12 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
     case 0x0810:
         /* Password protect 1 register */
         if (sysctrl->nvram != NULL)
-            m48t59_toggle_lock(sysctrl->nvram, 1);
+            m48txx_toggle_lock(sysctrl->nvram, 1);
         break;
     case 0x0812:
         /* Password protect 2 register */
         if (sysctrl->nvram != NULL)
-            m48t59_toggle_lock(sysctrl->nvram, 2);
+            m48txx_toggle_lock(sysctrl->nvram, 2);
         break;
     case 0x0814:
         /* L2 invalidate register */
@@ -443,7 +443,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     CPUPPCState *env = NULL;
     char *filename;
     nvram_t nvram;
-    M48t59State *m48t59;
+    DeviceState *m48t59;
     MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);
 #if 0
     MemoryRegion *xcsr = g_new(MemoryRegion, 1);
@@ -646,8 +646,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
 
     /* Initialise NVRAM */
     nvram.opaque = m48t59;
-    nvram.read_fn = &m48t59_read;
-    nvram.write_fn = &m48t59_write;
+    nvram.read_fn = &m48txx_read;
+    nvram.write_fn = &m48txx_write;
     PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,
                          kernel_base, kernel_size,
                          kernel_cmdline,
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 31beb32..7ba4576 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -167,7 +167,7 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
     return 0;
 }
 
-static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
+static void nvram_init(DeviceState *nvram, uint8_t *macaddr,
                        const char *cmdline, const char *boot_devices,
                        ram_addr_t RAM_size, uint32_t kernel_size,
                        int width, int height, int depth,
@@ -211,7 +211,7 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
                     nvram_machine_id);
 
     for (i = 0; i < sizeof(image); i++)
-        m48t59_write(nvram, i, image[i]);
+        m48txx_write(nvram, i, image[i]);
 }
 
 static DeviceState *slavio_intctl;
@@ -866,7 +866,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
                           const char *initrd_filename, const char *cpu_model)
 {
     unsigned int i;
-    void *iommu, *espdma, *ledma, *nvram;
+    void *iommu, *espdma, *ledma;
+    DeviceState *nvram;
     qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
         espdma_irq, ledma_irq;
     qemu_irq esp_reset, dma_enable;
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 0d29620..0197bfc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -130,7 +130,7 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
     return 0;
 }
 
-static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
+static int sun4u_NVRAM_set_params(DeviceState *nvram, uint16_t NVRAM_size,
                                   const char *arch, ram_addr_t RAM_size,
                                   const char *boot_devices,
                                   uint32_t kernel_image, uint32_t kernel_size,
@@ -177,7 +177,7 @@ static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
     Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80);
 
     for (i = 0; i < sizeof(image); i++)
-        m48t59_write(nvram, i, image[i]);
+        m48txx_write(nvram, i, image[i]);
 
     return 0;
 }
@@ -810,7 +810,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
                         const struct hwdef *hwdef)
 {
     SPARCCPU *cpu;
-    M48t59State *nvram;
+    DeviceState *nvram;
     unsigned int i;
     uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 29ec462..afcd5f5 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -222,9 +222,8 @@ static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
 }
 
 /* Direct access to NVRAM */
-void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
+static void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
 {
-    M48t59State *NVRAM = opaque;
     struct tm tm;
     int tmp;
 
@@ -392,9 +391,8 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t m48t59_read (void *opaque, uint32_t addr)
+static uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
 {
-    M48t59State *NVRAM = opaque;
     struct tm tm;
     uint32_t retval = 0xFF;
 
@@ -501,11 +499,60 @@ uint32_t m48t59_read (void *opaque, uint32_t addr)
     return retval;
 }
 
-void m48t59_toggle_lock (void *opaque, int lock)
+static M48t59State *m48txx_get_state(DeviceState *dev)
 {
-    M48t59State *NVRAM = opaque;
+    Object *o = OBJECT(dev);
+    Object *o2;
+    M48t59SysBusState *sysbus;
+    M48t59ISAState *isa;
+    int i;
 
-    NVRAM->lock ^= 1 << lock;
+    for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
+        if (m48txx_info[i].sysbus_name) {
+            o2 = object_dynamic_cast(o, m48txx_info[i].sysbus_name);
+            if (o2) {
+                sysbus = FROM_SYSBUS(M48t59SysBusState, SYS_BUS_DEVICE(o2));
+                return &sysbus->state;
+            }
+        }
+        if (m48txx_info[i].isa_name) {
+            o2 = object_dynamic_cast(o, m48txx_info[i].isa_name);
+            if (o2) {
+                isa = FROM_SYSBUS(M48t59ISAState, ISA_DEVICE(o2));
+                return &isa->state;
+            }
+        }
+    }
+    return NULL;
+}
+
+void m48txx_write(DeviceState *dev, uint32_t addr, uint32_t val)
+{
+    M48t59State *NVRAM = m48txx_get_state(dev);
+
+    if (NVRAM) {
+        m48t59_write(NVRAM, addr, val);
+    }
+}
+
+uint32_t m48txx_read(DeviceState *dev, uint32_t addr)
+{
+    M48t59State *NVRAM = m48txx_get_state(dev);
+
+    if (NVRAM) {
+        return m48t59_read(NVRAM, addr);
+    } else {
+        return 0;
+    }
+}
+
+void m48txx_toggle_lock(DeviceState *dev, int lock)
+{
+    M48t59State *NVRAM = m48txx_get_state(dev);
+
+    if (NVRAM) {
+        NVRAM->lock ^= 1 << lock;
+    }
 }
 
 /* IO access to NVRAM */
@@ -666,7 +713,7 @@ static const MemoryRegionOps m48t59_io_ops = {
 };
 
 /* Initialisation routine */
-M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+DeviceState *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
                          uint32_t io_base, uint16_t size, int model)
 {
     DeviceState *dev;
@@ -696,19 +743,17 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
             sysbus_mmio_map(s, 0, mem_base);
         }
 
-        return state;
+        return dev;
     }
 
     assert(false);
     return NULL;
 }
 
-M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+DeviceState *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
                              int model)
 {
-    M48t59ISAState *d;
-    ISADevice *dev;
-    M48t59State *s;
+    DeviceState *dev;
     int i;
 
     assert(io_base == 0x74);
@@ -720,12 +765,10 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
             continue;
         }
 
-        dev = isa_create(bus, m48txx_info[i].isa_name);
-        qdev_init_nofail(&dev->qdev);
-        d = DO_UPCAST(M48t59ISAState, busdev, dev);
-        s = &d->state;
+        dev = DEVICE(isa_create(bus, m48txx_info[i].isa_name));
+        qdev_init_nofail(dev);
 
-        return s;
+        return dev;
     }
 
     assert(false);
diff --git a/include/hw/timer/m48t59.h b/include/hw/timer/m48t59.h
index 59337fa..7ec4173 100644
--- a/include/hw/timer/m48t59.h
+++ b/include/hw/timer/m48t59.h
@@ -2,8 +2,8 @@
 #define NVRAM_H
 
 /* NVRAM helpers */
-typedef uint32_t (*nvram_read_t)(void *private, uint32_t addr);
-typedef void (*nvram_write_t)(void *private, uint32_t addr, uint32_t val);
+typedef uint32_t (*nvram_read_t)(DeviceState *dev, uint32_t addr);
+typedef void (*nvram_write_t)(DeviceState *dev, uint32_t addr, uint32_t val);
 typedef struct nvram_t {
     void *opaque;
     nvram_read_t read_fn;
@@ -23,12 +23,12 @@ int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
                           int width, int height, int depth);
 typedef struct M48t59State M48t59State;
 
-void m48t59_write (void *private, uint32_t addr, uint32_t val);
-uint32_t m48t59_read (void *private, uint32_t addr);
-void m48t59_toggle_lock (void *private, int lock);
-M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+void m48txx_write(DeviceState *dev, uint32_t addr, uint32_t val);
+uint32_t m48txx_read(DeviceState *dev, uint32_t addr);
+void m48txx_toggle_lock(DeviceState *dev, int lock);
+DeviceState *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
                              int type);
-M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+DeviceState *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
                          uint32_t io_base, uint16_t size, int type);
 
 #endif /* !NVRAM_H */
