aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/cpu-bugs64.c2
-rw-r--r--arch/mips/kernel/irixelf.c11
-rw-r--r--arch/mips/kernel/kspd.c5
-rw-r--r--arch/mips/kernel/rtlx.c65
-rw-r--r--arch/mips/kernel/setup.c1
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/kernel/vpe.c29
8 files changed, 78 insertions, 41 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 45545be3eb8..cc0244036ae 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -56,9 +56,9 @@ obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
obj-$(CONFIG_CPU_MIPSR2) += spram.o
-obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
+obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
obj-$(CONFIG_I8259) += i8259.o
obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index a1b48af0992..02b7713cf71 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -38,7 +38,7 @@ static inline void align_mod(const int align, const int mod)
".endr\n\t"
".set pop"
:
- : GCC_IMM_ASM(align), GCC_IMM_ASM(mod));
+ : GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod));
}
static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 290d8e3a664..469c7237e5b 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -578,7 +578,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
* process and the system, here we map the page and fill the
* structure
*/
-static void irix_map_prda_page(void)
+static int irix_map_prda_page(void)
{
unsigned long v;
struct prda *pp;
@@ -587,8 +587,8 @@ static void irix_map_prda_page(void)
v = do_brk(PRDA_ADDRESS, PAGE_SIZE);
up_write(&current->mm->mmap_sem);
- if (v < 0)
- return;
+ if (v != PRDA_ADDRESS)
+ return v; /* v must be an error code */
pp = (struct prda *) v;
pp->prda_sys.t_pid = task_pid_vnr(current);
@@ -596,6 +596,8 @@ static void irix_map_prda_page(void)
pp->prda_sys.t_rpid = task_pid_vnr(current);
/* We leave the rest set to zero */
+
+ return 0;
}
@@ -781,7 +783,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* IRIX maps a page at 0x200000 which holds some system
* information. Programs depend on this.
*/
- irix_map_prda_page();
+ if (irix_map_prda_page())
+ goto out_free_dentry;
padzero(elf_bss);
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index ceb62dce1c9..b0591ae0ce5 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -257,7 +257,7 @@ void sp_work_handle_request(void)
vcwd = vpe_getcwd(tclimit);
- /* change to the cwd of the process that loaded the SP program */
+ /* change to cwd of the process that loaded the SP program */
old_fs = get_fs();
set_fs(KERNEL_DS);
sys_chdir(vcwd);
@@ -323,6 +323,9 @@ static void sp_cleanup(void)
set >>= 1;
}
}
+
+ /* Put daemon cwd back to root to avoid umount problems */
+ sys_chdir("/");
}
static int channel_open = 0;
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 0233798f715..b88f1c18ff4 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -72,6 +72,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 +117,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 +172,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 +191,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 +206,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 +214,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 +244,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 +267,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 +298,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 +362,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);
@@ -514,6 +532,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);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 39f3dfe134f..c6a063b2a0d 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -331,6 +331,7 @@ static void __init bootmem_init(void)
/*
* Determine low and high memory ranges
*/
+ max_pfn = max_low_pfn;
if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
#ifdef CONFIG_HIGHMEM
highstart_pfn = PFN_DOWN(HIGHMEM_START);
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 33780cc61ce..63370cdd3c9 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -87,8 +87,8 @@ struct plat_smp_ops *mp_ops;
__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
{
- if (ops)
- printk(KERN_WARNING "Overriding previous set SMP ops\n");
+ if (mp_ops)
+ printk(KERN_WARNING "Overriding previously set SMP ops\n");
mp_ops = ops;
}
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 39804c584ed..2794501ff30 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -269,7 +269,7 @@ static void *alloc_progmem(unsigned long len)
* This means you must tell Linux to use less memory than you
* physically have, for example by passing a mem= boot argument.
*/
- addr = pfn_to_kaddr(max_pfn);
+ addr = pfn_to_kaddr(max_low_pfn);
memset(addr, 0, len);
#else
/* simple grab some mem for now */
@@ -781,10 +781,15 @@ static int vpe_run(struct vpe * v)
/* take system out of configuration state */
clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ /*
+ * SMTC/SMVP kernels manage VPE enable independently,
+ * but uniprocessor kernels need to turn it on, even
+ * if that wasn't the pre-dvpe() state.
+ */
#ifdef CONFIG_SMP
- evpe(EVPE_ENABLE);
-#else
evpe(vpeflags);
+#else
+ evpe(EVPE_ENABLE);
#endif
emt(dmt_flag);
local_irq_restore(flags);
@@ -840,7 +845,7 @@ static int vpe_elfload(struct vpe * v)
/* Sanity checks against insmoding binaries or wrong arch,
weird elf version */
- if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
|| (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
|| !elf_check_arch(hdr)
|| hdr->e_shentsize != sizeof(*sechdrs)) {
@@ -947,12 +952,14 @@ static int vpe_elfload(struct vpe * v)
struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
for (i = 0; i < hdr->e_phnum; i++) {
- if (phdr->p_type != PT_LOAD)
- continue;
-
- memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
- memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
- phdr++;
+ if (phdr->p_type == PT_LOAD) {
+ memcpy((void *)phdr->p_paddr,
+ (char *)hdr + phdr->p_offset,
+ phdr->p_filesz);
+ memset((void *)phdr->p_paddr + phdr->p_filesz,
+ 0, phdr->p_memsz - phdr->p_filesz);
+ }
+ phdr++;
}
for (i = 0; i < hdr->e_shnum; i++) {
@@ -1107,7 +1114,7 @@ static int vpe_release(struct inode *inode, struct file *filp)
return -ENODEV;
hdr = (Elf_Ehdr *) v->pbuffer;
- if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
if (vpe_elfload(v) >= 0) {
vpe_run(v);
} else {