bcast_write(LIMA_BCAST_BROADCAST_MASK, mask);
 }
 
+static int lima_bcast_hw_init(struct lima_ip *ip)
+{
+       bcast_write(LIMA_BCAST_BROADCAST_MASK, ip->data.mask << 16);
+       bcast_write(LIMA_BCAST_INTERRUPT_MASK, ip->data.mask);
+       return 0;
+}
+
+int lima_bcast_resume(struct lima_ip *ip)
+{
+       return lima_bcast_hw_init(ip);
+}
+
+void lima_bcast_suspend(struct lima_ip *ip)
+{
+
+}
+
 int lima_bcast_init(struct lima_ip *ip)
 {
-       int i, mask = 0;
+       int i;
 
        for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) {
                if (ip->dev->ip[i].present)
-                       mask |= 1 << (i - lima_ip_pp0);
+                       ip->data.mask |= 1 << (i - lima_ip_pp0);
        }
 
-       bcast_write(LIMA_BCAST_BROADCAST_MASK, mask << 16);
-       bcast_write(LIMA_BCAST_INTERRUPT_MASK, mask);
-       return 0;
+       return lima_bcast_hw_init(ip);
 }
 
 void lima_bcast_fini(struct lima_ip *ip)
 
 
 struct lima_ip;
 
+int lima_bcast_resume(struct lima_ip *ip);
+void lima_bcast_suspend(struct lima_ip *ip);
 int lima_bcast_init(struct lima_ip *ip);
 void lima_bcast_fini(struct lima_ip *ip);
 
 
 
        int (*init)(struct lima_ip *ip);
        void (*fini)(struct lima_ip *ip);
+       int (*resume)(struct lima_ip *ip);
+       void (*suspend)(struct lima_ip *ip);
 };
 
 #define LIMA_IP_DESC(ipname, mst0, mst1, off0, off1, func, irq) \
                }, \
                .init = lima_##func##_init, \
                .fini = lima_##func##_fini, \
+               .resume = lima_##func##_resume, \
+               .suspend = lima_##func##_suspend, \
        }
 
 static struct lima_ip_desc lima_ip_desc[lima_ip_num] = {
 
                bool async_reset;
                /* l2 cache */
                spinlock_t lock;
-               /* pmu */
+               /* pmu/bcast */
                u32 mask;
        } data;
 };
 
        dlbu_write(LIMA_DLBU_START_TILE_POS, reg[3]);
 }
 
-int lima_dlbu_init(struct lima_ip *ip)
+static int lima_dlbu_hw_init(struct lima_ip *ip)
 {
        struct lima_device *dev = ip->dev;
 
        return 0;
 }
 
+int lima_dlbu_resume(struct lima_ip *ip)
+{
+       return lima_dlbu_hw_init(ip);
+}
+
+void lima_dlbu_suspend(struct lima_ip *ip)
+{
+
+}
+
+int lima_dlbu_init(struct lima_ip *ip)
+{
+       return lima_dlbu_hw_init(ip);
+}
+
 void lima_dlbu_fini(struct lima_ip *ip)
 {
 
 
 
 void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg);
 
+int lima_dlbu_resume(struct lima_ip *ip);
+void lima_dlbu_suspend(struct lima_ip *ip);
 int lima_dlbu_init(struct lima_ip *ip);
 void lima_dlbu_fini(struct lima_ip *ip);
 
 
 static struct kmem_cache *lima_gp_task_slab;
 static int lima_gp_task_slab_refcnt;
 
+static int lima_gp_hw_init(struct lima_ip *ip)
+{
+       ip->data.async_reset = false;
+       lima_gp_soft_reset_async(ip);
+       return lima_gp_soft_reset_async_wait(ip);
+}
+
+int lima_gp_resume(struct lima_ip *ip)
+{
+       return lima_gp_hw_init(ip);
+}
+
+void lima_gp_suspend(struct lima_ip *ip)
+{
+
+}
+
 int lima_gp_init(struct lima_ip *ip)
 {
        struct lima_device *dev = ip->dev;
 
        lima_gp_print_version(ip);
 
-       ip->data.async_reset = false;
-       lima_gp_soft_reset_async(ip);
-       err = lima_gp_soft_reset_async_wait(ip);
+       err = lima_gp_hw_init(ip);
        if (err)
                return err;
 
 
 struct lima_ip;
 struct lima_device;
 
+int lima_gp_resume(struct lima_ip *ip);
+void lima_gp_suspend(struct lima_ip *ip);
 int lima_gp_init(struct lima_ip *ip);
 void lima_gp_fini(struct lima_ip *ip);
 
 
        return ret;
 }
 
+static int lima_l2_cache_hw_init(struct lima_ip *ip)
+{
+       int err;
+
+       err = lima_l2_cache_flush(ip);
+       if (err)
+               return err;
+
+       l2_cache_write(LIMA_L2_CACHE_ENABLE,
+                      LIMA_L2_CACHE_ENABLE_ACCESS |
+                      LIMA_L2_CACHE_ENABLE_READ_ALLOCATE);
+       l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c);
+
+       return 0;
+}
+
+int lima_l2_cache_resume(struct lima_ip *ip)
+{
+       return lima_l2_cache_hw_init(ip);
+}
+
+void lima_l2_cache_suspend(struct lima_ip *ip)
+{
+
+}
+
 int lima_l2_cache_init(struct lima_ip *ip)
 {
-       int i, err;
+       int i;
        u32 size;
        struct lima_device *dev = ip->dev;
 
                 1 << (size & 0xff),
                 1 << ((size >> 24) & 0xff));
 
-       err = lima_l2_cache_flush(ip);
-       if (err)
-               return err;
-
-       l2_cache_write(LIMA_L2_CACHE_ENABLE,
-                      LIMA_L2_CACHE_ENABLE_ACCESS|LIMA_L2_CACHE_ENABLE_READ_ALLOCATE);
-       l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c);
-
-       return 0;
+       return lima_l2_cache_hw_init(ip);
 }
 
 void lima_l2_cache_fini(struct lima_ip *ip)
 
 
 struct lima_ip;
 
+int lima_l2_cache_resume(struct lima_ip *ip);
+void lima_l2_cache_suspend(struct lima_ip *ip);
 int lima_l2_cache_init(struct lima_ip *ip);
 void lima_l2_cache_fini(struct lima_ip *ip);
 
 
        return IRQ_HANDLED;
 }
 
-int lima_mmu_init(struct lima_ip *ip)
+static int lima_mmu_hw_init(struct lima_ip *ip)
 {
        struct lima_device *dev = ip->dev;
        int err;
        u32 v;
 
+       mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET);
+       err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET,
+                                   LIMA_MMU_DTE_ADDR, v, v == 0);
+       if (err)
+               return err;
+
+       mmu_write(LIMA_MMU_INT_MASK,
+                 LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
+       mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma);
+       return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
+                                    LIMA_MMU_STATUS, v,
+                                    v & LIMA_MMU_STATUS_PAGING_ENABLED);
+}
+
+int lima_mmu_resume(struct lima_ip *ip)
+{
+       if (ip->id == lima_ip_ppmmu_bcast)
+               return 0;
+
+       return lima_mmu_hw_init(ip);
+}
+
+void lima_mmu_suspend(struct lima_ip *ip)
+{
+
+}
+
+int lima_mmu_init(struct lima_ip *ip)
+{
+       struct lima_device *dev = ip->dev;
+       int err;
+
        if (ip->id == lima_ip_ppmmu_bcast)
                return 0;
 
                return -EIO;
        }
 
-       mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET);
-       err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET,
-                                   LIMA_MMU_DTE_ADDR, v, v == 0);
-       if (err)
-               return err;
-
        err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler,
                               IRQF_SHARED, lima_ip_name(ip), ip);
        if (err) {
                return err;
        }
 
-       mmu_write(LIMA_MMU_INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
-       mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma);
-       return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
-                                    LIMA_MMU_STATUS, v,
-                                    v & LIMA_MMU_STATUS_PAGING_ENABLED);
+       return lima_mmu_hw_init(ip);
 }
 
 void lima_mmu_fini(struct lima_ip *ip)
 
 struct lima_ip;
 struct lima_vm;
 
+int lima_mmu_resume(struct lima_ip *ip);
+void lima_mmu_suspend(struct lima_ip *ip);
 int lima_mmu_init(struct lima_ip *ip);
 void lima_mmu_fini(struct lima_ip *ip);
 
 
        return ret;
 }
 
-int lima_pmu_init(struct lima_ip *ip)
+static int lima_pmu_hw_init(struct lima_ip *ip)
 {
        int err;
        u32 stat;
        return 0;
 }
 
-void lima_pmu_fini(struct lima_ip *ip)
+static void lima_pmu_hw_fini(struct lima_ip *ip)
 {
        u32 stat;
 
                        lima_pmu_wait_cmd(ip);
        }
 }
+
+int lima_pmu_resume(struct lima_ip *ip)
+{
+       return lima_pmu_hw_init(ip);
+}
+
+void lima_pmu_suspend(struct lima_ip *ip)
+{
+       lima_pmu_hw_fini(ip);
+}
+
+int lima_pmu_init(struct lima_ip *ip)
+{
+       return lima_pmu_hw_init(ip);
+}
+
+void lima_pmu_fini(struct lima_ip *ip)
+{
+       lima_pmu_hw_fini(ip);
+}
 
 
 struct lima_ip;
 
+int lima_pmu_resume(struct lima_ip *ip);
+void lima_pmu_suspend(struct lima_ip *ip);
 int lima_pmu_init(struct lima_ip *ip);
 void lima_pmu_fini(struct lima_ip *ip);
 
 
                 lima_ip_name(ip), name, major, minor);
 }
 
+static int lima_pp_hw_init(struct lima_ip *ip)
+{
+       ip->data.async_reset = false;
+       lima_pp_soft_reset_async(ip);
+       return lima_pp_soft_reset_async_wait(ip);
+}
+
+int lima_pp_resume(struct lima_ip *ip)
+{
+       return lima_pp_hw_init(ip);
+}
+
+void lima_pp_suspend(struct lima_ip *ip)
+{
+
+}
+
 int lima_pp_init(struct lima_ip *ip)
 {
        struct lima_device *dev = ip->dev;
 
        lima_pp_print_version(ip);
 
-       ip->data.async_reset = false;
-       lima_pp_soft_reset_async(ip);
-       err = lima_pp_soft_reset_async_wait(ip);
+       err = lima_pp_hw_init(ip);
        if (err)
                return err;
 
 
 }
 
+int lima_pp_bcast_resume(struct lima_ip *ip)
+{
+       return 0;
+}
+
+void lima_pp_bcast_suspend(struct lima_ip *ip)
+{
+
+}
+
 int lima_pp_bcast_init(struct lima_ip *ip)
 {
        struct lima_device *dev = ip->dev;
 
 struct lima_ip;
 struct lima_device;
 
+int lima_pp_resume(struct lima_ip *ip);
+void lima_pp_suspend(struct lima_ip *ip);
 int lima_pp_init(struct lima_ip *ip);
 void lima_pp_fini(struct lima_ip *ip);
 
+int lima_pp_bcast_resume(struct lima_ip *ip);
+void lima_pp_bcast_suspend(struct lima_ip *ip);
 int lima_pp_bcast_init(struct lima_ip *ip);
 void lima_pp_bcast_fini(struct lima_ip *ip);