summaryrefslogtreecommitdiffstats
path: root/arch/m68knommu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68knommu')
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c7
-rw-r--r--arch/m68knommu/kernel/entry.S9
-rw-r--r--arch/m68knommu/kernel/setup.c2
-rw-r--r--arch/m68knommu/kernel/signal.c21
-rw-r--r--arch/m68knommu/kernel/traps.c88
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S3
-rw-r--r--arch/m68knommu/platform/5206e/config.c2
-rw-r--r--arch/m68knommu/platform/5272/config.c4
-rw-r--r--arch/m68knommu/platform/528x/config.c266
-rw-r--r--arch/m68knommu/platform/5307/config.c3
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S18
11 files changed, 358 insertions, 65 deletions
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index d97b89bae53..c785d07c02c 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -13,15 +13,11 @@
#include <linux/kernel_stat.h>
#include <linux/ptrace.h>
#include <linux/hardirq.h>
+#include <linux/kbuild.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/thread_info.h>
-#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-
-#define BLANK() asm volatile("\n->" : : )
-
int main(void)
{
/* offsets into the task struct */
@@ -91,6 +87,7 @@ int main(void)
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
return 0;
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index 1e7ea6a3e1a..f4782d2dce8 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -32,6 +32,7 @@
#include <asm/segment.h>
#include <asm/asm-offsets.h>
#include <asm/entry.h>
+#include <asm/unistd.h>
.text
@@ -140,3 +141,11 @@ ENTRY(sys_rt_sigreturn)
RESTORE_SWITCH_STACK
rts
+ENTRY(ret_from_user_signal)
+ moveq #__NR_sigreturn,%d0
+ trap #0
+
+ENTRY(ret_from_user_rt_signal)
+ move #__NR_rt_sigreturn,%d0
+ trap #0
+
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index d6f0200316f..03f4fe6a2fc 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -162,7 +162,7 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
#endif
#ifdef CONFIG_M5235EVB
- printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)");
+ printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
#endif
#ifdef DEBUG
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
index 70371378db8..bbfcae9e52b 100644
--- a/arch/m68knommu/kernel/signal.c
+++ b/arch/m68knommu/kernel/signal.c
@@ -51,6 +51,8 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+void ret_from_user_signal(void);
+void ret_from_user_rt_signal(void);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
/*
@@ -539,10 +541,6 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
return err;
}
-static inline void push_cache (unsigned long vaddr)
-{
-}
-
static inline void *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
@@ -586,16 +584,11 @@ static void setup_frame (int sig, struct k_sigaction *ka,
err |= copy_to_user (&frame->sc, &context, sizeof(context));
/* Set up to return from userspace. */
- err |= __put_user(frame->retcode, &frame->pretcode);
- /* moveq #,d0; trap #0 */
- err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
- (long *)(frame->retcode));
+ err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
if (err)
goto give_sigsegv;
- push_cache ((unsigned long) &frame->retcode);
-
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
@@ -655,17 +648,11 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
/* Set up to return from userspace. */
- err |= __put_user(frame->retcode, &frame->pretcode);
- /* moveq #,d0; notb d0; trap #0 */
- err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
- (long *)(frame->retcode + 0));
- err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+ err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
if (err)
goto give_sigsegv;
- push_cache ((unsigned long) &frame->retcode);
-
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
index 437a061d8b9..ec9aea652e7 100644
--- a/arch/m68knommu/kernel/traps.c
+++ b/arch/m68knommu/kernel/traps.c
@@ -28,6 +28,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/ptrace.h>
+#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
@@ -102,56 +103,47 @@ asmlinkage void buserr_c(struct frame *fp)
force_sig(SIGSEGV, current);
}
-
int kstack_depth_to_print = 48;
-void show_stack(struct task_struct *task, unsigned long *stack)
+static void __show_stack(struct task_struct *task, unsigned long *stack)
{
unsigned long *endstack, addr;
- extern char _start, _etext;
+ unsigned long *last_stack;
int i;
- if (!stack) {
- if (task)
- stack = (unsigned long *)task->thread.ksp;
- else
- stack = (unsigned long *)&stack;
- }
+ if (!stack)
+ stack = (unsigned long *)task->thread.ksp;
addr = (unsigned long) stack;
endstack = (unsigned long *) PAGE_ALIGN(addr);
printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) {
- if (stack + 1 > endstack)
+ if (stack + 1 + i > endstack)
break;
if (i % 8 == 0)
printk("\n" KERN_EMERG " ");
- printk(" %08lx", *stack++);
+ printk(" %08lx", *(stack + i));
}
printk("\n");
- printk(KERN_EMERG "Call Trace:");
- i = 0;
- while (stack + 1 <= endstack) {
- addr = *stack++;
- /*
- * If the address is either in the text segment of the
- * kernel, or in the region which contains vmalloc'ed
- * memory, it *may* be the address of a calling
- * routine; if so, print it so that someone tracing
- * down the cause of the crash will be able to figure
- * out the call path that was taken.
- */
- if (((addr >= (unsigned long) &_start) &&
- (addr <= (unsigned long) &_etext))) {
- if (i % 4 == 0)
- printk("\n" KERN_EMERG " ");
- printk(" [<%08lx>]", addr);
- i++;
- }
+#ifdef CONFIG_FRAME_POINTER
+ printk(KERN_EMERG "Call Trace:\n");
+
+ last_stack = stack - 1;
+ while (stack <= endstack && stack > last_stack) {
+
+ addr = *(stack + 1);
+ printk(KERN_EMERG " [%08lx] ", addr);
+ print_symbol(KERN_CONT "%s\n", addr);
+
+ last_stack = stack;
+ stack = (unsigned long *)*stack;
}
printk("\n");
+#else
+ printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic call trace\n");
+#endif
}
void bad_super_trap(struct frame *fp)
@@ -298,19 +290,47 @@ asmlinkage void set_esp0(unsigned long ssp)
current->thread.esp0 = ssp;
}
-
/*
* The architecture-independent backtrace generator
*/
void dump_stack(void)
{
- unsigned long stack;
+ /*
+ * We need frame pointers for this little trick, which works as follows:
+ *
+ * +------------+ 0x00
+ * | Next SP | -> 0x0c
+ * +------------+ 0x04
+ * | Caller |
+ * +------------+ 0x08
+ * | Local vars | -> our stack var
+ * +------------+ 0x0c
+ * | Next SP | -> 0x18, that is what we pass to show_stack()
+ * +------------+ 0x10
+ * | Caller |
+ * +------------+ 0x14
+ * | Local vars |
+ * +------------+ 0x18
+ * | ... |
+ * +------------+
+ */
- show_stack(current, &stack);
-}
+ unsigned long *stack;
+ stack = (unsigned long *)&stack;
+ stack++;
+ __show_stack(current, stack);
+}
EXPORT_SYMBOL(dump_stack);
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+ if (!stack && !task)
+ dump_stack();
+ else
+ __show_stack(task, stack);
+}
+
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpemu_signal(int signal, int code, void *addr)
{
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index b44edb08e21..5592e0bf951 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -64,6 +64,7 @@ SECTIONS {
_stext = . ;
TEXT_TEXT
SCHED_TEXT
+ LOCK_TEXT
*(.text.lock)
. = ALIGN(16); /* Exception table */
@@ -73,6 +74,7 @@ SECTIONS {
*(.rodata) *(.rodata.*)
*(__vermagic) /* Kernel version magic */
+ *(__markers_strings)
*(.rodata1)
*(.rodata.str1.1)
@@ -182,6 +184,7 @@ SECTIONS {
*(COMMON)
. = ALIGN(4) ;
_ebss = . ;
+ _end = . ;
} > BSS
}
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index a6692e958f6..d01a5d2b755 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -48,7 +48,7 @@ static struct platform_device *m5206e_devices[] __initdata = {
/***************************************************************************/
-static void __init m5206_uart_init_line(int line, int irq)
+static void __init m5206e_uart_init_line(int line, int irq)
{
if (line == 0) {
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 2aca599a1ca..230bae691a7 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -139,10 +139,6 @@ void __init config_BSP(char *commandp, int size)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
commandp[size-1] = 0;
-#elif defined(CONFIG_MTD_KeyTechnology)
- /* Copy command line from FLASH to local buffer... */
- memcpy(commandp, (char *) 0xffe06000, size);
- commandp[size-1] = 0;
#elif defined(CONFIG_CANCam)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0010000, size);
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index 036e1b73d94..dfdb5c2ed8e 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -26,9 +26,240 @@
#include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
/***************************************************************************/
void coldfire_reset(void);
+static void coldfire_qspi_cs_control(u8 cs, u8 command);
+
+/***************************************************************************/
+
+#if defined(CONFIG_SPI)
+
+#if defined(CONFIG_WILDFIRE)
+#define SPI_NUM_CHIPSELECTS 0x02
+#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */
+#define SPI_CS_MASK 0x18
+
+#define FLASH_BLOCKSIZE (1024*64)
+#define FLASH_NUMBLOCKS 16
+#define FLASH_TYPE "m25p80"
+
+#define M25P80_CS 0
+#define MMC_CS 1
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition stm25p_partitions[] = {
+ /* sflash */
+ [0] = {
+ .name = "stm25p80",
+ .offset = 0x00000000,
+ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS,
+ .mask_flags = 0
+ }
+};
+
+#endif
+
+#elif defined(CONFIG_WILDFIREMOD)
+
+#define SPI_NUM_CHIPSELECTS 0x08
+#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */
+#define SPI_CS_MASK 0x78
+
+#define FLASH_BLOCKSIZE (1024*64)
+#define FLASH_NUMBLOCKS 64
+#define FLASH_TYPE "m25p32"
+/* Reserve 1M for the kernel parition */
+#define FLASH_KERNEL_SIZE (1024 * 1024)
+
+#define M25P80_CS 5
+#define MMC_CS 6
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition stm25p_partitions[] = {
+ /* sflash */
+ [0] = {
+ .name = "kernel",
+ .offset = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE,
+ .size = FLASH_KERNEL_SIZE,
+ .mask_flags = 0
+ },
+ [1] = {
+ .name = "image",
+ .offset = 0x00000000,
+ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE,
+ .mask_flags = 0
+ },
+ [2] = {
+ .name = "all",
+ .offset = 0x00000000,
+ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS,
+ .mask_flags = 0
+ }
+};
+#endif
+
+#else
+#define SPI_NUM_CHIPSELECTS 0x04
+#define SPI_PAR_VAL 0x7F /* Enable DIN, DOUT, CLK, CS0 - CS4 */
+#endif
+
+#ifdef MMC_CS
+static struct coldfire_spi_chip flash_chip_info = {
+ .mode = SPI_MODE_0,
+ .bits_per_word = 16,
+ .del_cs_to_clk = 17,
+ .del_after_trans = 1,
+ .void_write_data = 0
+};
+
+static struct coldfire_spi_chip mmc_chip_info = {
+ .mode = SPI_MODE_0,
+ .bits_per_word = 16,
+ .del_cs_to_clk = 17,
+ .del_after_trans = 1,
+ .void_write_data = 0xFFFF
+};
+#endif
+
+#ifdef M25P80_CS
+static struct flash_platform_data stm25p80_platform_data = {
+ .name = "ST M25P80 SPI Flash chip",
+#ifdef CONFIG_MTD_PARTITIONS
+ .parts = stm25p_partitions,
+ .nr_parts = sizeof(stm25p_partitions) / sizeof(*stm25p_partitions),
+#endif
+ .type = FLASH_TYPE
+};
+#endif
+
+static struct spi_board_info spi_board_info[] __initdata = {
+#ifdef M25P80_CS
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 16000000,
+ .bus_num = 1,
+ .chip_select = M25P80_CS,
+ .platform_data = &stm25p80_platform_data,
+ .controller_data = &flash_chip_info
+ },
+#endif
+#ifdef MMC_CS
+ {
+ .modalias = "mmc_spi",
+ .max_speed_hz = 16000000,
+ .bus_num = 1,
+ .chip_select = MMC_CS,
+ .controller_data = &mmc_chip_info
+ }
+#endif
+};
+
+static struct coldfire_spi_master coldfire_master_info = {
+ .bus_num = 1,
+ .num_chipselect = SPI_NUM_CHIPSELECTS,
+ .irq_source = MCF5282_QSPI_IRQ_SOURCE,
+ .irq_vector = MCF5282_QSPI_IRQ_VECTOR,
+ .irq_mask = ((0x01 << MCF5282_QSPI_IRQ_SOURCE) | 0x01),
+ .irq_lp = 0x2B, /* Level 5 and Priority 3 */
+ .par_val = SPI_PAR_VAL,
+ .cs_control = coldfire_qspi_cs_control,
+};
+
+static struct resource coldfire_spi_resources[] = {
+ [0] = {
+ .name = "qspi-par",
+ .start = MCF5282_QSPI_PAR,
+ .end = MCF5282_QSPI_PAR,
+ .flags = IORESOURCE_MEM
+ },
+
+ [1] = {
+ .name = "qspi-module",
+ .start = MCF5282_QSPI_QMR,
+ .end = MCF5282_QSPI_QMR + 0x18,
+ .flags = IORESOURCE_MEM
+ },
+
+ [2] = {
+ .name = "qspi-int-level",
+ .start = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE,
+ .end = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE,
+ .flags = IORESOURCE_MEM
+ },
+
+ [3] = {
+ .name = "qspi-int-mask",
+ .start = MCF5282_INTC0 + MCFINTC_IMRL,
+ .end = MCF5282_INTC0 + MCFINTC_IMRL,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device coldfire_spi = {
+ .name = "spi_coldfire",
+ .id = -1,
+ .resource = coldfire_spi_resources,
+ .num_resources = ARRAY_SIZE(coldfire_spi_resources),
+ .dev = {
+ .platform_data = &coldfire_master_info,
+ }
+};
+
+static void coldfire_qspi_cs_control(u8 cs, u8 command)
+{
+ u8 cs_bit = ((0x01 << cs) << 3) & SPI_CS_MASK;
+
+#if defined(CONFIG_WILDFIRE)
+ u8 cs_mask = ~(((0x01 << cs) << 3) & SPI_CS_MASK);
+#endif
+#if defined(CONFIG_WILDFIREMOD)
+ u8 cs_mask = (cs << 3) & SPI_CS_MASK;
+#endif
+
+ /*
+ * Don't do anything if the chip select is not
+ * one of the port qs pins.
+ */
+ if (command & QSPI_CS_INIT) {
+#if defined(CONFIG_WILDFIRE)
+ MCF5282_GPIO_DDRQS |= cs_bit;
+ MCF5282_GPIO_PQSPAR &= ~cs_bit;
+#endif
+
+#if defined(CONFIG_WILDFIREMOD)
+ MCF5282_GPIO_DDRQS |= SPI_CS_MASK;
+ MCF5282_GPIO_PQSPAR &= ~SPI_CS_MASK;
+#endif
+ }
+
+ if (command & QSPI_CS_ASSERT) {
+ MCF5282_GPIO_PORTQS &= ~SPI_CS_MASK;
+ MCF5282_GPIO_PORTQS |= cs_mask;
+ } else if (command & QSPI_CS_DROP) {
+ MCF5282_GPIO_PORTQS |= SPI_CS_MASK;
+ }
+}
+
+static int __init spi_dev_init(void)
+{
+ int retval;
+
+ retval = platform_device_register(&coldfire_spi);
+ if (retval < 0)
+ return retval;
+
+ if (ARRAY_SIZE(spi_board_info))
+ retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ return retval;
+}
+
+#endif /* CONFIG_SPI */
/***************************************************************************/
@@ -111,10 +342,43 @@ void mcf_autovector(unsigned int vec)
/***************************************************************************/
+#ifdef CONFIG_WILDFIRE
+void wildfire_halt(void)
+{
+ writeb(0, 0x30000007);
+ writeb(0x2, 0x30000007);
+}
+#endif
+
+#ifdef CONFIG_WILDFIREMOD
+void wildfiremod_halt(void)
+{
+ printk(KERN_INFO "WildFireMod hibernating...\n");
+
+ /* Set portE.5 to Digital IO */
+ MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
+
+ /* Make portE.5 an output */
+ MCF5282_GPIO_DDRE |= (1 << 5);
+
+ /* Now toggle portE.5 from low to high */
+ MCF5282_GPIO_PORTE &= ~(1 << 5);
+ MCF5282_GPIO_PORTE |= (1 << 5);
+
+ printk(KERN_EMERG "Failed to hibernate. Halting!\n");
+}
+#endif
+
void __init config_BSP(char *commandp, int size)
{
mcf_disableall();
- mach_reset = coldfire_reset;
+
+#ifdef CONFIG_WILDFIRE
+ mach_halt = wildfire_halt;
+#endif
+#ifdef CONFIG_WILDFIREMOD
+ mach_halt = wildfiremod_halt;
+#endif
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 92dc862fa82..11cff6625dc 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -124,8 +124,7 @@ void __init config_BSP(char *commandp, int size)
mcf_setimr(MCFSIM_IMR_MASKALL);
#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
- defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
- defined(CONFIG_CLEOPATRA)
+ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
commandp[size-1] = 0;
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index 111b66dc737..1e3c0dcbd7a 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -103,9 +103,26 @@ ret_from_signal:
addql #4,%sp
ret_from_exception:
+ move #0x2700,%sr /* disable intrs */
btst #5,%sp@(PT_SR) /* check if returning to kernel */
jeq Luser_return /* if so, skip resched, signals */
+#ifdef CONFIG_PREEMPT
+ movel %sp,%d1 /* get thread_info pointer */
+ andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
+ movel %d1,%a0
+ movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
+ andl #_TIF_NEED_RESCHED,%d1
+ jeq Lkernel_return
+
+ movel %a0@(TI_PREEMPTCOUNT),%d1
+ cmpl #0,%d1
+ jne Lkernel_return
+
+ pea Lkernel_return
+ jmp preempt_schedule_irq /* preempt the kernel */
+#endif
+
Lkernel_return:
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
@@ -140,6 +157,7 @@ Lreturn:
Lwork_to_do:
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
+ move #0x2000,%sr /* enable intrs again */
btst #TIF_NEED_RESCHED,%d1
jne reschedule