Commit 3a05a606 authored by Toshihiro Kobayashi's avatar Toshihiro Kobayashi Committed by Paul Mundt

ARM: OMAP: DSP gateway updates.

- Add api_ck control needed for McBSP initialization.
- Bug fix for process list handling
- Conversion from internal pool allocators to mempool API.
Signed-off-by: default avatarToshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
Signed-off-by: default avatarPaul Mundt <paul.mundt@nokia.com>
parent 7a0d12e1
......@@ -280,14 +280,25 @@ static int __init omap_dsp_init(void)
return PTR_ERR(api_ck_handle);
}
/* This is needed for McBSP init, released in late_initcall */
clk_enable(api_ck_handle);
__dsp_enable();
mpui_byteswap_off();
mpui_wordswap_on();
tc_wordswap();
init_done = 1;
printk(KERN_INFO "omap_dsp_init() done\n");
return 0;
}
static int dsp_late_init(void)
{
clk_disable(api_ck_handle);
return 0;
}
late_initcall(dsp_late_init);
static void dsp_cpustat_update(void)
{
......
This diff is collapsed.
......@@ -26,20 +26,18 @@
struct proc_list {
struct list_head list_head;
struct task_struct *tsk;
pid_t pid;
unsigned int cnt;
};
static __inline__ void proc_list_add(struct list_head *list,
struct task_struct *tsk)
{
struct list_head *ptr;
struct proc_list *pl;
struct proc_list *new;
list_for_each(ptr, list) {
pl = list_entry(ptr, struct proc_list, list_head);
if (pl->tsk == tsk) {
list_for_each_entry(pl, list, list_head) {
if (pl->pid == tsk->pid) {
/*
* this process has opened DSP devices multi time
*/
......@@ -49,7 +47,7 @@ static __inline__ void proc_list_add(struct list_head *list,
}
new = kmalloc(sizeof(struct proc_list), GFP_KERNEL);
new->tsk = tsk;
new->pid = tsk->pid;
new->cnt = 1;
list_add_tail(&new->list_head, list);
}
......@@ -57,12 +55,10 @@ static __inline__ void proc_list_add(struct list_head *list,
static __inline__ void proc_list_del(struct list_head *list,
struct task_struct *tsk)
{
struct list_head *ptr;
struct proc_list *pl;
struct proc_list *pl, *next;
list_for_each(ptr, list) {
pl = list_entry(ptr, struct proc_list, list_head);
if (pl->tsk == tsk) {
list_for_each_entry(pl, list, list_head) {
if (pl->pid == tsk->pid) {
if (--pl->cnt == 0) {
list_del(&pl->list_head);
kfree(pl);
......@@ -70,6 +66,23 @@ static __inline__ void proc_list_del(struct list_head *list,
return;
}
}
/*
* correspinding pid wasn't found in the list
* -- this means the caller of proc_list_del is different from
* the proc_list_add's caller. in this case, the parent is
* cleaning up the context of a killed child.
* let's delete exiting task from the list.
*/
/* need to lock tasklist_lock before calling find_task_by_pid_type. */
read_lock(&tasklist_lock);
list_for_each_entry_safe(pl, next, list, list_head) {
if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) == NULL) {
list_del(&pl->list_head);
kfree(pl);
}
}
read_unlock(&tasklist_lock);
}
static __inline__ void proc_list_flush(struct list_head *list)
......
......@@ -273,6 +273,26 @@ static __inline__ int down_tasksem_interruptible(struct taskdev *dev,
return ret;
}
static void proclist_send_sigbus(struct list_head *list)
{
siginfo_t info;
struct proc_list *pl;
struct task_struct *tsk;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = SI_KERNEL;
info._sifields._sigfault._addr = NULL;
/* need to lock tasklist_lock before calling find_task_by_pid_type. */
read_lock(&tasklist_lock);
list_for_each_entry(pl, list, list_head) {
if ((tsk = find_task_by_pid_type(PIDTYPE_PID, pl->pid)) != NULL)
send_sig_info(SIGBUS, &info, tsk);
}
read_unlock(&tasklist_lock);
}
static int dsp_task_flush_buf(struct dsptask *task)
{
unsigned short ttyp = task->ttyp;
......@@ -1666,22 +1686,11 @@ static int dsp_rmdev_minor(unsigned char minor)
case OMAP_DSP_DEVSTATE_ATTACHED:
/* task is working. kill it. */
{
siginfo_t info;
struct proc_list *pl;
dev->state = OMAP_DSP_DEVSTATE_KILLING;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = SI_KERNEL;
info._sifields._sigfault._addr = NULL;
list_for_each_entry(pl, &dev->proc_list, list_head) {
send_sig_info(SIGBUS, &info, pl->tsk);
}
spin_unlock(&dev->state_lock);
dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
goto invalidate;
}
dev->state = OMAP_DSP_DEVSTATE_KILLING;
proclist_send_sigbus(&dev->proc_list);
spin_unlock(&dev->state_lock);
dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
goto invalidate;
case OMAP_DSP_DEVSTATE_ADDREQ:
/* open() is waiting. drain it. */
......@@ -2003,8 +2012,6 @@ int dsp_tdel(unsigned char minor)
int dsp_tkill(unsigned char minor)
{
struct taskdev *dev;
siginfo_t info;
struct proc_list *pl;
if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
printk(KERN_ERR
......@@ -2020,13 +2027,7 @@ int dsp_tkill(unsigned char minor)
return -EINVAL;
}
dev->state = OMAP_DSP_DEVSTATE_KILLING;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = SI_KERNEL;
info._sifields._sigfault._addr = NULL;
list_for_each_entry(pl, &dev->proc_list, list_head) {
send_sig_info(SIGBUS, &info, pl->tsk);
}
proclist_send_sigbus(&dev->proc_list);
spin_unlock(&dev->state_lock);
return dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
......@@ -2437,22 +2438,14 @@ void mbx1_tdel(struct mbcmd *mb)
void mbx1_err_fatal(unsigned char tid)
{
struct dsptask *task = dsptask[tid];
struct proc_list *pl;
siginfo_t info;
if ((tid >= TASKDEV_MAX) || (task == NULL)) {
printk(KERN_ERR "mbx: FATAL ERR with illegal tid! %d\n", tid);
return;
}
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = SI_KERNEL;
info._sifields._sigfault._addr = NULL;
spin_lock(&task->dev->state_lock);
list_for_each_entry(pl, &task->dev->proc_list, list_head) {
send_sig_info(SIGBUS, &info, pl->tsk);
}
proclist_send_sigbus(&task->dev->proc_list);
spin_unlock(&task->dev->state_lock);
}
......@@ -2656,7 +2649,7 @@ static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
dev = to_taskdev(d);
spin_lock(&dev->state_lock);
list_for_each_entry(pl, &dev->proc_list, list_head) {
len += sprintf(buf + len, "%d\n", pl->tsk->pid);
len += sprintf(buf + len, "%d\n", pl->pid);
}
spin_unlock(&dev->state_lock);
......
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