#include <linux/module.h>
#include <linux/init.h>
-
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/kernel_stat.h>
#include <linux/smp_lock.h>
-
#include <linux/delay.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
-
+#include <linux/timex.h>
+#include <asm/setup.h>
#include <asm/sigp.h>
#include <asm/pgalloc.h>
#include <asm/irq.h>
#include <asm/s390_ext.h>
#include <asm/cpcmd.h>
#include <asm/tlbflush.h>
+#include <asm/timer.h>
extern volatile int __cpu_logical_map[];
static struct task_struct *current_set[NR_CPUS];
-/*
- * Reboot, halt and power_off routines for SMP.
- */
-extern char vmhalt_cmd[];
-extern char vmpoff_cmd[];
-
static void smp_ext_bitcall(int, ec_bit_sig);
static void smp_ext_bitcall_others(ec_bit_sig);
/*
-5B * Structure and data for smp_call_function(). This is designed to minimise
+ * Structure and data for smp_call_function(). This is designed to minimise
* static memory requirements. It also looks cleaner.
*/
static DEFINE_SPINLOCK(call_lock);
* remote CPUs are nearly ready to execute <<func>> or are or have executed.
*
* You must not call this function with disabled interrupts or from a
- * hardware interrupt handler or from a bottom half handler.
+ * hardware interrupt handler.
*/
{
struct call_data_struct data;
if (cpus <= 0)
return 0;
- /* Can deadlock when called with interrupts disabled */
- WARN_ON(irqs_disabled());
+ /* Can deadlock when interrupts are disabled or if in wrong context */
+ WARN_ON(irqs_disabled() || in_irq());
data.func = func;
data.info = info;
if (wait)
atomic_set(&data.finished, 0);
- spin_lock(&call_lock);
+ spin_lock_bh(&call_lock);
call_data = &data;
/* Send a message to all other CPUs and wait for them to respond */
smp_ext_bitcall_others(ec_call_function);
if (wait)
while (atomic_read(&data.finished) != cpus)
cpu_relax();
- spin_unlock(&call_lock);
+ spin_unlock_bh(&call_lock);
return 0;
}
if (!cpu_online(cpu))
return -EINVAL;
+ /* Can deadlock when interrupts are disabled or if in wrong context */
+ WARN_ON(irqs_disabled() || in_irq());
+
/* disable preemption for local function call */
curr_cpu = get_cpu();
}
EXPORT_SYMBOL(smp_call_function_on);
-static inline void do_send_stop(void)
+static void do_send_stop(void)
{
int cpu, rc;
}
}
-static inline void do_store_status(void)
+static void do_store_status(void)
{
int cpu, rc;
}
}
-static inline void do_wait_for_stop(void)
+static void do_wait_for_stop(void)
{
int cpu;
void smp_send_stop(void)
{
/* Disable all interrupts/machine checks */
- __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
+ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
/* write magic number to zero page (absolute 0) */
lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
* cpus are handled.
*/
-void do_ext_call_interrupt(__u16 code)
+static void do_ext_call_interrupt(__u16 code)
{
unsigned long bits;
/*
* callback for setting/clearing control bits
*/
-void smp_ctl_bit_callback(void *info) {
+static void smp_ctl_bit_callback(void *info) {
struct ec_creg_mask_parms *pp = info;
unsigned long cregs[16];
int i;
/*
* Activate a secondary processor.
*/
-extern void init_cpu_timer(void);
-extern void init_cpu_vtimer(void);
-
int __devinit start_secondary(void *cpuvoid)
{
/* Setup the cpu */
cpu_init();
preempt_disable();
- /* init per CPU timer */
+ /* Enable TOD clock interrupts on the secondary cpu. */
init_cpu_timer();
#ifdef CONFIG_VIRT_TIMER
+ /* Enable cpu timer interrupts on the secondary cpu. */
init_cpu_vtimer();
#endif
/* Enable pfault pseudo page faults on this cpu. */
spin_unlock_irqrestore(&smp_reserve_lock, flags);
}
-static inline int
+static int
cpu_stopped(int cpu)
{
__u32 status;