Commit 82873734 authored by Hiroshi DOYU's avatar Hiroshi DOYU Committed by Tony Lindgren

OMAP: DSP: N800: remaining updates for dsp parts

Signed-off-by: default avatarHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 19890e58
...@@ -50,7 +50,7 @@ static struct dsp_kfunc_device n800_audio_device = { ...@@ -50,7 +50,7 @@ static struct dsp_kfunc_device n800_audio_device = {
/* /*
* dsp peripheral device: TIMER * dsp peripheral device: TIMER
*/ */
static int dsp_timer_probe(struct dsp_kfunc_device *kdev) static int dsp_timer_probe(struct dsp_kfunc_device *kdev, int stage)
{ {
char clockname[20]; char clockname[20];
...@@ -80,7 +80,7 @@ static int dsp_timer_probe(struct dsp_kfunc_device *kdev) ...@@ -80,7 +80,7 @@ static int dsp_timer_probe(struct dsp_kfunc_device *kdev)
return PTR_ERR(kdev->ick); return PTR_ERR(kdev->ick);
} }
static int dsp_timer_remove(struct dsp_kfunc_device *kdev) static int dsp_timer_remove(struct dsp_kfunc_device *kdev, int stage)
{ {
clk_put(kdev->ick); clk_put(kdev->ick);
clk_put(kdev->fck); clk_put(kdev->fck);
...@@ -92,7 +92,7 @@ static int dsp_timer_enable(struct dsp_kfunc_device *kdev, int stage) ...@@ -92,7 +92,7 @@ static int dsp_timer_enable(struct dsp_kfunc_device *kdev, int stage)
{ {
pr_debug("%s enabled(%d)\n", kdev->name, stage); pr_debug("%s enabled(%d)\n", kdev->name, stage);
mutex_lock(&kdev->lock); spin_lock(&kdev->lock);
if (kdev->enabled) if (kdev->enabled)
goto out; goto out;
...@@ -101,7 +101,7 @@ static int dsp_timer_enable(struct dsp_kfunc_device *kdev, int stage) ...@@ -101,7 +101,7 @@ static int dsp_timer_enable(struct dsp_kfunc_device *kdev, int stage)
clk_enable(kdev->fck); clk_enable(kdev->fck);
clk_enable(kdev->ick); clk_enable(kdev->ick);
out: out:
mutex_unlock(&kdev->lock); spin_unlock(&kdev->lock);
return 0; return 0;
} }
...@@ -110,7 +110,7 @@ static int dsp_timer_disable(struct dsp_kfunc_device *kdev, int stage) ...@@ -110,7 +110,7 @@ static int dsp_timer_disable(struct dsp_kfunc_device *kdev, int stage)
{ {
pr_debug("%s disabled(%d)\n", kdev->name, stage); pr_debug("%s disabled(%d)\n", kdev->name, stage);
mutex_lock(&kdev->lock); spin_lock(&kdev->lock);
if (kdev->enabled == 0) if (kdev->enabled == 0)
goto out; goto out;
...@@ -119,7 +119,7 @@ static int dsp_timer_disable(struct dsp_kfunc_device *kdev, int stage) ...@@ -119,7 +119,7 @@ static int dsp_timer_disable(struct dsp_kfunc_device *kdev, int stage)
clk_disable(kdev->ick); clk_disable(kdev->ick);
clk_disable(kdev->fck); clk_disable(kdev->fck);
out: out:
mutex_unlock(&kdev->lock); spin_unlock(&kdev->lock);
return 0; return 0;
} }
......
...@@ -74,7 +74,7 @@ int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev) ...@@ -74,7 +74,7 @@ int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
{ {
static DEFINE_MUTEX(dsp_pdata_lock); static DEFINE_MUTEX(dsp_pdata_lock);
mutex_init(&kdev->lock); spin_lock_init(&kdev->lock);
mutex_lock(&dsp_pdata_lock); mutex_lock(&dsp_pdata_lock);
list_add_tail(&kdev->entry, &dsp_pdata.kdev_list); list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
......
...@@ -23,7 +23,7 @@ config OMAP_DSP_TASK_MULTIOPEN ...@@ -23,7 +23,7 @@ config OMAP_DSP_TASK_MULTIOPEN
config OMAP_DSP_FBEXPORT config OMAP_DSP_FBEXPORT
bool "Framebuffer export to DSP" bool "Framebuffer export to DSP"
depends on OMAP_DSP depends on OMAP_DSP && FB
help help
This enables to map the frame buffer to DSP. This enables to map the frame buffer to DSP.
By doing this, DSP can access the frame buffer directly without By doing this, DSP can access the frame buffer directly without
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* *
*/ */
#ifndef __PLAT_OMAP_DSP_DSP_H
#define __PLAT_OMAP_DSP_DSP_H
#include "hardware_dsp.h" #include "hardware_dsp.h"
#include "dsp_common.h" #include "dsp_common.h"
#include <asm/arch/mmu.h> #include <asm/arch/mmu.h>
...@@ -129,7 +132,7 @@ extern int dsp_mbcmd_send_and_wait_exarg(struct mbcmd *mb, struct mb_exarg *arg, ...@@ -129,7 +132,7 @@ extern int dsp_mbcmd_send_and_wait_exarg(struct mbcmd *mb, struct mb_exarg *arg,
#define dsp_mbcmd_send_and_wait(mb, q) \ #define dsp_mbcmd_send_and_wait(mb, q) \
dsp_mbcmd_send_and_wait_exarg((mb), NULL, (q)) dsp_mbcmd_send_and_wait_exarg((mb), NULL, (q))
static __inline__ int __mbcompose_send_exarg(u8 cmd_h, u8 cmd_l, u16 data, static inline int __mbcompose_send_exarg(u8 cmd_h, u8 cmd_l, u16 data,
struct mb_exarg *arg, struct mb_exarg *arg,
int recovery_flag) int recovery_flag)
{ {
...@@ -143,7 +146,7 @@ static __inline__ int __mbcompose_send_exarg(u8 cmd_h, u8 cmd_l, u16 data, ...@@ -143,7 +146,7 @@ static __inline__ int __mbcompose_send_exarg(u8 cmd_h, u8 cmd_l, u16 data,
#define mbcompose_send_recovery(cmd_h, cmd_l, data) \ #define mbcompose_send_recovery(cmd_h, cmd_l, data) \
__mbcompose_send_exarg(MBOX_CMD_DSP_##cmd_h, (cmd_l), (data), NULL, 1) __mbcompose_send_exarg(MBOX_CMD_DSP_##cmd_h, (cmd_l), (data), NULL, 1)
static __inline__ int __mbcompose_send_and_wait_exarg(u8 cmd_h, u8 cmd_l, static inline int __mbcompose_send_and_wait_exarg(u8 cmd_h, u8 cmd_l,
u16 data, u16 data,
struct mb_exarg *arg, struct mb_exarg *arg,
wait_queue_head_t *q) wait_queue_head_t *q)
...@@ -242,3 +245,5 @@ extern struct omap_mmu dsp_mmu; ...@@ -242,3 +245,5 @@ extern struct omap_mmu dsp_mmu;
#define dsp_mem_enable(addr) omap_mmu_mem_enable(&dsp_mmu, (addr)) #define dsp_mem_enable(addr) omap_mmu_mem_enable(&dsp_mmu, (addr))
#define dsp_mem_disable(addr) omap_mmu_mem_disable(&dsp_mmu, (addr)) #define dsp_mem_disable(addr) omap_mmu_mem_disable(&dsp_mmu, (addr))
#endif /* __PLAT_OMAP_DSP_DSP_H */
...@@ -56,7 +56,7 @@ dsp_long_t dspmem_base, dspmem_size, ...@@ -56,7 +56,7 @@ dsp_long_t dspmem_base, dspmem_size,
daram_base, daram_size, daram_base, daram_size,
saram_base, saram_size; saram_base, saram_size;
struct cpustat { static struct cpustat {
struct mutex lock; struct mutex lock;
enum cpustat_e stat; enum cpustat_e stat;
enum cpustat_e req; enum cpustat_e req;
...@@ -317,6 +317,8 @@ static int __init omap_dsp_init(void) ...@@ -317,6 +317,8 @@ static int __init omap_dsp_init(void)
api_ck_handle = clk_get(NULL, "api_ck"); api_ck_handle = clk_get(NULL, "api_ck");
if (IS_ERR(api_ck_handle)) { if (IS_ERR(api_ck_handle)) {
printk(KERN_ERR "omapdsp: could not acquire api_ck handle.\n"); printk(KERN_ERR "omapdsp: could not acquire api_ck handle.\n");
if (dsp_ck_handle != NULL)
clk_put(dsp_ck_handle);
return PTR_ERR(api_ck_handle); return PTR_ERR(api_ck_handle);
} }
...@@ -337,12 +339,14 @@ static int __init omap_dsp_init(void) ...@@ -337,12 +339,14 @@ static int __init omap_dsp_init(void)
dsp_ick_handle = clk_get(NULL, "dsp_ick"); dsp_ick_handle = clk_get(NULL, "dsp_ick");
if (IS_ERR(dsp_ick_handle)) { if (IS_ERR(dsp_ick_handle)) {
printk(KERN_ERR "omapdsp: could not acquire dsp_ick handle.\n"); printk(KERN_ERR "omapdsp: could not acquire dsp_ick handle.\n");
if (dsp_fck_handle != NULL)
clk_put(dsp_fck_handle);
return PTR_ERR(dsp_ick_handle); return PTR_ERR(dsp_ick_handle);
} }
#endif #endif
init_done = 1; init_done = 1;
printk(KERN_INFO "omap_dsp_init() done\n"); pr_info("omap_dsp_init() done\n");
return 0; return 0;
} }
......
...@@ -145,18 +145,6 @@ void dsp_cpustat_set_icrmask(u16 mask); ...@@ -145,18 +145,6 @@ void dsp_cpustat_set_icrmask(u16 mask);
void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void)); void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void));
void dsp_unregister_mem_cb(void); void dsp_unregister_mem_cb(void);
#if defined(CONFIG_ARCH_OMAP1)
static inline void dsp_clk_autoidle(void) {}
#elif defined(CONFIG_ARCH_OMAP2)
static inline void dsp_clk_autoidle(void)
{
/*XXX should be handled in mach-omap[1,2] XXX*/
PM_PWSTCTRL_DSP = (1 << 18) | (1 << 0);
CM_AUTOIDLE_DSP |= (1 << 1);
CM_CLKSTCTRL_DSP |= (1 << 0);
}
#endif
#if defined(CONFIG_ARCH_OMAP1) #if defined(CONFIG_ARCH_OMAP1)
static inline void dsp_clk_enable(void) {} static inline void dsp_clk_enable(void) {}
static inline void dsp_clk_disable(void) {} static inline void dsp_clk_disable(void) {}
...@@ -186,7 +174,7 @@ struct dsp_kfunc_device { ...@@ -186,7 +174,7 @@ struct dsp_kfunc_device {
char *name; char *name;
struct clk *fck; struct clk *fck;
struct clk *ick;; struct clk *ick;;
struct mutex lock; spinlock_t lock;
int enabled; int enabled;
int type; int type;
#define DSP_KFUNC_DEV_TYPE_COMMON 1 #define DSP_KFUNC_DEV_TYPE_COMMON 1
...@@ -194,8 +182,8 @@ struct dsp_kfunc_device { ...@@ -194,8 +182,8 @@ struct dsp_kfunc_device {
struct list_head entry; struct list_head entry;
int (*probe)(struct dsp_kfunc_device *); int (*probe)(struct dsp_kfunc_device *, int);
int (*remove)(struct dsp_kfunc_device *); int (*remove)(struct dsp_kfunc_device *, int);
int (*enable)(struct dsp_kfunc_device *, int); int (*enable)(struct dsp_kfunc_device *, int);
int (*disable)(struct dsp_kfunc_device *, int); int (*disable)(struct dsp_kfunc_device *, int);
}; };
...@@ -212,7 +200,7 @@ struct omap_dsp { ...@@ -212,7 +200,7 @@ struct omap_dsp {
int mmu_irq; int mmu_irq;
struct omap_mbox *mbox; struct omap_mbox *mbox;
struct device *dev; struct device *dev;
struct list_head *kdev_list; struct list_head *kdev_list;
int initialized; int initialized;
}; };
......
...@@ -132,97 +132,44 @@ const struct cmdinfo *cmdinfo[MBOX_CMD_MAX] = { ...@@ -132,97 +132,44 @@ const struct cmdinfo *cmdinfo[MBOX_CMD_MAX] = {
[MBOX_CMD_DSP_DBG] = &cif_dbg, [MBOX_CMD_DSP_DBG] = &cif_dbg,
}; };
static int dsp_kfunc_probe_devices(struct omap_dsp *dsp) #define list_for_each_entry_safe_natural(p,n,h,m) \
{ list_for_each_entry_safe(p,n,h,m)
struct dsp_kfunc_device *p; #define __BUILD_KFUNC(fn, dir) \
int ret, fail = 0; static int __dsp_kfunc_##fn##_devices(struct omap_dsp *dsp, int type, int stage)\
{ \
mutex_lock(&dsp->lock); struct dsp_kfunc_device *p, *tmp; \
list_for_each_entry(p, dsp->kdev_list, entry) { int ret, fail = 0; \
if (p->probe == NULL) \
continue; list_for_each_entry_safe_##dir(p, tmp, dsp->kdev_list, entry) { \
ret = p->probe(p); if (type && (p->type != type)) \
if (ret) { continue; \
printk(KERN_ERR if (p->fn == NULL) \
"probing %s failed\n", p->name); continue; \
fail++; ret = p->fn(p, stage); \
} if (ret) { \
} printk(KERN_ERR "%s %s failed\n", #fn, p->name); \
mutex_unlock(&dsp->lock); fail++; \
} \
pr_debug("%s() fail:%d\n", __FUNCTION__, fail); } \
return fail; \
return fail;
} }
#define BUILD_KFUNC(fn, dir) \
static int dsp_kfunc_remove_devices(struct omap_dsp *dsp) __BUILD_KFUNC(fn, dir) \
{ static inline int dsp_kfunc_##fn##_devices(struct omap_dsp *dsp) \
struct dsp_kfunc_device *p; { \
int ret, fail = 0; return __dsp_kfunc_##fn##_devices(dsp, 0, 0); \
mutex_lock(&dsp->lock);
list_for_each_entry_reverse(p, dsp->kdev_list, entry) {
if (p->remove == NULL)
continue;
ret = p->remove(p);
if (ret) {
printk(KERN_ERR
"removing %s failed\n", p->name);
fail++;
}
}
mutex_unlock(&dsp->lock);
pr_debug("%s() fail:%d\n", __FUNCTION__, fail);
return fail;
} }
#define BUILD_KFUNC_CTL(fn, dir) \
static int dsp_kfunc_enable_devices(struct omap_dsp *dsp, int type, int stage) __BUILD_KFUNC(fn, dir) \
{ static inline int dsp_kfunc_##fn##_devices(struct omap_dsp *dsp, int type, int stage) \
struct dsp_kfunc_device *p; { \
int ret, fail = 0; return __dsp_kfunc_##fn##_devices(dsp, type, stage); \
mutex_lock(&dsp->lock);
list_for_each_entry(p, dsp->kdev_list, entry) {
if ((p->type != type) || (p->enable == NULL))
continue;
ret = p->enable(p, stage);
if (ret) {
printk(KERN_ERR
"enabling %s failed\n", p->name);
fail++;
}
}
mutex_unlock(&dsp->lock);
pr_debug("%s(%d) fail:%d\n", __FUNCTION__, type, fail);
return fail;
} }
static int dsp_kfunc_disable_devices(struct omap_dsp *dsp, int type, int stage) BUILD_KFUNC(probe, natural)
{ BUILD_KFUNC(remove, reverse)
struct dsp_kfunc_device *p; BUILD_KFUNC_CTL(enable, natural)
int ret, fail = 0; BUILD_KFUNC_CTL(disable, reverse)
mutex_lock(&dsp->lock);
list_for_each_entry_reverse(p, omap_dsp->kdev_list, entry) {
if ((p->type != type) || (p->disable == NULL))
continue;
ret = p->disable(p, stage);
if (ret) {
printk(KERN_ERR
"disabling %s failed\n", p->name);
fail++;
}
}
mutex_unlock(&dsp->lock);
pr_debug("%s(%d) fail:%d\n", __FUNCTION__, type, fail);
return fail;
}
int sync_with_dsp(u16 *adr, u16 val, int try_cnt) int sync_with_dsp(u16 *adr, u16 val, int try_cnt)
{ {
...@@ -256,6 +203,7 @@ static int mbcmd_sender_prepare(void *data) ...@@ -256,6 +203,7 @@ static int mbcmd_sender_prepare(void *data)
* *
* Therefore, we can call this function here safely. * Therefore, we can call this function here safely.
*/ */
dsp_mem_enable(ipbuf_sys_ad);
if (sync_with_dsp(&ipbuf_sys_ad->s, TID_FREE, 10) < 0) { if (sync_with_dsp(&ipbuf_sys_ad->s, TID_FREE, 10) < 0) {
printk(KERN_ERR "omapdsp: ipbuf_sys_ad is busy.\n"); printk(KERN_ERR "omapdsp: ipbuf_sys_ad is busy.\n");
ret = -EBUSY; ret = -EBUSY;
...@@ -267,6 +215,7 @@ static int mbcmd_sender_prepare(void *data) ...@@ -267,6 +215,7 @@ static int mbcmd_sender_prepare(void *data)
} }
ipbuf_sys_ad->s = arg->tid; ipbuf_sys_ad->s = arg->tid;
out: out:
dsp_mem_disable(ipbuf_sys_ad);
return ret; return ret;
} }
...@@ -296,9 +245,6 @@ int __dsp_mbcmd_send_exarg(struct mbcmd *mb, struct mb_exarg *arg, ...@@ -296,9 +245,6 @@ int __dsp_mbcmd_send_exarg(struct mbcmd *mb, struct mb_exarg *arg,
goto out; goto out;
} }
if (arg)
dsp_mem_enable(ipbuf_sys_ad);
ret = omap_mbox_msg_send(omap_dsp->mbox, ret = omap_mbox_msg_send(omap_dsp->mbox,
*(mbox_msg_t *)mb, (void*)arg); *(mbox_msg_t *)mb, (void*)arg);
if (ret) if (ret)
...@@ -309,44 +255,37 @@ int __dsp_mbcmd_send_exarg(struct mbcmd *mb, struct mb_exarg *arg, ...@@ -309,44 +255,37 @@ int __dsp_mbcmd_send_exarg(struct mbcmd *mb, struct mb_exarg *arg,
mblog_add(mb, DIR_A2D); mblog_add(mb, DIR_A2D);
out: out:
if (arg)
dsp_mem_disable(ipbuf_sys_ad);
return ret; return ret;
} }
int dsp_mbcmd_send_and_wait_exarg(struct mbcmd *mb, struct mb_exarg *arg, int dsp_mbcmd_send_and_wait_exarg(struct mbcmd *mb, struct mb_exarg *arg,
wait_queue_head_t *q) wait_queue_head_t *q)
{ {
long current_state; int ret;
DECLARE_WAITQUEUE(wait, current);
add_wait_queue(q, &wait);
current_state = current->state;
set_current_state(TASK_INTERRUPTIBLE);
if (dsp_mbcmd_send_exarg(mb, arg) < 0) {
set_current_state(current_state);
remove_wait_queue(q, &wait);
return -1;
}
schedule_timeout(DSP_TIMEOUT);
set_current_state(current_state);
remove_wait_queue(q, &wait);
return 0; DEFINE_WAIT(wait);
prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE);
ret = dsp_mbcmd_send_exarg(mb, arg);
if (ret < 0)
goto out;
schedule_timeout(DSP_TIMEOUT);
out:
finish_wait(q, &wait);
return ret;
} }
/* /*
* mbcmd receiver * mbcmd receiver
*/ */
static int mbcmd_receiver(void *data) static int mbcmd_receiver(void* msg)
{ {
struct mbcmd *mb = data; struct mbcmd *mb = (struct mbcmd *)&msg;
if (cmdinfo[mb->cmd_h] == NULL) { if (cmdinfo[mb->cmd_h] == NULL) {
printk(KERN_ERR printk(KERN_ERR
"invalid message for mbcmd_receiver().\n"); "invalid message (%08x) for mbcmd_receiver().\n",
return -EINVAL; (mbox_msg_t)msg);
return -1;
} }
(*mbseq_expect)++; (*mbseq_expect)++;
...@@ -407,7 +346,7 @@ int dsp_mbox_config(void *p) ...@@ -407,7 +346,7 @@ int dsp_mbox_config(void *p)
static int __init dsp_mbox_init(void) static int __init dsp_mbox_init(void)
{ {
omap_dsp->mbox = omap_mbox_get("dsp"); omap_dsp->mbox = omap_mbox_get("dsp");
if (omap_dsp->mbox == NULL) { if (IS_ERR(omap_dsp->mbox)) {
printk(KERN_ERR "failed to get mailbox handler for DSP.\n"); printk(KERN_ERR "failed to get mailbox handler for DSP.\n");
return -ENODEV; return -ENODEV;
} }
...@@ -420,8 +359,10 @@ static int __init dsp_mbox_init(void) ...@@ -420,8 +359,10 @@ static int __init dsp_mbox_init(void)
static void dsp_mbox_exit(void) static void dsp_mbox_exit(void)
{ {
omap_dsp->mbox->rxq->callback = NULL;
omap_dsp->mbox->txq->callback = NULL; omap_dsp->mbox->txq->callback = NULL;
omap_dsp->mbox->rxq->callback = NULL;
omap_mbox_put(omap_dsp->mbox);
if (mbsync_hold_mem_active) { if (mbsync_hold_mem_active) {
dsp_mem_disable((void *)daram_base); dsp_mem_disable((void *)daram_base);
...@@ -517,36 +458,33 @@ int dsp_late_init(void) ...@@ -517,36 +458,33 @@ int dsp_late_init(void)
{ {
int ret; int ret;
/*dsp_clk_autoidle();*/
dsp_clk_enable(); dsp_clk_enable();
dsp_mem_late_init(); dsp_mem_late_init();
ret = dsp_mbox_init(); ret = dsp_mbox_init();
if (ret) if (ret)
goto fail_mbox; goto fail_mbox;
#ifdef CONFIG_ARCH_OMAP1 #ifdef CONFIG_ARCH_OMAP1
dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE); dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
#endif #endif
ret = dsp_kfunc_enable_devices(omap_dsp, ret = dsp_kfunc_enable_devices(omap_dsp,
DSP_KFUNC_DEV_TYPE_COMMON, 0); DSP_KFUNC_DEV_TYPE_COMMON, 0);
if (ret == 0) if (ret)
goto fail_kfunc; goto fail_kfunc;
omap_dsp->enabled = 1; omap_dsp->enabled = 1;
return 0; return 0;
fail_kfunc: fail_kfunc:
dsp_mbox_exit(); dsp_mbox_exit();
fail_mbox: fail_mbox:
dsp_clk_disable(); dsp_clk_disable();
return ret; return ret;
} }
extern int dsp_ctl_core_init(void); extern int dsp_ctl_core_init(void);
extern void dsp_ctl_core_exit(void); extern void dsp_ctl_core_exit(void);
extern void dsp_ctl_init(void); extern int dsp_ctl_init(void);
extern void dsp_ctl_exit(void); extern void dsp_ctl_exit(void);
extern int dsp_mem_init(void); extern int dsp_mem_init(void);
extern void dsp_mem_exit(void); extern void dsp_mem_exit(void);
...@@ -581,36 +519,42 @@ static int __init dsp_drv_probe(struct platform_device *pdev) ...@@ -581,36 +519,42 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
ret = dsp_kfunc_probe_devices(info); ret = dsp_kfunc_probe_devices(info);
if (ret) { if (ret) {
ret = -ENXIO; ret = -ENXIO;
goto fail0; goto fail_kfunc;
} }
info->mmu_irq = platform_get_irq_byname(pdev, "dsp_mmu"); info->mmu_irq = platform_get_irq_byname(pdev, "dsp_mmu");
if (unlikely(info->mmu_irq) < 0) { if (unlikely(info->mmu_irq) < 0) {
ret = -ENXIO; ret = -ENXIO;
goto fail1; goto fail_irq;
} }
if ((ret = dsp_ctl_core_init()) < 0) ret = dsp_ctl_core_init();
goto fail2; if (ret)
if ((ret = dsp_mem_init()) < 0) goto fail_ctl_core;
goto fail3; ret = dsp_mem_init();
dsp_ctl_init(); if (ret)
goto fail_mem;
ret = dsp_ctl_init();
if (unlikely(ret))
goto fail_ctl_init;
mblog_init(); mblog_init();
if ((ret = dsp_taskmod_init()) < 0) ret = dsp_taskmod_init();
goto fail4; if (ret)
goto fail_taskmod;
return 0; return 0;
fail4: fail_taskmod:
mblog_exit(); mblog_exit();
dsp_ctl_exit(); dsp_ctl_exit();
fail_ctl_init:
dsp_mem_exit(); dsp_mem_exit();
fail3: fail_mem:
dsp_ctl_core_exit(); dsp_ctl_core_exit();
fail2: fail_ctl_core:
fail1: fail_irq:
dsp_kfunc_remove_devices(info); dsp_kfunc_remove_devices(info);
fail0: fail_kfunc:
kfree(info); kfree(info);
return ret; return ret;
...@@ -642,7 +586,7 @@ static int dsp_drv_remove(struct platform_device *pdev) ...@@ -642,7 +586,7 @@ static int dsp_drv_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP1)
static int dsp_drv_suspend(struct platform_device *pdev, pm_message_t state) static int dsp_drv_suspend(struct platform_device *pdev, pm_message_t state)
{ {
dsp_cfgstat_request(CFGSTAT_SUSPEND); dsp_cfgstat_request(CFGSTAT_SUSPEND);
......
...@@ -269,15 +269,15 @@ static int dsp_cfg(void) ...@@ -269,15 +269,15 @@ static int dsp_cfg(void)
#endif #endif
/* send parameter */ /* send parameter */
if ((ret = dsp_setvar(VARID_ICRMASK, dsp_cpustat_get_icrmask())) < 0) ret = dsp_setvar(VARID_ICRMASK, dsp_cpustat_get_icrmask());
if (ret < 0)
goto out; goto out;
/* create runtime sysfs entries */ /* create runtime sysfs entries */
ret = device_create_file(omap_dsp->dev, &dev_attr_loadinfo); ret = device_create_file(omap_dsp->dev, &dev_attr_loadinfo);
if (ret) if (ret)
printk(KERN_ERR "device_create_file failed: %d\n", ret); printk(KERN_ERR "device_create_file failed: %d\n", ret);
out:
out:
dsp_mem_disable((void *)dspmem_base); dsp_mem_disable((void *)dspmem_base);
return ret; return ret;
} }
...@@ -749,9 +749,8 @@ void mbox_dspcfg(struct mbcmd *mb) ...@@ -749,9 +749,8 @@ void mbox_dspcfg(struct mbcmd *mb)
* revision check has been passed. * revision check has been passed.
*/ */
if (!mbox_revision < 0) { if (!mbox_revision < 0) {
printk(KERN_INFO pr_info("mbox: DSPCFG command received, "
"mbox: DSPCFG command received, " "but revision check has not been passed.\n");
"but revision check has not been passed.\n");
return; return;
} }
...@@ -1038,15 +1037,28 @@ out: ...@@ -1038,15 +1037,28 @@ out:
return len; return len;
} }
void __init dsp_ctl_init(void) int __init dsp_ctl_init(void)
{ {
int ret; int ret;
ret = device_create_file(omap_dsp->dev, &dev_attr_ifver); ret = device_create_file(omap_dsp->dev, &dev_attr_ifver);
ret |= device_create_file(omap_dsp->dev, &dev_attr_cpustat); if (unlikely(ret))
ret |= device_create_file(omap_dsp->dev, &dev_attr_icrmask); return ret;
if (ret) ret = device_create_file(omap_dsp->dev, &dev_attr_cpustat);
printk(KERN_ERR "device_create_file failed: %d\n", ret); if (unlikely(ret))
goto fail_create_cpustat;
ret = device_create_file(omap_dsp->dev, &dev_attr_icrmask);
if (unlikely(ret))
goto fail_create_icrmask;
return 0;
fail_create_icrmask:
device_remove_file(omap_dsp->dev, &dev_attr_cpustat);
fail_create_cpustat:
device_remove_file(omap_dsp->dev, &dev_attr_ifver);
return ret;
} }
void dsp_ctl_exit(void) void dsp_ctl_exit(void)
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
* *
*/ */
#ifndef __PLAT_OMAP_DSP_MBCMD_H
#define __PLAT_OMAP_DSP_MBCMD_H
/* /*
* mailbox command: 0x00 - 0x7f * mailbox command: 0x00 - 0x7f
* when a driver wants to use mailbox, it must reserve mailbox commands here. * when a driver wants to use mailbox, it must reserve mailbox commands here.
...@@ -141,3 +143,5 @@ ...@@ -141,3 +143,5 @@
#define BID_NULL 0xffff #define BID_NULL 0xffff
#define BID_PVT 0xfffe #define BID_PVT 0xfffe
#endif /* __PLAT_OMAP_DSP_MBCMD_H */
...@@ -352,6 +352,7 @@ static int dsp_mem_ioctl(struct inode *inode, struct file *file, ...@@ -352,6 +352,7 @@ static int dsp_mem_ioctl(struct inode *inode, struct file *file,
case MEM_IOCTL_MMUINIT: case MEM_IOCTL_MMUINIT:
if (dsp_mmu.exmap_tbl) if (dsp_mmu.exmap_tbl)
omap_mmu_unregister(&dsp_mmu); omap_mmu_unregister(&dsp_mmu);
dsp_mem_ipi_init();
return omap_mmu_register(&dsp_mmu); return omap_mmu_register(&dsp_mmu);
case MEM_IOCTL_EXMAP: case MEM_IOCTL_EXMAP:
...@@ -432,17 +433,9 @@ void dsp_mem_stop(void) ...@@ -432,17 +433,9 @@ void dsp_mem_stop(void)
void dsp_mem_late_init(void) void dsp_mem_late_init(void)
{ {
int ret = 0; int ret = 0;
#ifdef CONFIG_ARCH_OMAP2
int i, dspmem_pg_count;
dspmem_pg_count = dspmem_size >> 12;
for (i = 0; i < dspmem_pg_count; i++) {
writel(i, DSP_IPI_INDEX);
writel(DSP_IPI_ENTRY_ELMSIZEVALUE_16, DSP_IPI_ENTRY);
}
writel(1, DSP_IPI_ENABLE);
writel(IOMAP_VAL, DSP_IPI_IOMAP);
dsp_mem_ipi_init();
#ifdef CONFIG_ARCH_OMAP2
dsp_mmu.clk = dsp_fck_handle; dsp_mmu.clk = dsp_fck_handle;
dsp_mmu.memclk = dsp_ick_handle; dsp_mmu.memclk = dsp_ick_handle;
#elif defined(CONFIG_ARCH_OMAP1) #elif defined(CONFIG_ARCH_OMAP1)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/arch/mailbox.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "dsp_mbcmd.h" #include "dsp_mbcmd.h"
#include "dsp.h" #include "dsp.h"
...@@ -50,24 +51,17 @@ static ssize_t dsp_err_read(struct file *file, char __user *buf, size_t count, ...@@ -50,24 +51,17 @@ static ssize_t dsp_err_read(struct file *file, char __user *buf, size_t count,
{ {
unsigned long flags; unsigned long flags;
int status; int status;
DEFINE_WAIT(wait);
if (count < 4) if (count < 4)
return 0; return 0;
if (errcnt == 0) { prepare_to_wait(&err_wait_q, &wait, TASK_INTERRUPTIBLE);
long current_state; if (errcnt == 0)
DECLARE_WAITQUEUE(wait, current); schedule();
finish_wait(&err_wait_q, &wait);
add_wait_queue(&err_wait_q, &wait); if (signal_pending(current))
current_state = current->state; return -EINTR;
set_current_state(TASK_INTERRUPTIBLE);
if (errcnt == 0) /* last check */
schedule();
set_current_state(current_state);
remove_wait_queue(&err_wait_q, &wait);
if (signal_pending(current))
return -EINTR;
}
local_irq_save(flags); local_irq_save(flags);
status = copy_to_user(buf, &errval, 4); status = copy_to_user(buf, &errval, 4);
...@@ -155,6 +149,12 @@ int dsp_err_isset(enum errcode_e code) ...@@ -155,6 +149,12 @@ int dsp_err_isset(enum errcode_e code)
return (errval & dsp_err_desc[code].val) ? 1 : 0; return (errval & dsp_err_desc[code].val) ? 1 : 0;
} }
void dsp_err_notify(void)
{
/* new error code should be assigned */
dsp_err_set(DSP_ERR_WDT, 0);
}
/* /*
* functions called from mailbox interrupt routine * functions called from mailbox interrupt routine
*/ */
...@@ -216,11 +216,12 @@ void dsp_err_start(void) ...@@ -216,11 +216,12 @@ void dsp_err_start(void)
if (dsp_err_isset(i)) if (dsp_err_isset(i))
dsp_err_clear(i); dsp_err_clear(i);
} }
omap_dsp->mbox->err_notify = dsp_err_notify;
errcnt = 0; errcnt = 0;
} }
void dsp_err_stop(void) void dsp_err_stop(void)
{ {
wake_up_interruptible(&err_wait_q); wake_up_interruptible(&err_wait_q);
omap_dsp->mbox->err_notify = NULL;
} }
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* *
*/ */
#ifndef __PLAT_OMAP_DSP_FIFO_H
#define __PLAT_OMAP_DSP_FIFO_H
struct fifo_struct { struct fifo_struct {
spinlock_t lock; spinlock_t lock;
char *buf; char *buf;
...@@ -168,3 +171,5 @@ out: ...@@ -168,3 +171,5 @@ out:
spin_unlock(&fifo->lock); spin_unlock(&fifo->lock);
return ret; return ret;
} }
#endif /* __PLAT_OMAP_DSP_FIFO_H */
...@@ -112,10 +112,9 @@ int ipbuf_config(u16 ln, u16 lsz, void *base) ...@@ -112,10 +112,9 @@ int ipbuf_config(u16 ln, u16 lsz, void *base)
ipbcfg.bsycnt = ln; /* DSP holds all ipbufs initially. */ ipbcfg.bsycnt = ln; /* DSP holds all ipbufs initially. */
ipbcfg.cnt_full = 0; ipbcfg.cnt_full = 0;
printk(KERN_INFO pr_info("omapdsp: IPBUF configuration\n"
"omapdsp: IPBUF configuration\n" " %d words * %d lines at 0x%p.\n",
" %d words * %d lines at 0x%p.\n", ipbcfg.lsz, ipbcfg.ln, ipbcfg.base);
ipbcfg.lsz, ipbcfg.ln, ipbcfg.base);
ret = device_create_file(omap_dsp->dev, &dev_attr_ipbuf); ret = device_create_file(omap_dsp->dev, &dev_attr_ipbuf);
if (ret) if (ret)
...@@ -123,7 +122,7 @@ int ipbuf_config(u16 ln, u16 lsz, void *base) ...@@ -123,7 +122,7 @@ int ipbuf_config(u16 ln, u16 lsz, void *base)
return ret; return ret;
free_out: free_out:
kfree(g_ipbuf); kfree(g_ipbuf);
g_ipbuf = NULL; g_ipbuf = NULL;
return ret; return ret;
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* *
*/ */
#ifndef __PLAT_OMAP_DSP_IPBUF_H
#define __PLAT_OMAP_DSP_IPBUF_H
struct ipbuf { struct ipbuf {
u16 c; /* count */ u16 c; /* count */
u16 next; /* link */ u16 next; /* link */
...@@ -61,19 +64,8 @@ struct ipbuf_head { ...@@ -61,19 +64,8 @@ struct ipbuf_head {
extern struct ipbcfg ipbcfg; extern struct ipbcfg ipbcfg;
extern struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad; extern struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad;
#define ipb_bsycnt_inc(ipbcfg) \ #define ipb_bsycnt_inc(ipbcfg) atomic_inc((atomic_t *)&((ipbcfg)->bsycnt))
do { \ #define ipb_bsycnt_dec(ipbcfg) atomic_dec((atomic_t *)&((ipbcfg)->bsycnt))
disable_irq(omap_dsp->mbox->irq); \
(ipbcfg)->bsycnt++; \
enable_irq(omap_dsp->mbox->irq); \
} while(0)
#define ipb_bsycnt_dec(ipbcfg) \
do { \
disable_irq(omap_dsp->mbox->irq); \
(ipbcfg)->bsycnt--; \
enable_irq(omap_dsp->mbox->irq); \
} while(0)
#define dsp_mem_enable_ipbuf() dsp_mem_enable(ipbcfg.base) #define dsp_mem_enable_ipbuf() dsp_mem_enable(ipbcfg.base)
#define dsp_mem_disable_ipbuf() dsp_mem_disable(ipbcfg.base) #define dsp_mem_disable_ipbuf() dsp_mem_disable(ipbcfg.base)
...@@ -105,7 +97,7 @@ struct ipblink { ...@@ -105,7 +97,7 @@ struct ipblink {
#define ipblink_empty(link) ((link)->top == BID_NULL) #define ipblink_empty(link) ((link)->top == BID_NULL)
static __inline__ void __ipblink_del_top(struct ipblink *link) static inline void __ipblink_del_top(struct ipblink *link)
{ {
struct ipbuf_head *ipb_h = bid_to_ipbuf(link->top); struct ipbuf_head *ipb_h = bid_to_ipbuf(link->top);
...@@ -115,14 +107,14 @@ static __inline__ void __ipblink_del_top(struct ipblink *link) ...@@ -115,14 +107,14 @@ static __inline__ void __ipblink_del_top(struct ipblink *link)
ipb_h->p->next = BID_NULL; ipb_h->p->next = BID_NULL;
} }
static __inline__ void ipblink_del_top(struct ipblink *link) static inline void ipblink_del_top(struct ipblink *link)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_del_top(link); __ipblink_del_top(link);
spin_unlock(&link->lock); spin_unlock(&link->lock);
} }
static __inline__ void __ipblink_add_tail(struct ipblink *link, u16 bid) static inline void __ipblink_add_tail(struct ipblink *link, u16 bid)
{ {
if (ipblink_empty(link)) if (ipblink_empty(link))
link->top = bid; link->top = bid;
...@@ -131,14 +123,14 @@ static __inline__ void __ipblink_add_tail(struct ipblink *link, u16 bid) ...@@ -131,14 +123,14 @@ static __inline__ void __ipblink_add_tail(struct ipblink *link, u16 bid)
link->tail = bid; link->tail = bid;
} }
static __inline__ void ipblink_add_tail(struct ipblink *link, u16 bid) static inline void ipblink_add_tail(struct ipblink *link, u16 bid)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_add_tail(link, bid); __ipblink_add_tail(link, bid);
spin_unlock(&link->lock); spin_unlock(&link->lock);
} }
static __inline__ void __ipblink_flush(struct ipblink *link) static inline void __ipblink_flush(struct ipblink *link)
{ {
u16 bid; u16 bid;
...@@ -149,46 +141,46 @@ static __inline__ void __ipblink_flush(struct ipblink *link) ...@@ -149,46 +141,46 @@ static __inline__ void __ipblink_flush(struct ipblink *link)
} }
} }
static __inline__ void ipblink_flush(struct ipblink *link) static inline void ipblink_flush(struct ipblink *link)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_flush(link); __ipblink_flush(link);
spin_unlock(&link->lock); spin_unlock(&link->lock);
} }
static __inline__ void __ipblink_add_pvt(struct ipblink *link) static inline void __ipblink_add_pvt(struct ipblink *link)
{ {
link->top = BID_PVT; link->top = BID_PVT;
link->tail = BID_PVT; link->tail = BID_PVT;
} }
static __inline__ void ipblink_add_pvt(struct ipblink *link) static inline void ipblink_add_pvt(struct ipblink *link)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_add_pvt(link); __ipblink_add_pvt(link);
spin_unlock(&link->lock); spin_unlock(&link->lock);
} }
static __inline__ void __ipblink_del_pvt(struct ipblink *link) static inline void __ipblink_del_pvt(struct ipblink *link)
{ {
link->top = BID_NULL; link->top = BID_NULL;
link->tail = BID_NULL; link->tail = BID_NULL;
} }
static __inline__ void ipblink_del_pvt(struct ipblink *link) static inline void ipblink_del_pvt(struct ipblink *link)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_del_pvt(link); __ipblink_del_pvt(link);
spin_unlock(&link->lock); spin_unlock(&link->lock);
} }
static __inline__ void __ipblink_flush_pvt(struct ipblink *link) static inline void __ipblink_flush_pvt(struct ipblink *link)
{ {
if (!ipblink_empty(link)) if (!ipblink_empty(link))
ipblink_del_pvt(link); ipblink_del_pvt(link);
} }
static __inline__ void ipblink_flush_pvt(struct ipblink *link) static inline void ipblink_flush_pvt(struct ipblink *link)
{ {
spin_lock(&link->lock); spin_lock(&link->lock);
__ipblink_flush_pvt(link); __ipblink_flush_pvt(link);
...@@ -197,3 +189,5 @@ static __inline__ void ipblink_flush_pvt(struct ipblink *link) ...@@ -197,3 +189,5 @@ static __inline__ void ipblink_flush_pvt(struct ipblink *link)
#define ipblink_for_each(bid, link) \ #define ipblink_for_each(bid, link) \
for (bid = (link)->top; bid != BID_NULL; bid = bid_to_ipbuf(bid)->p->next) for (bid = (link)->top; bid != BID_NULL; bid = bid_to_ipbuf(bid)->p->next)
#endif /* __PLAT_OMAP_DSP_IPBUF_H */
...@@ -48,7 +48,16 @@ char *subcmd_name(struct mbcmd *mb) ...@@ -48,7 +48,16 @@ char *subcmd_name(struct mbcmd *mb)
break; break;
case MBOX_CMD_DSP_KFUNC: case MBOX_CMD_DSP_KFUNC:
s = (cmd_l == KFUNC_FBCTL) ? "FBCTL": s = (cmd_l == KFUNC_FBCTL) ? "FBCTL":
(cmd_l == KFUNC_POWER) ? "POWER": (cmd_l == KFUNC_POWER) ?
((mb->data == AUDIO_PWR_UP) ? "PWR AUD /UP":
(mb->data == AUDIO_PWR_DOWN) ? "PWR AUD /DOWN":
(mb->data == AUDIO_PWR_DOWN2) ? "PWR AUD /DOWN(2)":
(mb->data == DSP_PWR_UP) ? "PWR DSP /UP":
(mb->data == DSP_PWR_DOWN) ? "PWR DSP /DOWN":
(mb->data == DVFS_START) ? "PWR DVFS/START":
(mb->data == DVFS_STOP) ? "PWR DVFS/STOP":
NULL):
NULL; NULL;
break; break;
case MBOX_CMD_DSP_DSPCFG: case MBOX_CMD_DSP_DSPCFG:
...@@ -138,22 +147,19 @@ static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) ...@@ -138,22 +147,19 @@ static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir)
subname = subcmd_name(mb); subname = subcmd_name(mb);
if (unlikely(!subname)) if (unlikely(!subname))
subname = "Unknown"; subname = "Unknown";
printk(KERN_DEBUG pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
"mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n", dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
dir_str, mb->seq, mb->cmd_h, mb->cmd_l, ci->name, subname, mb->data);
ci->name, subname, mb->data);
break; break;
case CMD_L_TYPE_TID: case CMD_L_TYPE_TID:
printk(KERN_DEBUG pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
"mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n", dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
dir_str, mb->seq, mb->cmd_h, mb->cmd_l, ci->name, mb->cmd_l, mb->data);
ci->name, mb->cmd_l, mb->data);
break; break;
case CMD_L_TYPE_NULL: case CMD_L_TYPE_NULL:
printk(KERN_DEBUG pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
"mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n", dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
dir_str, mb->seq, mb->cmd_h, mb->cmd_l, ci->name, mb->data);
ci->name, mb->data);
break; break;
} }
} }
......
...@@ -274,4 +274,20 @@ static void intmem_disable(void) { } ...@@ -274,4 +274,20 @@ static void intmem_disable(void) { }
static int dsp_mmu_itack(void) { return 0; } static int dsp_mmu_itack(void) { return 0; }
#endif #endif
#ifdef CONFIG_ARCH_OMAP2
static inline void dsp_mem_ipi_init(void)
{
int i, dspmem_pg_count;
dspmem_pg_count = dspmem_size >> 12;
for (i = 0; i < dspmem_pg_count; i++) {
writel(i, DSP_IPI_INDEX);
writel(DSP_IPI_ENTRY_ELMSIZEVALUE_16, DSP_IPI_ENTRY);
}
writel(1, DSP_IPI_ENABLE);
writel(IOMAP_VAL, DSP_IPI_IOMAP);
}
#else
static inline void dsp_mem_ipi_init(void) { }
#endif
#endif /* __PLAT_OMAP_DSP_MMU_H */ #endif /* __PLAT_OMAP_DSP_MMU_H */
...@@ -21,26 +21,33 @@ ...@@ -21,26 +21,33 @@
* *
*/ */
#ifndef __PLAT_OMAP_DSP_PROCLIST_H
#define __PLAT_OMAP_DSP_PROCLIST_H
struct proc_list { struct proc_list {
struct list_head list_head; struct list_head list_head;
pid_t pid; pid_t pid;
struct file *file; struct file *file;
}; };
static __inline__ void proc_list_add(spinlock_t *lock, struct list_head *list, static inline int proc_list_add(spinlock_t *lock, struct list_head *list,
struct task_struct *tsk, struct file *file) struct task_struct *tsk, struct file *file)
{ {
struct proc_list *new; struct proc_list *new;
new = kmalloc(sizeof(struct proc_list), GFP_KERNEL); new = kmalloc(sizeof(struct proc_list), GFP_KERNEL);
if (new == NULL)
return -ENOMEM;
new->pid = tsk->pid; new->pid = tsk->pid;
new->file = file; new->file = file;
spin_lock(lock); spin_lock(lock);
list_add_tail(&new->list_head, list); list_add_tail(&new->list_head, list);
spin_unlock(lock); spin_unlock(lock);
return 0;
} }
static __inline__ void proc_list_del(spinlock_t *lock, struct list_head *list, static inline void proc_list_del(spinlock_t *lock, struct list_head *list,
struct task_struct *tsk, struct file *file) struct task_struct *tsk, struct file *file)
{ {
struct proc_list *pl; struct proc_list *pl;
...@@ -64,7 +71,7 @@ static __inline__ void proc_list_del(spinlock_t *lock, struct list_head *list, ...@@ -64,7 +71,7 @@ static __inline__ void proc_list_del(spinlock_t *lock, struct list_head *list,
spin_unlock(lock); spin_unlock(lock);
} }
static __inline__ void proc_list_flush(spinlock_t *lock, struct list_head *list) static inline void proc_list_flush(spinlock_t *lock, struct list_head *list)
{ {
struct proc_list *pl; struct proc_list *pl;
...@@ -76,3 +83,5 @@ static __inline__ void proc_list_flush(spinlock_t *lock, struct list_head *list) ...@@ -76,3 +83,5 @@ static __inline__ void proc_list_flush(spinlock_t *lock, struct list_head *list)
} }
spin_unlock(lock); spin_unlock(lock);
} }
#endif /* __PLAT_OMAP_DSP_PROCLIST_H */
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
#define TASKDEV_ST_STATE_MASK 0x7fffffff #define TASKDEV_ST_STATE_MASK 0x7fffffff
#define TASKDEV_ST_STALE 0x80000000 #define TASKDEV_ST_STALE 0x80000000
struct { static struct {
long state; long state;
char *name; char *name;
} devstate_desc[] = { } devstate_desc[] = {
...@@ -90,7 +90,8 @@ struct { ...@@ -90,7 +90,8 @@ struct {
{ TASKDEV_ST_KILLING, "killing" }, { TASKDEV_ST_KILLING, "killing" },
}; };
static char *devstate_name(long state) { static char *devstate_name(long state)
{
int i; int i;
int max = ARRAY_SIZE(devstate_desc); int max = ARRAY_SIZE(devstate_desc);
...@@ -183,7 +184,7 @@ struct dsptask { ...@@ -183,7 +184,7 @@ struct dsptask {
#define rcvtyp_pvt(ttyp) ((ttyp) & TTYP_PVMD) #define rcvtyp_pvt(ttyp) ((ttyp) & TTYP_PVMD)
#define rcvtyp_gbl(ttyp) (!((ttyp) & TTYP_PVMD)) #define rcvtyp_gbl(ttyp) (!((ttyp) & TTYP_PVMD))
static __inline__ int has_taskdev_lock(struct taskdev *dev); static inline int has_taskdev_lock(struct taskdev *dev);
static int dsp_rmdev_minor(unsigned char minor); static int dsp_rmdev_minor(unsigned char minor);
static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor); static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
static void taskdev_delete(unsigned char minor); static void taskdev_delete(unsigned char minor);
...@@ -254,100 +255,58 @@ static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink); ...@@ -254,100 +255,58 @@ static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink);
static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz); static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz);
static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap); static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap);
static inline void set_taskdev_state(struct taskdev *dev, int state)
{
pr_debug("omapdsp: devstate: CHANGE %s[%d]:\"%s\"->\"%s\"\n",
dev->name,
(dev->task ? dev->task->tid : -1),
devstate_name(dev->state),
devstate_name(state));
dev->state = state;
}
/* /*
* devstate_read_lock_timeout() * devstate_read_lock_timeout()
* devstate_write_lock_timeout(): * devstate_write_lock_timeout():
* timeout != 0: dev->state can be diffeent from what you want. * timeout != 0: dev->state can be diffeent from what you want.
* timeout == 0: no timeout * timeout == 0: no timeout
*/ */
static int devstate_read_lock_timeout(struct taskdev *dev, long devstate, #define BUILD_DEVSTATE_LOCK_TIMEOUT(rw) \
int timeout) static int devstate_##rw##_lock_timeout(struct taskdev *dev, long devstate, \
{ int timeout) \
DECLARE_WAITQUEUE(wait, current); { \
long current_state = current->state; DEFINE_WAIT(wait); \
int ret = 0; down_##rw(&dev->state_sem); \
while (!(dev->state & devstate)) { \
down_read(&dev->state_sem); up_##rw(&dev->state_sem); \
if (dev->state & devstate) prepare_to_wait(&dev->state_wait_q, &wait, TASK_INTERRUPTIBLE); \
return 0; if (!timeout) \
timeout = MAX_SCHEDULE_TIMEOUT; \
add_wait_queue(&dev->state_wait_q, &wait); timeout = schedule_timeout(timeout); \
do { finish_wait(&dev->state_wait_q, &wait); \
set_current_state(TASK_INTERRUPTIBLE); if (timeout == 0) \
up_read(&dev->state_sem); return -ETIME; \
if (timeout) { if (signal_pending(current)) \
if ((timeout = schedule_timeout(timeout)) == 0) { return -EINTR; \
/* timeout */ down_##rw(&dev->state_sem); \
down_read(&dev->state_sem); } \
break; return 0; \
} }
} else BUILD_DEVSTATE_LOCK_TIMEOUT(read)
schedule(); BUILD_DEVSTATE_LOCK_TIMEOUT(write)
if (signal_pending(current)) {
ret = -EINTR; #define BUILD_DEVSTATE_LOCK_AND_TEST(rw) \
break; static int devstate_##rw##_lock_and_test(struct taskdev *dev, long devstate) \
} { \
down_read(&dev->state_sem); down_##rw(&dev->state_sem); \
} while (!(dev->state & devstate)); if (dev->state & devstate) \
remove_wait_queue(&dev->state_wait_q, &wait); return 1; /* success */ \
set_current_state(current_state); /* failure */ \
return ret; up_##rw(&dev->state_sem); \
} return 0; \
}
static int devstate_read_lock_and_test(struct taskdev *dev, long devstate) BUILD_DEVSTATE_LOCK_AND_TEST(read)
{ BUILD_DEVSTATE_LOCK_AND_TEST(write)
down_read(&dev->state_sem);
if (dev->state & devstate)
return 1; /* success */
/* failure */
up_read(&dev->state_sem);
return 0;
}
static int devstate_write_lock_timeout(struct taskdev *dev, long devstate,
int timeout)
{
DECLARE_WAITQUEUE(wait, current);
long current_state = current->state;
int ret = 0;
down_write(&dev->state_sem);
if (dev->state & devstate)
return 0;
add_wait_queue(&dev->state_wait_q, &wait);
do {
set_current_state(TASK_INTERRUPTIBLE);
up_write(&dev->state_sem);
if (timeout) {
if ((timeout = schedule_timeout(timeout)) == 0) {
/* timeout */
down_write(&dev->state_sem);
break;
}
} else
schedule();
if (signal_pending(current)) {
ret = -EINTR;
break;
}
down_write(&dev->state_sem);
} while (!(dev->state & devstate));
remove_wait_queue(&dev->state_wait_q, &wait);
set_current_state(current_state);
return ret;
}
static int devstate_write_lock_and_test(struct taskdev *dev, long devstate)
{
down_write(&dev->state_sem);
if (dev->state & devstate) /* success */
return 1;
/* failure */
up_write(&dev->state_sem);
return -1;
}
static int taskdev_lock_interruptible(struct taskdev *dev, static int taskdev_lock_interruptible(struct taskdev *dev,
struct mutex *lock) struct mutex *lock)
...@@ -380,7 +339,7 @@ static int taskdev_lock_and_statelock_attached(struct taskdev *dev, ...@@ -380,7 +339,7 @@ static int taskdev_lock_and_statelock_attached(struct taskdev *dev,
return ret; return ret;
} }
static __inline__ void taskdev_unlock_and_stateunlock(struct taskdev *dev, static inline void taskdev_unlock_and_stateunlock(struct taskdev *dev,
struct mutex *lock) struct mutex *lock)
{ {
mutex_unlock(lock); mutex_unlock(lock);
...@@ -448,7 +407,7 @@ static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz) ...@@ -448,7 +407,7 @@ static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz)
return 0; return 0;
} }
static __inline__ int has_taskdev_lock(struct taskdev *dev) static inline int has_taskdev_lock(struct taskdev *dev)
{ {
return (dev->lock_pid == current->pid); return (dev->lock_pid == current->pid);
} }
...@@ -501,7 +460,7 @@ static int dsp_task_config(struct dsptask *task, u8 tid) ...@@ -501,7 +460,7 @@ static int dsp_task_config(struct dsptask *task, u8 tid)
if (strlen(task->name) <= 1) if (strlen(task->name) <= 1)
sprintf(task->name, "%d", tid); sprintf(task->name, "%d", tid);
printk(KERN_INFO "omapdsp: task %d: name %s\n", tid, task->name); pr_info("omapdsp: task %d: name %s\n", tid, task->name);
ttyp = task->ttyp; ttyp = task->ttyp;
...@@ -563,7 +522,7 @@ int dsp_task_config_all(u8 n) ...@@ -563,7 +522,7 @@ int dsp_task_config_all(u8 n)
struct dsptask *taskheap; struct dsptask *taskheap;
size_t devheapsz, taskheapsz; size_t devheapsz, taskheapsz;
printk(KERN_INFO "omapdsp: found %d task(s)\n", n); pr_info("omapdsp: found %d task(s)\n", n);
if (n == 0) if (n == 0)
return 0; return 0;
...@@ -590,7 +549,7 @@ int dsp_task_config_all(u8 n) ...@@ -590,7 +549,7 @@ int dsp_task_config_all(u8 n)
if ((ret = taskdev_attach_task(dev, task)) < 0) if ((ret = taskdev_attach_task(dev, task)) < 0)
return ret; return ret;
dsp_task_init(task); dsp_task_init(task);
printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name); pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
} }
return 0; return 0;
...@@ -696,6 +655,7 @@ static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf, ...@@ -696,6 +655,7 @@ static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
struct taskdev *dev = taskdev[minor]; struct taskdev *dev = taskdev[minor];
int ret = 0; int ret = 0;
DEFINE_WAIT(wait);
if (count == 0) { if (count == 0) {
return 0; return 0;
...@@ -708,27 +668,22 @@ static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf, ...@@ -708,27 +668,22 @@ static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex)) if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
return -ENODEV; return -ENODEV;
prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
if (fifo_empty(&dev->rcvdt.fifo))
schedule();
finish_wait(&dev->read_wait_q, &wait);
if (fifo_empty(&dev->rcvdt.fifo)) { if (fifo_empty(&dev->rcvdt.fifo)) {
long current_state = current->state; /* failure */
DECLARE_WAITQUEUE(wait, current); if (signal_pending(current))
ret = -EINTR;
set_current_state(TASK_INTERRUPTIBLE); goto up_out;
add_wait_queue(&dev->read_wait_q, &wait);
if (fifo_empty(&dev->rcvdt.fifo)) /* last check */
schedule();
set_current_state(current_state);
remove_wait_queue(&dev->read_wait_q, &wait);
if (fifo_empty(&dev->rcvdt.fifo)) {
/* failure */
if (signal_pending(current))
ret = -EINTR;
goto up_out;
}
} }
ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count); ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
up_out: up_out:
taskdev_unlock_and_stateunlock(dev, &dev->read_mutex); taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
return ret; return ret;
} }
...@@ -740,6 +695,7 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf, ...@@ -740,6 +695,7 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
struct taskdev *dev = taskdev[minor]; struct taskdev *dev = taskdev[minor];
struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk; struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
ssize_t ret = 0; ssize_t ret = 0;
DEFINE_WAIT(wait);
if (count == 0) { if (count == 0) {
return 0; return 0;
...@@ -757,23 +713,15 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf, ...@@ -757,23 +713,15 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex)) if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
return -ENODEV; return -ENODEV;
prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
if (ipblink_empty(&rcvdt->link))
schedule();
finish_wait(&dev->read_wait_q, &wait);
if (ipblink_empty(&rcvdt->link)) { if (ipblink_empty(&rcvdt->link)) {
long current_state; /* failure */
DECLARE_WAITQUEUE(wait, current); if (signal_pending(current))
ret = -EINTR;
add_wait_queue(&dev->read_wait_q, &wait); goto up_out;
current_state = current->state;
set_current_state(TASK_INTERRUPTIBLE);
if (ipblink_empty(&rcvdt->link)) /* last check */
schedule();
set_current_state(current_state);
remove_wait_queue(&dev->read_wait_q, &wait);
if (ipblink_empty(&rcvdt->link)) {
/* failure */
if (signal_pending(current))
ret = -EINTR;
goto up_out;
}
} }
/* copy from delayed IPBUF */ /* copy from delayed IPBUF */
...@@ -818,9 +766,9 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf, ...@@ -818,9 +766,9 @@ static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
release_ipbuf_pvt(ipbp); release_ipbuf_pvt(ipbp);
rcvdt->rp = 0; rcvdt->rp = 0;
} }
pv_out2: pv_out2:
dsp_mem_disable(src); dsp_mem_disable(src);
pv_out1: pv_out1:
dsp_mem_disable(ipbp); dsp_mem_disable(ipbp);
} }
} else { } else {
...@@ -857,11 +805,11 @@ pv_out1: ...@@ -857,11 +805,11 @@ pv_out1:
rcvdt->rp = 0; rcvdt->rp = 0;
} }
} }
gb_out: gb_out:
dsp_mem_disable_ipbuf(); dsp_mem_disable_ipbuf();
} }
up_out: up_out:
taskdev_unlock_and_stateunlock(dev, &dev->read_mutex); taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
return ret; return ret;
} }
...@@ -1009,6 +957,7 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf, ...@@ -1009,6 +957,7 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
struct taskdev *dev = taskdev[minor]; struct taskdev *dev = taskdev[minor];
u16 wd; u16 wd;
int ret = 0; int ret = 0;
DEFINE_WAIT(wait);
if (count == 0) { if (count == 0) {
return 0; return 0;
...@@ -1024,23 +973,15 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf, ...@@ -1024,23 +973,15 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex)) if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
return -ENODEV; return -ENODEV;
prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
if (dev->wsz == 0)
schedule();
finish_wait(&dev->write_wait_q, &wait);
if (dev->wsz == 0) { if (dev->wsz == 0) {
long current_state; /* failure */
DECLARE_WAITQUEUE(wait, current); if (signal_pending(current))
ret = -EINTR;
add_wait_queue(&dev->write_wait_q, &wait); goto up_out;
current_state = current->state;
set_current_state(TASK_INTERRUPTIBLE);
if (dev->wsz == 0) /* last check */
schedule();
set_current_state(current_state);
remove_wait_queue(&dev->write_wait_q, &wait);
if (dev->wsz == 0) {
/* failure */
if (signal_pending(current))
ret = -EINTR;
goto up_out;
}
} }
if (copy_from_user(&wd, buf, count)) { if (copy_from_user(&wd, buf, count)) {
...@@ -1058,7 +999,7 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf, ...@@ -1058,7 +999,7 @@ static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
dev->wsz = 0; dev->wsz = 0;
spin_unlock(&dev->wsz_lock); spin_unlock(&dev->wsz_lock);
up_out: up_out:
taskdev_unlock_and_stateunlock(dev, &dev->write_mutex); taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
return ret; return ret;
} }
...@@ -1069,6 +1010,7 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf, ...@@ -1069,6 +1010,7 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
struct taskdev *dev = taskdev[minor]; struct taskdev *dev = taskdev[minor];
int ret = 0; int ret = 0;
DEFINE_WAIT(wait);
if (count == 0) { if (count == 0) {
return 0; return 0;
...@@ -1086,23 +1028,15 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf, ...@@ -1086,23 +1028,15 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex)) if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
return -ENODEV; return -ENODEV;
prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
if (dev->wsz == 0)
schedule();
finish_wait(&dev->write_wait_q, &wait);
if (dev->wsz == 0) { if (dev->wsz == 0) {
long current_state; /* failure */
DECLARE_WAITQUEUE(wait, current); if (signal_pending(current))
ret = -EINTR;
add_wait_queue(&dev->write_wait_q, &wait); goto up_out;
current_state = current->state;
set_current_state(TASK_INTERRUPTIBLE);
if (dev->wsz == 0) /* last check */
schedule();
set_current_state(current_state);
remove_wait_queue(&dev->write_wait_q, &wait);
if (dev->wsz == 0) {
/* failure */
if (signal_pending(current))
ret = -EINTR;
goto up_out;
}
} }
if (count > dev->wsz) if (count > dev->wsz)
...@@ -1140,9 +1074,9 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf, ...@@ -1140,9 +1074,9 @@ static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
ret = count; ret = count;
} }
spin_unlock(&dev->wsz_lock); spin_unlock(&dev->wsz_lock);
pv_out2: pv_out2:
dsp_mem_disable(dst); dsp_mem_disable(dst);
pv_out1: pv_out1:
dsp_mem_disable(ipbp); dsp_mem_disable(ipbp);
} else { } else {
/* global */ /* global */
...@@ -1170,11 +1104,11 @@ pv_out1: ...@@ -1170,11 +1104,11 @@ pv_out1:
} else } else
release_ipbuf(ipb_h); release_ipbuf(ipb_h);
spin_unlock(&dev->wsz_lock); spin_unlock(&dev->wsz_lock);
gb_out: gb_out:
dsp_mem_disable_ipbuf(); dsp_mem_disable_ipbuf();
} }
up_out: up_out:
taskdev_unlock_and_stateunlock(dev, &dev->write_mutex); taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
return ret; return ret;
} }
...@@ -1428,10 +1362,9 @@ static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1428,10 +1362,9 @@ static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
if (tmp_len > req_len) if (tmp_len > req_len)
tmp_len = req_len; tmp_len = req_len;
printk(KERN_DEBUG pr_debug("omapdsp: mmap info: "
"omapdsp: mmap info: " "vmadr = %08lx, padr = %08lx, len = %x\n",
"vmadr = %08lx, padr = %08lx, len = %x\n", tmp_vmadr, tmp_padr, tmp_len);
tmp_vmadr, tmp_padr, tmp_len);
if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT, if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
tmp_len, vma->vm_page_prot) != 0) { tmp_len, vma->vm_page_prot) != 0) {
printk(KERN_ERR printk(KERN_ERR
...@@ -1465,49 +1398,49 @@ static int dsp_task_open(struct inode *inode, struct file *file) ...@@ -1465,49 +1398,49 @@ static int dsp_task_open(struct inode *inode, struct file *file)
if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
return -ENODEV; return -ENODEV;
restart: restart:
mutex_lock(&dev->usecount_lock); mutex_lock(&dev->usecount_lock);
down_write(&dev->state_sem); down_write(&dev->state_sem);
/* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */ /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
switch (dev->state & TASKDEV_ST_STATE_MASK) { switch (dev->state & TASKDEV_ST_STATE_MASK) {
case TASKDEV_ST_NOTASK: case TASKDEV_ST_NOTASK:
break; break;
case TASKDEV_ST_ATTACHED: case TASKDEV_ST_ATTACHED:
goto attached; goto attached;
case TASKDEV_ST_INVALID: case TASKDEV_ST_INVALID:
up_write(&dev->state_sem); up_write(&dev->state_sem);
mutex_unlock(&dev->usecount_lock); mutex_unlock(&dev->usecount_lock);
return -ENODEV; return -ENODEV;
case TASKDEV_ST_FREEZED: case TASKDEV_ST_FREEZED:
case TASKDEV_ST_KILLING: case TASKDEV_ST_KILLING:
case TASKDEV_ST_GARBAGE: case TASKDEV_ST_GARBAGE:
case TASKDEV_ST_DELREQ: case TASKDEV_ST_DELREQ:
/* on the kill process. wait until it becomes NOTASK. */ /* on the kill process. wait until it becomes NOTASK. */
up_write(&dev->state_sem); up_write(&dev->state_sem);
mutex_unlock(&dev->usecount_lock); mutex_unlock(&dev->usecount_lock);
if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0) if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
return -EINTR; return -EINTR;
devstate_write_unlock(dev); devstate_write_unlock(dev);
goto restart; goto restart;
} }
/* NOTASK */ /* NOTASK */
dev->state = TASKDEV_ST_ADDREQ; set_taskdev_state(dev, TASKDEV_ST_ADDREQ);
/* wake up twch daemon for tadd */ /* wake up twch daemon for tadd */
dsp_twch_touch(); dsp_twch_touch();
up_write(&dev->state_sem); up_write(&dev->state_sem);
if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED | if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
TASKDEV_ST_ADDFAIL) < 0) { TASKDEV_ST_ADDFAIL) < 0) {
/* cancelled */ /* cancelled */
if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) { if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
mutex_unlock(&dev->usecount_lock); mutex_unlock(&dev->usecount_lock);
/* out of control ??? */ /* out of control ??? */
return -EINTR; return -EINTR;
} }
dev->state = TASKDEV_ST_NOTASK; set_taskdev_state(dev, TASKDEV_ST_NOTASK);
ret = -EINTR; ret = -EINTR;
goto change_out; goto change_out;
} }
...@@ -1515,11 +1448,11 @@ restart: ...@@ -1515,11 +1448,11 @@ restart:
printk(KERN_ERR "omapdsp: task attach failed for %s!\n", printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
dev->name); dev->name);
ret = -EBUSY; ret = -EBUSY;
dev->state = TASKDEV_ST_NOTASK; set_taskdev_state(dev, TASKDEV_ST_NOTASK);
goto change_out; goto change_out;
} }
attached: attached:
/* ATTACHED */ /* ATTACHED */
#ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN #ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN
if (dev->usecount > 0) { if (dev->usecount > 0) {
...@@ -1527,8 +1460,12 @@ attached: ...@@ -1527,8 +1460,12 @@ attached:
return -EBUSY; return -EBUSY;
} }
#endif #endif
ret = proc_list_add(&dev->proc_list_lock,
&dev->proc_list, current, file);
if (ret)
goto out;
dev->usecount++; dev->usecount++;
proc_list_add(&dev->proc_list_lock, &dev->proc_list, current, file);
file->f_op = &dev->fops; file->f_op = &dev->fops;
up_write(&dev->state_sem); up_write(&dev->state_sem);
mutex_unlock(&dev->usecount_lock); mutex_unlock(&dev->usecount_lock);
...@@ -1539,8 +1476,9 @@ attached: ...@@ -1539,8 +1476,9 @@ attached:
#endif /* DSP_PTE_FREE */ #endif /* DSP_PTE_FREE */
return 0; return 0;
change_out: change_out:
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
out:
up_write(&dev->state_sem); up_write(&dev->state_sem);
mutex_unlock(&dev->usecount_lock); mutex_unlock(&dev->usecount_lock);
return ret; return ret;
...@@ -1576,14 +1514,14 @@ static int dsp_task_release(struct inode *inode, struct file *file) ...@@ -1576,14 +1514,14 @@ static int dsp_task_release(struct inode *inode, struct file *file)
break; break;
case TASKDEV_ST_GARBAGE: case TASKDEV_ST_GARBAGE:
dev->state = TASKDEV_ST_NOTASK; set_taskdev_state(dev, TASKDEV_ST_NOTASK);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
break; break;
case TASKDEV_ST_ATTACHED: case TASKDEV_ST_ATTACHED:
case TASKDEV_ST_FREEZED: case TASKDEV_ST_FREEZED:
if (is_dynamic_task(minor)) { if (is_dynamic_task(minor)) {
dev->state = TASKDEV_ST_DELREQ; set_taskdev_state(dev, TASKDEV_ST_DELREQ);
/* wake up twch daemon for tdel */ /* wake up twch daemon for tdel */
dsp_twch_touch(); dsp_twch_touch();
} }
...@@ -1706,7 +1644,7 @@ static int dsp_rmdev_minor(unsigned char minor) ...@@ -1706,7 +1644,7 @@ static int dsp_rmdev_minor(unsigned char minor)
* ATTACHED -> FREEZED can be changed under * ATTACHED -> FREEZED can be changed under
* down_read of state_sem.. * down_read of state_sem..
*/ */
dev->state = TASKDEV_ST_FREEZED; set_taskdev_state(dev, TASKDEV_ST_FREEZED);
wake_up_interruptible_all(&dev->read_wait_q); wake_up_interruptible_all(&dev->read_wait_q);
wake_up_interruptible_all(&dev->write_wait_q); wake_up_interruptible_all(&dev->write_wait_q);
wake_up_interruptible_all(&dev->tctl_wait_q); wake_up_interruptible_all(&dev->tctl_wait_q);
...@@ -1718,26 +1656,27 @@ static int dsp_rmdev_minor(unsigned char minor) ...@@ -1718,26 +1656,27 @@ static int dsp_rmdev_minor(unsigned char minor)
switch (dev->state & TASKDEV_ST_STATE_MASK) { switch (dev->state & TASKDEV_ST_STATE_MASK) {
case TASKDEV_ST_NOTASK: case TASKDEV_ST_NOTASK:
case TASKDEV_ST_INVALID:
/* fine */ /* fine */
goto notask; goto notask;
case TASKDEV_ST_ATTACHED: case TASKDEV_ST_ATTACHED:
case TASKDEV_ST_FREEZED: case TASKDEV_ST_FREEZED:
/* task is working. kill it. */ /* task is working. kill it. */
dev->state = TASKDEV_ST_KILLING; set_taskdev_state(dev, TASKDEV_ST_KILLING);
up_write(&dev->state_sem); up_write(&dev->state_sem);
dsp_tdel_bh(dev, TDEL_KILL); dsp_tdel_bh(dev, TDEL_KILL);
goto invalidate; goto invalidate;
case TASKDEV_ST_ADDREQ: case TASKDEV_ST_ADDREQ:
/* open() is waiting. drain it. */ /* open() is waiting. drain it. */
dev->state = TASKDEV_ST_ADDFAIL; set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
break; break;
case TASKDEV_ST_DELREQ: case TASKDEV_ST_DELREQ:
/* nobody is waiting. */ /* nobody is waiting. */
dev->state = TASKDEV_ST_NOTASK; set_taskdev_state(dev, TASKDEV_ST_NOTASK);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
break; break;
...@@ -1762,7 +1701,7 @@ invalidate: ...@@ -1762,7 +1701,7 @@ invalidate:
devstate_name(dev->state), dev->name); devstate_name(dev->state), dev->name);
} }
notask: notask:
dev->state = TASKDEV_ST_INVALID; set_taskdev_state(dev, TASKDEV_ST_INVALID);
devstate_read_unlock(dev); devstate_read_unlock(dev);
taskdev_delete(minor); taskdev_delete(minor);
...@@ -1771,7 +1710,7 @@ notask: ...@@ -1771,7 +1710,7 @@ notask:
return 0; return 0;
} }
struct file_operations dsp_task_fops = { static struct file_operations dsp_task_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.poll = dsp_task_poll, .poll = dsp_task_poll,
.ioctl = dsp_task_ioctl, .ioctl = dsp_task_ioctl,
...@@ -1786,6 +1725,7 @@ static void dsptask_dev_release(struct device *dev) ...@@ -1786,6 +1725,7 @@ static void dsptask_dev_release(struct device *dev)
static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor) static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
{ {
int ret; int ret;
struct device *task_dev;
taskdev[minor] = dev; taskdev[minor] = dev;
...@@ -1804,7 +1744,7 @@ static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor) ...@@ -1804,7 +1744,7 @@ static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
strncpy(dev->name, name, TNM_LEN); strncpy(dev->name, name, TNM_LEN);
dev->name[TNM_LEN-1] = '\0'; dev->name[TNM_LEN-1] = '\0';
dev->state = (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK; set_taskdev_state(dev, (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK);
dev->usecount = 0; dev->usecount = 0;
mutex_init(&dev->usecount_lock); mutex_init(&dev->usecount_lock);
memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations)); memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
...@@ -1814,21 +1754,43 @@ static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor) ...@@ -1814,21 +1754,43 @@ static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
sprintf(dev->dev.bus_id, "dsptask%d", minor); sprintf(dev->dev.bus_id, "dsptask%d", minor);
dev->dev.release = dsptask_dev_release; dev->dev.release = dsptask_dev_release;
ret = device_register(&dev->dev); ret = device_register(&dev->dev);
if (ret) if (ret) {
printk(KERN_ERR "device_register failed: %d\n", ret); printk(KERN_ERR "device_register failed: %d\n", ret);
return ret;
}
ret = device_create_file(&dev->dev, &dev_attr_devname); ret = device_create_file(&dev->dev, &dev_attr_devname);
ret |= device_create_file(&dev->dev, &dev_attr_devstate);
ret |= device_create_file(&dev->dev, &dev_attr_proc_list);
if (ret) if (ret)
printk(KERN_ERR "device_create_file failed: %d\n", ret); goto fail_create_devname;
device_create(dsp_task_class, NULL, ret = device_create_file(&dev->dev, &dev_attr_devstate);
MKDEV(OMAP_DSP_TASK_MAJOR, minor), if (ret)
"dsptask%d", minor); goto fail_create_devstate;
ret = device_create_file(&dev->dev, &dev_attr_proc_list);
if (ret)
goto fail_create_proclist;
task_dev = device_create(dsp_task_class, NULL,
MKDEV(OMAP_DSP_TASK_MAJOR, minor),
"dsptask%d", (int)minor);
if (unlikely(IS_ERR(task_dev))) {
ret = -EINVAL;
goto fail_create_taskclass;
}
init_waitqueue_head(&dev->state_wait_q); init_waitqueue_head(&dev->state_wait_q);
init_rwsem(&dev->state_sem); init_rwsem(&dev->state_sem);
return 0; return 0;
fail_create_taskclass:
device_remove_file(&dev->dev, &dev_attr_proc_list);
fail_create_proclist:
device_remove_file(&dev->dev, &dev_attr_devstate);
fail_create_devstate:
device_remove_file(&dev->dev, &dev_attr_devname);
fail_create_devname:
device_unregister(&dev->dev);
return ret;
} }
static void taskdev_delete(unsigned char minor) static void taskdev_delete(unsigned char minor)
...@@ -1853,17 +1815,17 @@ static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task) ...@@ -1853,17 +1815,17 @@ static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
dev->fops.read = dev->fops.read =
sndtyp_acv(ttyp) ? sndtyp_acv(ttyp) ?
sndtyp_wd(ttyp) ? dsp_task_read_wd_acv: sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
/* sndtyp_bk */ dsp_task_read_bk_acv: /* sndtyp_bk */ dsp_task_read_bk_acv:
/* sndtyp_psv */ /* sndtyp_psv */
sndtyp_wd(ttyp) ? dsp_task_read_wd_psv: sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
/* sndtyp_bk */ dsp_task_read_bk_psv; /* sndtyp_bk */ dsp_task_read_bk_psv;
if (sndtyp_wd(ttyp)) { if (sndtyp_wd(ttyp)) {
/* word */ /* word */
size_t fifosz; size_t fifosz;
fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */ fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
32; /* active */ 32; /* active */
if (init_fifo(&dev->rcvdt.fifo, fifosz) < 0) { if (init_fifo(&dev->rcvdt.fifo, fifosz) < 0) {
printk(KERN_ERR printk(KERN_ERR
"omapdsp: unable to allocate receive buffer. " "omapdsp: unable to allocate receive buffer. "
...@@ -1880,29 +1842,72 @@ static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task) ...@@ -1880,29 +1842,72 @@ static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
rcvtyp_wd(ttyp) ? dsp_task_write_wd: rcvtyp_wd(ttyp) ? dsp_task_write_wd:
/* rcvbyp_bk */ dsp_task_write_bk; /* rcvbyp_bk */ dsp_task_write_bk;
dev->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */ dev->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
rcvtyp_wd(ttyp) ? 2 : /* passive word */ rcvtyp_wd(ttyp) ? 2 : /* passive word */
ipbcfg.lsz*2; /* passive block */ ipbcfg.lsz*2; /* passive block */
if (task->map_length) if (task->map_length)
dev->fops.mmap = dsp_task_mmap; dev->fops.mmap = dsp_task_mmap;
ret = device_create_file(&dev->dev, &dev_attr_taskname); ret = device_create_file(&dev->dev, &dev_attr_taskname);
ret |= device_create_file(&dev->dev, &dev_attr_ttyp); if (unlikely(ret))
goto fail_create_taskname;
ret = device_create_file(&dev->dev, &dev_attr_ttyp);
if (unlikely(ret))
goto fail_create_ttyp;
ret = device_create_file(&dev->dev, &dev_attr_wsz);
if (unlikely(ret))
goto fail_create_wsz;
if (task->map_length) {
ret = device_create_file(&dev->dev, &dev_attr_mmap);
if (unlikely(ret))
goto fail_create_mmap;
}
if (sndtyp_wd(ttyp)) { if (sndtyp_wd(ttyp)) {
ret |= device_create_file(&dev->dev, &dev_attr_fifosz); ret = device_create_file(&dev->dev, &dev_attr_fifosz);
ret |= device_create_file(&dev->dev, &dev_attr_fifocnt); if (unlikely(ret))
} else goto fail_create_fifosz;
ret |= device_create_file(&dev->dev, &dev_attr_ipblink); ret = device_create_file(&dev->dev, &dev_attr_fifocnt);
ret |= device_create_file(&dev->dev, &dev_attr_wsz); if (unlikely(ret))
if (task->map_length) goto fail_create_fifocnt;
ret |= device_create_file(&dev->dev, &dev_attr_mmap); } else {
if (ret) ret = device_create_file(&dev->dev, &dev_attr_ipblink);
printk(KERN_ERR "device_create_file failed: %d\n", ret); if (unlikely(ret))
goto fail_create_ipblink;
}
dev->task = task; dev->task = task;
task->dev = dev; task->dev = dev;
return 0; return 0;
fail_create_fifocnt:
device_remove_file(&dev->dev, &dev_attr_fifosz);
fail_create_ipblink:
fail_create_fifosz:
if (task->map_length)
device_remove_file(&dev->dev, &dev_attr_mmap);
fail_create_mmap:
device_remove_file(&dev->dev, &dev_attr_wsz);
fail_create_wsz:
device_remove_file(&dev->dev, &dev_attr_ttyp);
fail_create_ttyp:
device_remove_file(&dev->dev, &dev_attr_taskname);
fail_create_taskname:
if (task->map_length)
dev->fops.mmap = NULL;
dev->fops.write = NULL;
dev->wsz = 0;
dev->fops.read = NULL;
taskdev_flush_buf(dev);
if (sndtyp_wd(ttyp))
free_fifo(&dev->rcvdt.fifo);
dev->task = NULL;
return ret;
} }
static void taskdev_detach_task(struct taskdev *dev) static void taskdev_detach_task(struct taskdev *dev)
...@@ -1917,8 +1922,10 @@ static void taskdev_detach_task(struct taskdev *dev) ...@@ -1917,8 +1922,10 @@ static void taskdev_detach_task(struct taskdev *dev)
} else } else
device_remove_file(&dev->dev, &dev_attr_ipblink); device_remove_file(&dev->dev, &dev_attr_ipblink);
device_remove_file(&dev->dev, &dev_attr_wsz); device_remove_file(&dev->dev, &dev_attr_wsz);
if (dev->task->map_length) if (dev->task->map_length) {
device_remove_file(&dev->dev, &dev_attr_mmap); device_remove_file(&dev->dev, &dev_attr_mmap);
dev->fops.mmap = NULL;
}
dev->fops.read = NULL; dev->fops.read = NULL;
taskdev_flush_buf(dev); taskdev_flush_buf(dev);
...@@ -1928,7 +1935,7 @@ static void taskdev_detach_task(struct taskdev *dev) ...@@ -1928,7 +1935,7 @@ static void taskdev_detach_task(struct taskdev *dev)
dev->fops.write = NULL; dev->fops.write = NULL;
dev->wsz = 0; dev->wsz = 0;
printk(KERN_INFO "omapdsp: taskdev %s disabled.\n", dev->name); pr_info("omapdsp: taskdev %s disabled.\n", dev->name);
dev->task = NULL; dev->task = NULL;
} }
...@@ -1949,12 +1956,12 @@ static int dsp_tadd(struct taskdev *dev, dsp_long_t adr) ...@@ -1949,12 +1956,12 @@ static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
"(state is %s)\n", dev->name, devstate_name(dev->state)); "(state is %s)\n", dev->name, devstate_name(dev->state));
return -EINVAL; return -EINVAL;
} }
dev->state = TASKDEV_ST_ADDING; set_taskdev_state(dev, TASKDEV_ST_ADDING);
devstate_write_unlock(dev); devstate_write_unlock(dev);
if (adr == TADD_ABORTADR) { if (adr == TADD_ABORTADR) {
/* aborting tadd intentionally */ /* aborting tadd intentionally */
printk(KERN_INFO "omapdsp: tadd address is ABORTADR.\n"); pr_info("omapdsp: tadd address is ABORTADR.\n");
goto fail_out; goto fail_out;
} }
if (adr >= DSPSPACE_SIZE) { if (adr >= DSPSPACE_SIZE) {
...@@ -2020,8 +2027,8 @@ static int dsp_tadd(struct taskdev *dev, dsp_long_t adr) ...@@ -2020,8 +2027,8 @@ static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
goto free_out; goto free_out;
dsp_task_init(task); dsp_task_init(task);
printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name); pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
dev->state = TASKDEV_ST_ATTACHED; set_taskdev_state(dev, TASKDEV_ST_ATTACHED);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
return 0; return 0;
...@@ -2031,7 +2038,7 @@ free_out: ...@@ -2031,7 +2038,7 @@ free_out:
del_out: del_out:
printk(KERN_ERR "omapdsp: deleting the task...\n"); printk(KERN_ERR "omapdsp: deleting the task...\n");
dev->state = TASKDEV_ST_DELING; set_taskdev_state(dev, TASKDEV_ST_DELING);
if (mutex_lock_interruptible(&cfg_lock)) { if (mutex_lock_interruptible(&cfg_lock)) {
printk(KERN_ERR "omapdsp: aborting tdel process. " printk(KERN_ERR "omapdsp: aborting tdel process. "
...@@ -2051,7 +2058,7 @@ del_out: ...@@ -2051,7 +2058,7 @@ del_out:
"DSP side could be corrupted.\n"); "DSP side could be corrupted.\n");
fail_out: fail_out:
dev->state = TASKDEV_ST_ADDFAIL; set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
return ret; return ret;
} }
...@@ -2088,7 +2095,7 @@ static int dsp_tdel(struct taskdev *dev) ...@@ -2088,7 +2095,7 @@ static int dsp_tdel(struct taskdev *dev)
"(state is %s)\n", dev->name, devstate_name(dev->state)); "(state is %s)\n", dev->name, devstate_name(dev->state));
return -EINVAL; return -EINVAL;
} }
dev->state = TASKDEV_ST_DELING; set_taskdev_state(dev, TASKDEV_ST_DELING);
devstate_write_unlock(dev); devstate_write_unlock(dev);
return dsp_tdel_bh(dev, TDEL_SAFE); return dsp_tdel_bh(dev, TDEL_SAFE);
...@@ -2130,7 +2137,7 @@ static int dsp_tkill(struct taskdev *dev) ...@@ -2130,7 +2137,7 @@ static int dsp_tkill(struct taskdev *dev)
return -EINVAL; return -EINVAL;
} }
/* ATTACHED -> FREEZED can be changed under read semaphore. */ /* ATTACHED -> FREEZED can be changed under read semaphore. */
dev->state = TASKDEV_ST_FREEZED; set_taskdev_state(dev, TASKDEV_ST_FREEZED);
wake_up_interruptible_all(&dev->read_wait_q); wake_up_interruptible_all(&dev->read_wait_q);
wake_up_interruptible_all(&dev->write_wait_q); wake_up_interruptible_all(&dev->write_wait_q);
wake_up_interruptible_all(&dev->tctl_wait_q); wake_up_interruptible_all(&dev->tctl_wait_q);
...@@ -2152,7 +2159,7 @@ static int dsp_tkill(struct taskdev *dev) ...@@ -2152,7 +2159,7 @@ static int dsp_tkill(struct taskdev *dev)
devstate_write_unlock(dev); devstate_write_unlock(dev);
return -EINVAL; return -EINVAL;
} }
dev->state = TASKDEV_ST_KILLING; set_taskdev_state(dev, TASKDEV_ST_KILLING);
devstate_write_unlock(dev); devstate_write_unlock(dev);
return dsp_tdel_bh(dev, TDEL_KILL); return dsp_tdel_bh(dev, TDEL_KILL);
...@@ -2193,7 +2200,7 @@ static int dsp_tdel_bh(struct taskdev *dev, u16 type) ...@@ -2193,7 +2200,7 @@ static int dsp_tdel_bh(struct taskdev *dev, u16 type)
tid = task->tid; tid = task->tid;
if (mutex_lock_interruptible(&cfg_lock)) { if (mutex_lock_interruptible(&cfg_lock)) {
if (type == TDEL_SAFE) { if (type == TDEL_SAFE) {
dev->state = TASKDEV_ST_DELREQ; set_taskdev_state(dev, TASKDEV_ST_DELREQ);
return -EINTR; return -EINTR;
} else { } else {
tid_response = TID_ANON; tid_response = TID_ANON;
...@@ -2220,8 +2227,8 @@ detach_out: ...@@ -2220,8 +2227,8 @@ detach_out:
ret = -EINVAL; ret = -EINVAL;
} }
down_write(&dev->state_sem); down_write(&dev->state_sem);
dev->state = (dev->usecount > 0) ? TASKDEV_ST_GARBAGE : set_taskdev_state(dev, (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
TASKDEV_ST_NOTASK; TASKDEV_ST_NOTASK);
wake_up_interruptible_all(&dev->state_wait_q); wake_up_interruptible_all(&dev->state_wait_q);
up_write(&dev->state_sem); up_write(&dev->state_sem);
...@@ -2443,7 +2450,7 @@ void mbox_bksndp(struct mbcmd *mb) ...@@ -2443,7 +2450,7 @@ void mbox_bksndp(struct mbcmd *mb)
printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n"); printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n");
return; return;
} }
printk(KERN_DEBUG "mbox: ipbuf_pvt_r->a = 0x%08lx\n", pr_debug("mbox: ipbuf_pvt_r->a = 0x%08lx\n",
MKLONG(ipbp->ah, ipbp->al)); MKLONG(ipbp->ah, ipbp->al));
ipblink_add_pvt(&task->dev->rcvdt.bk.link); ipblink_add_pvt(&task->dev->rcvdt.bk.link);
wake_up_interruptible(&task->dev->read_wait_q); wake_up_interruptible(&task->dev->read_wait_q);
...@@ -2481,7 +2488,7 @@ void mbox_bkreqp(struct mbcmd *mb) ...@@ -2481,7 +2488,7 @@ void mbox_bkreqp(struct mbcmd *mb)
printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n"); printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n");
return; return;
} }
printk(KERN_DEBUG "mbox: ipbuf_pvt_w->a = 0x%08lx\n", pr_debug("mbox: ipbuf_pvt_w->a = 0x%08lx\n",
MKLONG(ipbp->ah, ipbp->al)); MKLONG(ipbp->ah, ipbp->al));
dev = task->dev; dev = task->dev;
spin_lock(&dev->wsz_lock); spin_lock(&dev->wsz_lock);
...@@ -2701,20 +2708,20 @@ void mbox_dbg(struct mbcmd *mb) ...@@ -2701,20 +2708,20 @@ void mbox_dbg(struct mbcmd *mb)
*(p++) = tmp & 0xff; *(p++) = tmp & 0xff;
if (*(p-1) == '\n') { if (*(p-1) == '\n') {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s", s); pr_info("%s", s);
p = s; p = s;
continue; continue;
} }
if (p == s_end) { if (p == s_end) {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s\n", s); pr_info("%s\n", s);
p = s; p = s;
continue; continue;
} }
} }
if (p > s) { if (p > s) {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s\n", s); pr_info("%s\n", s);
} }
if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz) if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
dbg_rp = 0; dbg_rp = 0;
...@@ -2769,20 +2776,20 @@ static void mbox_dbg_old(struct mbcmd *mb) ...@@ -2769,20 +2776,20 @@ static void mbox_dbg_old(struct mbcmd *mb)
*(p++) = tmp & 0xff; *(p++) = tmp & 0xff;
if (*(p-1) == '\n') { if (*(p-1) == '\n') {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s", s); pr_info("%s", s);
p = s; p = s;
continue; continue;
} }
if (p == s_end) { if (p == s_end) {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s\n", s); pr_info("%s\n", s);
p = s; p = s;
continue; continue;
} }
} }
if (p > s) { if (p > s) {
*p = '\0'; *p = '\0';
printk(KERN_INFO "%s\n", s); pr_info("%s\n", s);
} }
dsp_mem_disable(src); dsp_mem_disable(src);
...@@ -2909,7 +2916,7 @@ static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr, ...@@ -2909,7 +2916,7 @@ static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
} }
/* ipblink */ /* ipblink */
static __inline__ char *bid_name(u16 bid) static inline char *bid_name(u16 bid)
{ {
static char s[6]; static char s[6];
...@@ -3012,6 +3019,13 @@ int __init dsp_taskmod_init(void) ...@@ -3012,6 +3019,13 @@ int __init dsp_taskmod_init(void)
return -EINVAL; return -EINVAL;
} }
dsp_task_class = class_create(THIS_MODULE, "dsptask"); dsp_task_class = class_create(THIS_MODULE, "dsptask");
if (IS_ERR(dsp_task_class)) {
printk(KERN_ERR "omapdsp: failed to create DSP task class\n");
driver_unregister(&dsptask_driver);
bus_unregister(&dsptask_bus);
unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
return -EINVAL;
}
return 0; return 0;
} }
......
...@@ -48,28 +48,21 @@ static ssize_t dsp_twch_read(struct file *file, char __user *buf, size_t count, ...@@ -48,28 +48,21 @@ static ssize_t dsp_twch_read(struct file *file, char __user *buf, size_t count,
long taskstat[TASKDEV_MAX]; long taskstat[TASKDEV_MAX];
int devcount = count / sizeof(long); int devcount = count / sizeof(long);
int i; int i;
DEFINE_WAIT(wait);
if (dsp_cfgstat_get_stat() != CFGSTAT_READY) { if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
printk(KERN_ERR "omapdsp: dsp has not been configured.\n"); printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
return -EINVAL; return -EINVAL;
} }
if (change_cnt == 0) { prepare_to_wait(&read_wait_q, &wait, TASK_INTERRUPTIBLE);
long current_state; if (change_cnt == 0) /* last check */
DECLARE_WAITQUEUE(wait, current); schedule();
finish_wait(&read_wait_q, &wait);
add_wait_queue(&read_wait_q, &wait);
current_state = current->state; /* unconfigured while waiting ;-( */
set_current_state(TASK_INTERRUPTIBLE); if ((change_cnt == 0) && (dsp_cfgstat_get_stat() != CFGSTAT_READY))
if (change_cnt == 0) /* last check */ return -EINVAL;
schedule();
set_current_state(current_state);
remove_wait_queue(&read_wait_q, &wait);
/* unconfigured while waiting ;-( */
if (dsp_cfgstat_get_stat() != CFGSTAT_READY)
return -EINVAL;
}
if (devcount > TASKDEV_MAX) if (devcount > TASKDEV_MAX)
devcount = TASKDEV_MAX; devcount = TASKDEV_MAX;
......
...@@ -37,7 +37,7 @@ extern unsigned long __copy_to_user_dsp_2b(void __user *to, ...@@ -37,7 +37,7 @@ extern unsigned long __copy_to_user_dsp_2b(void __user *to,
#endif #endif
#ifndef HAVE_ASM_COPY_FROM_USER_DSP_2B #ifndef HAVE_ASM_COPY_FROM_USER_DSP_2B
static __inline__ unsigned long copy_from_user_dsp_2b(void *to, static inline unsigned long copy_from_user_dsp_2b(void *to,
const void *from) const void *from)
{ {
unsigned short tmp; unsigned short tmp;
...@@ -53,7 +53,7 @@ static __inline__ unsigned long copy_from_user_dsp_2b(void *to, ...@@ -53,7 +53,7 @@ static __inline__ unsigned long copy_from_user_dsp_2b(void *to,
/* /*
* @n must be multiple of 2 * @n must be multiple of 2
*/ */
static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from, static inline unsigned long copy_from_user_dsp(void *to, const void *from,
unsigned long n) unsigned long n)
{ {
if (access_ok(VERIFY_READ, from, n)) { if (access_ok(VERIFY_READ, from, n)) {
...@@ -108,7 +108,7 @@ static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from, ...@@ -108,7 +108,7 @@ static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from,
} }
#ifndef HAVE_ASM_COPY_FROM_USER_DSP_2B #ifndef HAVE_ASM_COPY_FROM_USER_DSP_2B
static __inline__ unsigned long copy_to_user_dsp_2b(void *to, const void *from) static inline unsigned long copy_to_user_dsp_2b(void *to, const void *from)
{ {
/* expecting compiler to generate "strh" instruction */ /* expecting compiler to generate "strh" instruction */
unsigned short tmp = *(unsigned short *)from; unsigned short tmp = *(unsigned short *)from;
...@@ -120,7 +120,7 @@ static __inline__ unsigned long copy_to_user_dsp_2b(void *to, const void *from) ...@@ -120,7 +120,7 @@ static __inline__ unsigned long copy_to_user_dsp_2b(void *to, const void *from)
/* /*
* @n must be multiple of 2 * @n must be multiple of 2
*/ */
static __inline__ unsigned long copy_to_user_dsp(void *to, const void *from, static inline unsigned long copy_to_user_dsp(void *to, const void *from,
unsigned long n) unsigned long n)
{ {
if (access_ok(VERIFY_WRITE, to, n)) { if (access_ok(VERIFY_WRITE, to, n)) {
......
...@@ -1239,13 +1239,13 @@ static ssize_t mempool_show(struct class *class, char *buf) ...@@ -1239,13 +1239,13 @@ static ssize_t mempool_show(struct class *class, char *buf)
static CLASS_ATTR(mempool, S_IRUGO, mempool_show, NULL); static CLASS_ATTR(mempool, S_IRUGO, mempool_show, NULL);
static void omap_mmu_class_dev_release(struct class_device *cd) static void omap_mmu_class_dev_release(struct device *dev)
{ {
} }
static struct class omap_mmu_class = { static struct class omap_mmu_class = {
.name = "mmu", .name = "mmu",
.release = omap_mmu_class_dev_release, .dev_release = omap_mmu_class_dev_release,
}; };
int omap_mmu_register(struct omap_mmu *mmu) int omap_mmu_register(struct omap_mmu *mmu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment