return -ENODEV;
}
- dsp_clk_autoidle();
-
#if defined(CONFIG_ARCH_OMAP1)
dsp_ck_handle = clk_get(NULL, "dsp_ck");
if (IS_ERR(dsp_ck_handle)) {
}
#if defined(CONFIG_ARCH_OMAP1)
-static int dsp_late_init(void)
+static int __dsp_late_init(void)
{
clk_disable(api_ck_handle);
return 0;
}
-late_initcall(dsp_late_init);
+late_initcall(__dsp_late_init);
#endif
static void dsp_cpustat_update(void)
struct omap_mbox *mbox;
struct device *dev;
struct list_head *kdev_list;
+ int initialized;
};
#if defined(CONFIG_ARCH_OMAP1)
extern struct omap_dsp *omap_dsp;
+extern int dsp_late_init(void);
+
#endif /* DRIVER_DSP_COMMON_H */
static u16 mbseq_expect_tmp;
static u16 *mbseq_expect = &mbseq_expect_tmp;
+extern void dsp_mem_late_init(void);
+
/*
* mailbox commands
*/
}
}
+int dsp_late_init(void)
+{
+ int ret;
+
+ dsp_clk_autoidle();
+
+#ifdef CONFIG_ARCH_OMAP2
+ clk_enable(dsp_fck_handle);
+ clk_enable(dsp_ick_handle);
+ __dsp_per_enable();
+#endif
+ dsp_mem_late_init();
+
+#ifdef CONFIG_ARCH_OMAP1
+ dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
+#endif
+ ret = dsp_kfunc_enable_devices(omap_dsp,
+ DSP_KFUNC_DEV_TYPE_COMMON, 0);
+ if (ret == 0)
+ omap_dsp->enabled = 0;
+
+ return 0;
+}
+
extern int dsp_ctl_core_init(void);
extern void dsp_ctl_core_exit(void);
extern void dsp_ctl_init(void);
goto fail1;
}
-#ifdef CONFIG_ARCH_OMAP2
- clk_enable(dsp_fck_handle);
- clk_enable(dsp_ick_handle);
- __dsp_per_enable();
-#endif
-
if ((ret = dsp_ctl_core_init()) < 0)
goto fail2;
if ((ret = dsp_mem_init()) < 0)
fail3:
dsp_ctl_core_exit();
fail2:
-#ifdef CONFIG_ARCH_OMAP2
- __dsp_per_disable();
- clk_disable(dsp_ick_handle);
- clk_disable(dsp_fck_handle);
-#endif
fail1:
dsp_kfunc_remove_devices(info);
fail0:
static int dsp_ctl_core_open(struct inode *inode, struct file *file)
{
+ static DEFINE_MUTEX(open_lock);
+ int ret = 0;
+
+ mutex_lock_interruptible(&open_lock);
+ if (omap_dsp->initialized == 0) {
+ ret = dsp_late_init();
+ if (ret != 0) {
+ mutex_unlock(&open_lock);
+ return ret;
+ }
+ omap_dsp->initialized = 1;
+ }
+ mutex_unlock(&open_lock);
+
switch (iminor(inode)) {
case CTL_MINOR:
file->f_op = &dsp_ctl_fops;
#endif
}
-static char devid_mmu;
-
-int __init dsp_mem_init(void)
+/*
+ * later half of dsp memory initialization
+ */
+void dsp_mem_late_init(void)
{
- int i;
- int ret = 0;
#ifdef CONFIG_ARCH_OMAP2
+ int i;
int dspmem_pg_count;
dspmem_pg_count = dspmem_size >> 12;
for (i = 0; i < dspmem_pg_count; i++) {
dsp_ipi_write_reg(i, DSP_IPI_INDEX);
- dsp_ipi_write_reg(DSP_IPI_ENTRY_ELMSIZEVALUE_16, DSP_IPI_ENTRY);
+ dsp_ipi_write_reg(DSP_IPI_ENTRY_ELMSIZEVALUE_16,
+ DSP_IPI_ENTRY);
}
dsp_ipi_write_reg(1, DSP_IPI_ENABLE);
-
dsp_ipi_write_reg(IOMAP_VAL, DSP_IPI_IOMAP);
#endif
+ dsp_mmu_init();
+}
+
+static char devid_mmu;
+
+int __init dsp_mem_init(void)
+{
+ int i, ret;
for (i = 0; i < DSP_MMU_TLB_LINES; i++)
exmap_tbl[i].valid = 0;
"for dsp vector table\n");
return -ENOMEM;
}
- dsp_mmu_init();
-#ifdef CONFIG_ARCH_OMAP1
- dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
-#endif
/*
* DSP MMU interrupt setup
if (ret) {
printk(KERN_ERR
"failed to register DSP MMU interrupt: %d\n", ret);
- goto fail;
+ return ret;
}
/* MMU interrupt is not enabled until DSP runs */
device_create_file(omap_dsp->dev, &dev_attr_mempool);
return 0;
-
-fail:
-#ifdef CONFIG_ARCH_OMAP1
- dsp_reset_idle_boot_base();
-#endif
- dsp_mmu_shutdown();
- free_page((unsigned long)dspvect_page);
- dspvect_page = NULL;
- return ret;
}
void dsp_mem_exit(void)