summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/vfp/vfp.h2
-rw-r--r--arch/arm/vfp/vfpdouble.c14
-rw-r--r--arch/cris/arch-v10/drivers/ds1302.c131
-rw-r--r--arch/cris/arch-v10/kernel/signal.c251
-rw-r--r--arch/cris/arch-v10/kernel/time.c1
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/cobalt/console.c5
-rw-r--r--arch/mips/pci/fixup-cobalt.c2
-rw-r--r--arch/powerpc/kernel/iommu.c17
-rw-r--r--arch/powerpc/kernel/prom_init.c39
-rw-r--r--arch/powerpc/mm/slb.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/x86/kernel/apm_32.c10
-rw-r--r--arch/x86/kernel/process_32.c11
-rw-r--r--arch/x86/kernel/process_64.c11
15 files changed, 219 insertions, 281 deletions
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 54a2ad6..791d023 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -361,10 +361,12 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand);
* OP_SCALAR - this operation always operates in scalar mode
* OP_SD - the instruction exceptionally writes to a single precision result.
* OP_DD - the instruction exceptionally writes to a double precision result.
+ * OP_SM - the instruction exceptionally reads from a single precision operand.
*/
#define OP_SCALAR (1 << 0)
#define OP_SD (1 << 1)
#define OP_DD (1 << 1)
+#define OP_SM (1 << 2)
struct op {
u32 (* const fn)(int dd, int dn, int dm, u32 fpscr);
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 190a09a..6cac43b 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -668,8 +668,8 @@ static struct op fops_ext[32] = {
[FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_double_fcmpz, OP_SCALAR },
[FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_double_fcmpez, OP_SCALAR },
[FEXT_TO_IDX(FEXT_FCVT)] = { vfp_double_fcvts, OP_SCALAR|OP_SD },
- [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR },
- [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR|OP_SM },
+ [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR|OP_SM },
[FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_double_ftoui, OP_SCALAR|OP_SD },
[FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_double_ftouiz, OP_SCALAR|OP_SD },
[FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_double_ftosi, OP_SCALAR|OP_SD },
@@ -1128,7 +1128,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
u32 exceptions = 0;
unsigned int dest;
unsigned int dn = vfp_get_dn(inst);
- unsigned int dm = vfp_get_dm(inst);
+ unsigned int dm;
unsigned int vecitr, veclen, vecstride;
struct op *fop;
@@ -1146,6 +1146,14 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
dest = vfp_get_dd(inst);
/*
+ * f[us]ito takes a sN operand, not a dN operand.
+ */
+ if (fop->flags & OP_SM)
+ dm = vfp_get_sm(inst);
+ else
+ dm = vfp_get_dm(inst);
+
+ /*
* If destination bank is zero, vector length is always '1'.
* ARM DDI0100F C5.1.3, C5.3.2.
*/
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
index 88eff7f..1d1936a 100644
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ b/arch/cris/arch-v10/drivers/ds1302.c
@@ -6,136 +6,9 @@
*!
*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
*!
-*! $Log: ds1302.c,v $
-*! Revision 1.18 2005/01/24 09:11:26 mikaelam
-*! Minor changes to get DS1302 RTC chip driver to work
-*!
-*! Revision 1.17 2005/01/05 06:11:22 starvik
-*! No need to do local_irq_disable after local_irq_save.
-*!
-*! Revision 1.16 2004/12/13 12:21:52 starvik
-*! Added I/O and DMA allocators from Linux 2.4
-*!
-*! Revision 1.14 2004/08/24 06:48:43 starvik
-*! Whitespace cleanup
-*!
-*! Revision 1.13 2004/05/28 09:26:59 starvik
-*! Modified I2C initialization to work in 2.6.
-*!
-*! Revision 1.12 2004/05/14 07:58:03 starvik
-*! Merge of changes from 2.4
-*!
-*! Revision 1.10 2004/02/04 09:25:12 starvik
-*! Merge of Linux 2.6.2
-*!
-*! Revision 1.9 2003/07/04 08:27:37 starvik
-*! Merge of Linux 2.5.74
-*!
-*! Revision 1.8 2003/04/09 05:20:47 starvik
-*! Merge of Linux 2.5.67
-*!
-*! Revision 1.6 2003/01/09 14:42:51 starvik
-*! Merge of Linux 2.5.55
-*!
-*! Revision 1.4 2002/12/11 13:13:57 starvik
-*! Added arch/ to v10 specific includes
-*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
-*!
-*! Revision 1.3 2002/11/20 11:56:10 starvik
-*! Merge of Linux 2.5.48
-*!
-*! Revision 1.2 2002/11/18 13:16:06 starvik
-*! Linux 2.5 port of latest 2.4 drivers
-*!
-*! Revision 1.15 2002/10/11 16:14:33 johana
-*! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the
-*! trcklecharge register.
-*!
-*! Revision 1.14 2002/10/10 12:15:38 magnusmn
-*! Added support for having the RST signal on bit g0
-*!
-*! Revision 1.13 2002/05/29 15:16:08 johana
-*! Removed unused variables.
-*!
-*! Revision 1.12 2002/04/10 15:35:25 johana
-*! Moved probe function closer to init function and marked it __init.
-*!
-*! Revision 1.11 2001/06/14 12:35:52 jonashg
-*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
-*!
-*! Revision 1.9 2001/06/14 10:00:14 jonashg
-*! No need for tempudelay to be inline anymore (had to adjust the usec to
-*! loops conversion because of this to make it slow enough to be a udelay).
-*!
-*! Revision 1.8 2001/06/14 08:06:32 jonashg
-*! Made tempudelay delay usecs (well, just a tad more).
-*!
-*! Revision 1.7 2001/06/13 14:18:11 jonashg
-*! Only allow processes with SYS_TIME capability to set time and charge.
-*!
-*! Revision 1.6 2001/06/12 15:22:07 jonashg
-*! * Made init function __init.
-*! * Parameter to out_byte() is unsigned char.
-*! * The magic number 42 has got a name.
-*! * Removed comment about /proc (nothing is exported there).
-*!
-*! Revision 1.5 2001/06/12 14:35:13 jonashg
-*! Gave the module a name and added it to printk's.
-*!
-*! Revision 1.4 2001/05/31 14:53:40 jonashg
-*! Made tempudelay() inline so that the watchdog doesn't reset (see
-*! function comment).
-*!
-*! Revision 1.3 2001/03/26 16:03:06 bjornw
-*! Needs linux/config.h
-*!
-*! Revision 1.2 2001/03/20 19:42:00 bjornw
-*! Use the ETRAX prefix on the DS1302 options
-*!
-*! Revision 1.1 2001/03/20 09:13:50 magnusmn
-*! Linux 2.4 port
-*!
-*! Revision 1.10 2000/07/05 15:38:23 bjornw
-*! Dont update kernel time when a RTC_SET_TIME is done
-*!
-*! Revision 1.9 2000/03/02 15:42:59 macce
-*! * Hack to make RTC work on all 2100/2400
-*!
-*! Revision 1.8 2000/02/23 16:59:18 torbjore
-*! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
-*!
-*! Revision 1.7 2000/01/17 15:51:43 johana
-*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
-*!
-*! Revision 1.6 1999/10/27 13:19:47 bjornw
-*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
-*! /dev/rtc calls it now.
-*!
-*! Revision 1.5 1999/10/27 12:39:37 bjornw
-*! Disabled superuser check. Anyone can now set the time.
-*!
-*! Revision 1.4 1999/09/02 13:27:46 pkj
-*! Added shadow for R_PORT_PB_CONFIG.
-*! Renamed port_g_shadow to port_g_data_shadow.
-*!
-*! Revision 1.3 1999/09/02 08:28:06 pkj
-*! Made it possible to select either port PB or the generic port for the RST
-*! signal line to the DS1302 RTC.
-*! Also make sure the RST bit is configured as output on Port PB (if used).
-*!
-*! Revision 1.2 1999/09/01 14:47:20 bjornw
-*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
-*! and set the date. Register as major 121.
-*!
-*! Revision 1.1 1999/09/01 09:45:29 bjornw
-*! Implemented a DS1302 RTC driver.
-*!
-*!
*! ---------------------------------------------------------------------------
*!
-*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN
-*!
-*! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $
+*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
*!
*!***************************************************************************/
@@ -156,6 +29,8 @@
#include <asm/rtc.h>
#include <asm/arch/io_interface_mux.h>
+#include "i2c.h"
+
#define RTC_MAJOR_NR 121 /* local major, change later */
static const char ds1302_name[] = "ds1302";
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 41d4a5f..b6be705 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -7,7 +7,7 @@
*
* Ideas also taken from arch/arm.
*
- * Copyright (C) 2000, 2001 Axis Communications AB
+ * Copyright (C) 2000-2007 Axis Communications AB
*
* Authors: Bjorn Wesen (bjornw@axis.com)
*
@@ -40,84 +40,30 @@
*/
#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
-int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
+void do_signal(int canrestart, struct pt_regs *regs);
/*
- * Atomically swap in the new signal mask, and wait for a signal. Define
+ * Atomically swap in the new signal mask, and wait for a signal. Define
* dummy arguments to be able to reach the regs argument. (Note that this
* arrangement relies on old_sigset_t occupying one register.)
*/
-int
-sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
- long srp, struct pt_regs *regs)
+int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
+ long srp, struct pt_regs *regs)
{
- sigset_t saveset;
-
mask &= _BLOCKABLE;
spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
+ current->saved_sigmask = current->blocked;
siginitset(&current->blocked, mask);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
-
- regs->r10 = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(0, &saveset, regs))
- /* We will get here twice: once to call the signal
- handler, then again to return from the
- sigsuspend system call. When calling the
- signal handler, R10 holds the signal number as
- set through do_signal. The sigsuspend call
- will return with the restored value set above;
- always -EINTR. */
- return regs->r10;
- }
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
}
-/* Define dummy arguments to be able to reach the regs argument. (Note that
- * this arrangement relies on size_t occupying one register.)
- */
-int
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
- long mof, long srp, struct pt_regs *regs)
-{
- sigset_t saveset, newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, ~_BLOCKABLE);
-
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->r10 = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(0, &saveset, regs))
- /* We will get here twice: once to call the signal
- handler, then again to return from the
- sigsuspend system call. When calling the
- signal handler, R10 holds the signal number as
- set through do_signal. The sigsuspend call
- will return with the restored value set above;
- always -EINTR. */
- return regs->r10;
- }
-}
-
-int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction *oact)
+int sys_sigaction(int sig, const struct old_sigaction __user *act,
+ struct old_sigaction *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
@@ -147,8 +93,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
return ret;
}
-int
-sys_sigaltstack(const stack_t *uss, stack_t __user *uoss)
+int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss)
{
return do_sigaltstack(uss, uoss, rdusp());
}
@@ -205,7 +150,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
/* TODO: the other ports use regs->orig_XX to disable syscall checks
* after this completes, but we don't use that mechanism. maybe we can
- * use it now ?
+ * use it now ?
*/
return err;
@@ -216,7 +161,7 @@ badframe:
/* Define dummy arguments to be able to reach the regs argument. */
-asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
+asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
long srp, struct pt_regs *regs)
{
struct sigframe __user *frame = (struct sigframe *)rdusp();
@@ -243,7 +188,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
-
+
if (restore_sigcontext(regs, &frame->sc))
goto badframe;
@@ -254,11 +199,11 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
badframe:
force_sig(SIGSEGV, current);
return 0;
-}
+}
/* Define dummy arguments to be able to reach the regs argument. */
-asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
+asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
long mof, long srp, struct pt_regs *regs)
{
struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp();
@@ -282,7 +227,7 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
-
+
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
@@ -294,14 +239,14 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
badframe:
force_sig(SIGSEGV, current);
return 0;
-}
+}
/*
* Set up a signal frame.
*/
-static int
-setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask)
+static int setup_sigcontext(struct sigcontext __user *sc,
+ struct pt_regs *regs, unsigned long mask)
{
int err = 0;
unsigned long usp = rdusp();
@@ -324,10 +269,11 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
return err;
}
-/* figure out where we want to put the new signal frame - usually on the stack */
+/* Figure out where we want to put the new signal frame
+ * - usually on the stack. */
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
unsigned long sp = rdusp();
@@ -345,15 +291,15 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
}
/* grab and setup a signal frame.
- *
+ *
* basically we stack a lot of state info, and arrange for the
* user-mode program to return to the kernel using either a
* trampoline which performs the syscall sigreturn, or a provided
* user-mode trampoline.
*/
-static void setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs)
+static int setup_frame(int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs *regs)
{
struct sigframe __user *frame;
unsigned long return_ip;
@@ -401,14 +347,15 @@ static void setup_frame(int sig, struct k_sigaction *ka,
wrusp((unsigned long)frame);
- return;
+ return 0;
give_sigsegv:
force_sigsegv(sig, current);
+ return -EFAULT;
}
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long return_ip;
@@ -443,9 +390,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* trampoline - the desired return ip is the retcode itself */
return_ip = (unsigned long)&frame->retcode;
/* This is movu.w __NR_rt_sigreturn, r9; break 13; */
- err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0));
- err |= __put_user(__NR_rt_sigreturn, (short __user*)(frame->retcode+2));
- err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
+ err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0));
+ err |= __put_user(__NR_rt_sigreturn,
+ (short __user *)(frame->retcode+2));
+ err |= __put_user(0xe93d, (short __user *)(frame->retcode+4));
}
if (err)
@@ -455,73 +403,81 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
- regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */
- regs->srp = return_ip; /* what we enter LATER */
- regs->r10 = sig; /* first argument is signo */
- regs->r11 = (unsigned long) &frame->info; /* second argument is (siginfo_t *) */
- regs->r12 = 0; /* third argument is unused */
-
- /* actually move the usp to reflect the stacked frame */
-
+ /* What we enter NOW */
+ regs->irp = (unsigned long) ka->sa.sa_handler;
+ /* What we enter LATER */
+ regs->srp = return_ip;
+ /* First argument is signo */
+ regs->r10 = sig;
+ /* Second argument is (siginfo_t *) */
+ regs->r11 = (unsigned long)&frame->info;
+ /* Third argument is unused */
+ regs->r12 = 0;
+
+ /* Actually move the usp to reflect the stacked frame */
wrusp((unsigned long)frame);
- return;
+ return 0;
give_sigsegv:
force_sigsegv(sig, current);
+ return -EFAULT;
}
/*
* OK, we're invoking a handler
- */
+ */
-static inline void
-handle_signal(int canrestart, unsigned long sig,
- siginfo_t *info, struct k_sigaction *ka,
- sigset_t *oldset, struct pt_regs * regs)
+static inline int handle_signal(int canrestart, unsigned long sig,
+ siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs *regs)
{
+ int ret;
+
/* Are we from a system call? */
if (canrestart) {
/* If so, check system call restarting.. */
switch (regs->r10) {
- case -ERESTART_RESTARTBLOCK:
- case -ERESTARTNOHAND:
- /* ERESTARTNOHAND means that the syscall should only be
- restarted if there was no handler for the signal, and since
- we only get here if there is a handler, we don't restart */
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ /* ERESTARTNOHAND means that the syscall should
+ * only be restarted if there was no handler for
+ * the signal, and since we only get here if there
+ * is a handler, we don't restart */
+ regs->r10 = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ /* ERESTARTSYS means to restart the syscall if
+ * there is no handler or the handler was
+ * registered with SA_RESTART */
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
regs->r10 = -EINTR;
break;
-
- case -ERESTARTSYS:
- /* ERESTARTSYS means to restart the syscall if there is no
- handler or the handler was registered with SA_RESTART */
- if (!(ka->sa.sa_flags & SA_RESTART)) {
- regs->r10 = -EINTR;
- break;
- }
- /* fallthrough */
- case -ERESTARTNOINTR:
- /* ERESTARTNOINTR means that the syscall should be called again
- after the signal handler returns. */
- RESTART_CRIS_SYS(regs);
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ /* ERESTARTNOINTR means that the syscall should
+ * be called again after the signal handler returns. */
+ RESTART_CRIS_SYS(regs);
}
}
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
else
- setup_frame(sig, ka, oldset, regs);
-
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
-
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked,sig);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ ret = setup_frame(sig, ka, oldset, regs);
+
+ if (ret == 0) {
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked, &current->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+ return ret;
}
/*
@@ -536,11 +492,12 @@ handle_signal(int canrestart, unsigned long sig,
* mode below.
*/
-int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
+void do_signal(int canrestart, struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
+ sigset_t *oldset;
/*
* We want the common case to go fast, which
@@ -549,16 +506,26 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
* if so.
*/
if (!user_mode(regs))
- return 1;
+ return;
- if (!oldset)
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
- handle_signal(canrestart, signr, &info, &ka, oldset, regs);
- return 1;
+ if (handle_signal(canrestart, signr, &info, &ka,
+ oldset, regs)) {
+ /* a signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+ return;
}
/* Did we come from a system call? */
@@ -569,10 +536,16 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
regs->r10 == -ERESTARTNOINTR) {
RESTART_CRIS_SYS(regs);
}
- if (regs->r10 == -ERESTART_RESTARTBLOCK){
+ if (regs->r10 == -ERESTART_RESTARTBLOCK) {
regs->r10 = __NR_restart_syscall;
regs->irp -= 2;
}
}
- return 0;
+
+ /* if there's no signal to deliver, we just put the saved sigmask
+ * back */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
}
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 5976f61..9310a7b 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -13,6 +13,7 @@
#include <linux/swap.h>
#include <linux/sched.h>
#include <linux/init.h>
+#include <linux/vmstat.h>
#include <asm/arch/svinto.h>
#include <asm/types.h>
#include <asm/signal.h>
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 291d368..b22c043 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -59,6 +59,8 @@ config BCM47XX
select SYS_SUPPORTS_LITTLE_ENDIAN
select SSB
select SSB_DRIVER_MIPS
+ select SSB_DRIVER_EXTIF
+ select SSB_PCICORE_HOSTMODE if PCI
select GENERIC_GPIO
select SYS_HAS_EARLY_PRINTK
select CFE
diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c
index db330e8..d1ba701 100644
--- a/arch/mips/cobalt/console.c
+++ b/arch/mips/cobalt/console.c
@@ -4,10 +4,15 @@
#include <linux/io.h>
#include <linux/serial_reg.h>
+#include <cobalt.h>
+
#define UART_BASE ((void __iomem *)CKSEG1ADDR(0x1c800000))
void prom_putchar(char c)
{
+ if (cobalt_board_id <= COBALT_BRD_ID_QUBE1)
+ return;
+
while (!(readb(UART_BASE + UART_LSR) & UART_LSR_THRE))
;
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index f7df114..9553b14 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -177,7 +177,7 @@ static char irq_tab_raq2[] __initdata = {
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
+ if (cobalt_board_id <= COBALT_BRD_ID_QUBE1)
return irq_tab_qube1[slot];
if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 2d0c9ef..79a85d6 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -278,6 +278,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
unsigned long flags;
struct scatterlist *s, *outs, *segstart;
int outcount, incount, i;
+ unsigned int align;
unsigned long handle;
BUG_ON(direction == DMA_NONE);
@@ -309,7 +310,12 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
/* Allocate iommu entries for that segment */
vaddr = (unsigned long) sg_virt(s);
npages = iommu_num_pages(vaddr, slen);
- entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
+ align = 0;
+ if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
+ (vaddr & ~PAGE_MASK) == 0)
+ align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+ entry = iommu_range_alloc(tbl, npages, &handle,
+ mask >> IOMMU_PAGE_SHIFT, align);
DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
@@ -572,7 +578,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
{
dma_addr_t dma_handle = DMA_ERROR_CODE;
unsigned long uaddr;
- unsigned int npages;
+ unsigned int npages, align;
BUG_ON(direction == DMA_NONE);
@@ -580,8 +586,13 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
npages = iommu_num_pages(uaddr, size);
if (tbl) {
+ align = 0;
+ if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && size >= PAGE_SIZE &&
+ ((unsigned long)vaddr & ~PAGE_MASK) == 0)
+ align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+
dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
- mask >> IOMMU_PAGE_SHIFT, 0);
+ mask >> IOMMU_PAGE_SHIFT, align);
if (dma_handle == DMA_ERROR_CODE) {
if (printk_ratelimit()) {
printk(KERN_INFO "iommu_alloc failed, "
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 1add6ef..5d89a21 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2216,6 +2216,45 @@ static void __init fixup_device_tree_efika(void)
prom_printf("fixup_device_tree_efika: ",
"skipped entry %x - setprop error\n", i);
}
+
+ /* Make sure ethernet mdio bus node exists */
+ node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
+ if (!PHANDLE_VALID(node)) {
+ prom_printf("Adding Ethernet MDIO node\n");
+ call_prom("interpret", 1, 1,
+ " s\" /builtin\" find-device"
+ " new-device"
+ " 1 encode-int s\" #address-cells\" property"
+ " 0 encode-int s\" #size-cells\" property"
+ " s\" mdio\" 2dup device-name device-type"
+ " s\" mpc5200b-fec-phy\" encode-string"
+ " s\" compatible\" property"
+ " 0xf0003000 0x400 reg"
+ " 0x2 encode-int"
+ " 0x5 encode-int encode+"
+ " 0x3 encode-int encode+"
+ " s\" interrupts\" property"
+ " finish-device");
+ };
+
+ /* Make sure ethernet phy device node exist */
+ node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio/ethernet-phy"));
+ if (!PHANDLE_VALID(node)) {
+ prom_printf("Adding Ethernet PHY node\n");
+ call_prom("interpret", 1, 1,
+ " s\" /builtin/mdio\" find-device"
+ " new-device"
+ " s\" ethernet-phy\" device-name"
+ " 0x10 encode-int s\" reg\" property"
+ " my-self"
+ " ihandle>phandle"
+ " finish-device"
+ " s\" /builtin/ethernet\" find-device"
+ " encode-int"
+ " s\" phy-handle\" property"
+ " device-end");
+ }
+
}
#else
#define fixup_device_tree_efika()
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 27922df..50d7372 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -292,6 +292,8 @@ void slb_initialize(void)
create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1);
+ slb_shadow_clear(2);
+
/* We don't bolt the stack for the time being - we're in boot,
* so the stack is in the bolted segment. By the time it goes
* elsewhere, we'll call _switch() which will bolt in the new
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index fc48b96..412e6b4 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -29,6 +29,7 @@
#include <asm/vdso_datapage.h>
#include <asm/pSeries_reconfig.h>
#include "xics.h"
+#include "plpar_wrappers.h"
/* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = {
@@ -58,6 +59,7 @@ static void pseries_mach_cpu_die(void)
local_irq_disable();
idle_task_exit();
xics_teardown_cpu(0);
+ unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
rtas_stop_self();
/* Should never get here... */
BUG();
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 17089a0..af045ca 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -2256,14 +2256,12 @@ static int __init apm_init(void)
apm_info.disabled = 1;
return -ENODEV;
}
- if (PM_IS_ACTIVE()) {
+ if (pm_flags & PM_ACPI) {
printk(KERN_NOTICE "apm: overridden by ACPI.\n");
apm_info.disabled = 1;
return -ENODEV;
}
-#ifdef CONFIG_PM_LEGACY
- pm_active = 1;
-#endif
+ pm_flags |= PM_APM;
/*
* Set up a segment that references the real mode segment 0x40
@@ -2366,9 +2364,7 @@ static void __exit apm_exit(void)
kthread_stop(kapmd_task);
kapmd_task = NULL;
}
-#ifdef CONFIG_PM_LEGACY
- pm_active = 0;
-#endif
+ pm_flags &= ~PM_APM;
}
module_init(apm_init);
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 9663c2a..46d391d 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -204,6 +204,10 @@ void cpu_idle(void)
}
}
+static void do_nothing(void *unused)
+{
+}
+
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
@@ -228,6 +232,13 @@ void cpu_idle_wait(void)
cpu_clear(cpu, map);
}
cpus_and(map, map, cpu_online_map);
+ /*
+ * We waited 1 sec, if a CPU still did not call idle
+ * it may be because it is in idle and not waking up
+ * because it has nothing to do.
+ * Give all the remaining CPUS a kick.
+ */
+ smp_call_function_mask(map, do_nothing, 0, 0);
} while (!cpus_empty(map));
set_cpus_allowed(current, tmp);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 6309b27..ab79e1d 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -135,6 +135,10 @@ static void poll_idle (void)
cpu_relax();
}
+static void do_nothing(void *unused)
+{
+}
+
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
@@ -160,6 +164,13 @@ void cpu_idle_wait(void)
cpu_clear(cpu, map);
}
cpus_and(map, map, cpu_online_map);
+ /*
+ * We waited 1 sec, if a CPU still did not call idle
+ * it may be because it is in idle and not waking up
+ * because it has nothing to do.
+ * Give all the remaining CPUS a kick.
+ */
+ smp_call_function_mask(map, do_nothing, 0, 0);
} while (!cpus_empty(map));
set_cpus_allowed(current, tmp);
OpenPOWER on IntegriCloud