u32 module_size;
        void __iomem *module_va;
        int offsets[SYSC_MAX_REGS];
+       struct ti_sysc_module_data *mdata;
        struct clk **clocks;
        const char **clock_roles;
        int nr_clocks;
        }
 }
 
+/*
+ * Note that pdata->init_module() typically does a reset first. After
+ * pdata->init_module() is done, PM runtime can be used for the interconnect
+ * target module.
+ */
+static int sysc_legacy_init(struct sysc *ddata)
+{
+       struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
+       int error;
+
+       if (!ddata->legacy_mode || !pdata || !pdata->init_module)
+               return 0;
+
+       error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie);
+       if (error == -EEXIST)
+               error = 0;
+
+       return error;
+}
+
 static int sysc_reset(struct sysc *ddata)
 {
        int offset = ddata->offsets[SYSC_SYSCONFIG];
        ddata->revision = sysc_read_revision(ddata);
        sysc_init_revision_quirks(ddata);
 
+       error = sysc_legacy_init(ddata);
+       if (error)
+               goto err_main_clocks;
+
        error = sysc_reset(ddata);
        if (error)
                dev_err(ddata->dev, "Reset failed with %d\n", error);
 
+err_main_clocks:
        if (manage_clocks)
                sysc_disable_main_clocks(ddata);
 err_opt_clocks:
 static int sysc_init_pdata(struct sysc *ddata)
 {
        struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
-       struct ti_sysc_module_data mdata;
-       int error = 0;
+       struct ti_sysc_module_data *mdata;
 
        if (!pdata || !ddata->legacy_mode)
                return 0;
 
-       mdata.name = ddata->legacy_mode;
-       mdata.module_pa = ddata->module_pa;
-       mdata.module_size = ddata->module_size;
-       mdata.offsets = ddata->offsets;
-       mdata.nr_offsets = SYSC_MAX_REGS;
-       mdata.cap = ddata->cap;
-       mdata.cfg = &ddata->cfg;
+       mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL);
+       if (!mdata)
+               return -ENOMEM;
 
-       if (!pdata->init_module)
-               return -ENODEV;
+       mdata->name = ddata->legacy_mode;
+       mdata->module_pa = ddata->module_pa;
+       mdata->module_size = ddata->module_size;
+       mdata->offsets = ddata->offsets;
+       mdata->nr_offsets = SYSC_MAX_REGS;
+       mdata->cap = ddata->cap;
+       mdata->cfg = &ddata->cfg;
 
-       error = pdata->init_module(ddata->dev, &mdata, &ddata->cookie);
-       if (error == -EEXIST)
-               error = 0;
+       ddata->mdata = mdata;
 
-       return error;
+       return 0;
 }
 
 static int sysc_init_match(struct sysc *ddata)