X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=arch%2Fmips%2Fkernel%2Frtlx.c;h=b556419612329a26fdf4493b8d4c1ee43073d4a7;hp=0233798f71552c4c64b85e9a61e45f3aafc9fe6c;hb=e7849f16c13476288fe4fbd420975e8456c75aa0;hpb=4f4ae0d42680889c62db4e1f3e6b4aa7787a7257 diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 0233798f7155..b55641961232 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,15 @@ static void rtlx_dispatch(void) static irqreturn_t rtlx_interrupt(int irq, void *dev_id) { int i; + unsigned int flags, vpeflags; + + /* Ought not to be strictly necessary for SMTC builds */ + local_irq_save(flags); + vpeflags = dvpe(); + set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ); + irq_enable_hazard(); + evpe(vpeflags); + local_irq_restore(flags); for (i = 0; i < RTLX_CHANNELS; i++) { wake_up(&channel_wqs[i].lx_queue); @@ -108,7 +118,8 @@ static void __used dump_rtlx(void) static int rtlx_init(struct rtlx_info *rtlxi) { if (rtlxi->id != RTLX_ID) { - printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id); + printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", + rtlxi, rtlxi->id); return -ENOEXEC; } @@ -162,18 +173,17 @@ int rtlx_open(int index, int can_sleep) if (rtlx == NULL) { if( (p = vpe_get_shared(tclimit)) == NULL) { - if (can_sleep) { - __wait_event_interruptible(channel_wqs[index].lx_queue, - (p = vpe_get_shared(tclimit)), - ret); - if (ret) - goto out_fail; - } else { - printk(KERN_DEBUG "No SP program loaded, and device " - "opened with O_NONBLOCK\n"); - ret = -ENOSYS; + if (can_sleep) { + __wait_event_interruptible(channel_wqs[index].lx_queue, + (p = vpe_get_shared(tclimit)), ret); + if (ret) goto out_fail; - } + } else { + printk(KERN_DEBUG "No SP program loaded, and device " + "opened with O_NONBLOCK\n"); + ret = -ENOSYS; + goto out_fail; + } } smp_rmb(); @@ -182,7 +192,9 @@ int rtlx_open(int index, int can_sleep) DEFINE_WAIT(wait); for (;;) { - prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); + prepare_to_wait( + &channel_wqs[index].lx_queue, + &wait, TASK_INTERRUPTIBLE); smp_rmb(); if (*p != NULL) break; @@ -195,7 +207,7 @@ int rtlx_open(int index, int can_sleep) } finish_wait(&channel_wqs[index].lx_queue, &wait); } else { - printk(" *vpe_get_shared is NULL. " + pr_err(" *vpe_get_shared is NULL. " "Has an SP program been loaded?\n"); ret = -ENOSYS; goto out_fail; @@ -203,8 +215,9 @@ int rtlx_open(int index, int can_sleep) } if ((unsigned int)*p < KSEG0) { - printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " - "maybe an error code %d\n", (int)*p); + printk(KERN_WARNING "vpe_get_shared returned an " + "invalid pointer maybe an error code %d\n", + (int)*p); ret = -ENOSYS; goto out_fail; } @@ -232,6 +245,10 @@ out_ret: int rtlx_release(int index) { + if (rtlx == NULL) { + pr_err("rtlx_release() with null rtlx\n"); + return 0; + } rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; return 0; } @@ -251,8 +268,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep) int ret = 0; __wait_event_interruptible(channel_wqs[index].lx_queue, - chan->lx_read != chan->lx_write || sp_stopping, - ret); + (chan->lx_read != chan->lx_write) || + sp_stopping, ret); if (ret) return ret; @@ -282,7 +299,9 @@ static inline int write_spacefree(int read, int write, int size) unsigned int rtlx_write_poll(int index) { struct rtlx_channel *chan = &rtlx->channel[index]; - return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); + + return write_spacefree(chan->rt_read, chan->rt_write, + chan->buffer_size); } ssize_t rtlx_read(int index, void __user *buff, size_t count) @@ -344,8 +363,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count) rt_read = rt->rt_read; /* total number of bytes to copy */ - count = min(count, - (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size)); + count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write, + rt->buffer_size)); /* first bit from write pointer to the end of the buffer, or count */ fl = min(count, (size_t) rt->buffer_size - rt->rt_write); @@ -374,8 +393,12 @@ out: static int file_open(struct inode *inode, struct file *filp) { int minor = iminor(inode); + int err; - return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); + lock_kernel(); + err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); + unlock_kernel(); + return err; } static int file_release(struct inode *inode, struct file *filp) @@ -514,6 +537,11 @@ static int __init rtlx_module_init(void) if (cpu_has_vint) set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); + else { + pr_err("APRP RTLX init on non-vectored-interrupt processor\n"); + err = -ENODEV; + goto out_chrdev; + } rtlx_irq.dev_id = rtlx; setup_irq(rtlx_irq_num, &rtlx_irq);