summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-21 22:00:56 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-21 22:00:56 +0000
commit168660f24dfc46c2702acbe4701a446f42a59578 (patch)
treef431368afbf6b1b71809cf3fd904d800ea126f4d /arch/arm/kernel
parent6420f767924fa73b0ea267864d96820815f4ba5a (diff)
Merge with Linux 2.4.0-test5-pre3.
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile22
-rw-r--r--arch/arm/kernel/arch.c40
-rw-r--r--arch/arm/kernel/armksyms.c9
-rw-r--r--arch/arm/kernel/bios32.c2
-rw-r--r--arch/arm/kernel/dma-a5k.c99
-rw-r--r--arch/arm/kernel/dma-arc.c260
-rw-r--r--arch/arm/kernel/dma-dummy.c34
-rw-r--r--arch/arm/kernel/dma-footbridge.c88
-rw-r--r--arch/arm/kernel/dma-isa.c44
-rw-r--r--arch/arm/kernel/dma-isa.h29
-rw-r--r--arch/arm/kernel/dma-rpc.c312
-rw-r--r--arch/arm/kernel/dma.c307
-rw-r--r--arch/arm/kernel/dma.h68
-rw-r--r--arch/arm/kernel/ecard.c11
-rw-r--r--arch/arm/kernel/hw-sa1100.c18
-rw-r--r--arch/arm/kernel/oldlatches.c57
-rw-r--r--arch/arm/kernel/process.c31
-rw-r--r--arch/arm/kernel/signal.c1
-rw-r--r--arch/arm/kernel/sys_arm.c3
-rw-r--r--arch/arm/kernel/time.c6
-rw-r--r--arch/arm/kernel/traps.c3
21 files changed, 660 insertions, 784 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 7662f42ef..62c0ca60e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -8,38 +8,32 @@
HEAD_OBJ = head-$(PROCESSOR).o
ENTRY_OBJ = entry-$(PROCESSOR).o
-ifeq ($(CONFIG_ISA_DMA),y)
- ISA_DMA_OBJS += dma-isa.o
-endif
-
O_OBJS_arc = dma-arc.o oldlatches.o
-O_OBJS_a5k = dma-a5k.o
O_OBJS_rpc = dma-rpc.o
-O_OBJS_ebsa110 = dma-dummy.o
-O_OBJS_footbridge = dma.o dma-footbridge.o $(ISA_DMA_OBJS) hw-footbridge.o isa.o
-O_OBJS_clps7500 = dma-dummy.o
-O_OBJS_nexuspci = dma-dummy.o
-O_OBJS_sa1100 = dma-dummy.o hw-sa1100.o
-O_OBJS_l7200 = dma-dummy.o fiq.o
+O_OBJS_footbridge = dma-footbridge.o hw-footbridge.o isa.o
+O_OBJS_sa1100 = hw-sa1100.o
+O_OBJS_l7200 = fiq.o
O_TARGET := kernel.o
# Object file lists.
-obj-y := arch.o $(ENTRY_OBJ) irq.o process.o ptrace.o \
+obj-y := arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o \
semaphore.o setup.o signal.o sys_arm.o time.o \
traps.o $(O_OBJS_$(MACHINE))
obj-m :=
obj-n :=
obj- :=
-export-objs := armksyms.o dma.o ecard.o hw-footbridge.o hw-sa1100.o leds-$(MACHINE).o
+export-objs := armksyms.o dma.o ecard.o hw-footbridge.o \
+ hw-sa1100.o leds-$(MACHINE).o oldlatches.o
-obj-$(CONFIG_ARCH_ACORN) += dma.o ecard.o fiq.o time-acorn.o
+obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o
obj-$(CONFIG_MODULES) += armksyms.o
obj-$(CONFIG_LEDS) += leds-$(MACHINE).o
obj-$(CONFIG_ARTHUR) += arthur.o
+obj-$(CONFIG_ISA_DMA) += dma-isa.o
ifeq ($(MACHINE),nexuspci)
obj-$(CONFIG_PCI) += plx9080.o
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
index 8b67943ce..0ce6d9d21 100644
--- a/arch/arm/kernel/arch.c
+++ b/arch/arm/kernel/arch.c
@@ -8,6 +8,8 @@
*/
#include <linux/config.h>
#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
#include <linux/init.h>
#include <asm/dec21285.h>
@@ -134,8 +136,10 @@ fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
isapnp_disable = 1;
#endif
- if (params->u1.s.nr_pages != 0x2000 &&
- params->u1.s.nr_pages != 0x4000) {
+ if (params->u1.s.nr_pages != 0x02000 &&
+ params->u1.s.nr_pages != 0x04000 &&
+ params->u1.s.nr_pages != 0x08000 &&
+ params->u1.s.nr_pages != 0x10000) {
printk(KERN_WARNING "Warning: bad NeTTrom parameters "
"detected, using defaults\n");
@@ -207,6 +211,14 @@ MACHINE_END
#ifdef CONFIG_ARCH_SA1100
+static void victor_power_off(void)
+{
+ /* switch off power supply */
+ mdelay(2000);
+ GPCR = GPIO_GPIO23;
+ while (1);
+}
+
extern void select_sa1100_io_desc(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
@@ -219,9 +231,31 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
select_sa1100_io_desc();
if (machine_is_assabet()) {
+ /*
+ * On Assabet, we must probe for the Neponset board *before*
+ * paging_init() has occured to actually determine the amount
+ * of RAM available.
+ */
+ extern void map_sa1100_gpio_regs(void);
+ extern void get_assabet_scr(void);
+ map_sa1100_gpio_regs();
+ get_assabet_scr();
+
SET_BANK( 0, 0xc0000000, 32*1024*1024 );
mi->nr_banks = 1;
+ if (machine_has_neponset()) {
+ printk("Neponset expansion board detected\n");
+ /*
+ * Note that Neponset RAM is slower...
+ * and still untested.
+ * This would be a candidate for
+ * _real_ NUMA support.
+ */
+ //SET_BANK( 1, 0xd0000000, 32*1024*1024 );
+ //mi->nr_banks = 2;
+ }
+
ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( 0xc0800000, 3*1024*1024 );
@@ -297,6 +331,8 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
/* power off if any problem */
strcat( *cmdline, " panic=1" );
+
+ pm_power_off = victor_power_off;
}
}
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 5ac0743be..6723291df 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -8,13 +8,14 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
#include <linux/vt_kern.h>
#include <asm/byteorder.h>
#include <asm/elf.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/dma.h>
#include <asm/pgalloc.h>
#include <asm/proc-fns.h>
#include <asm/processor.h>
@@ -28,9 +29,6 @@ extern int dump_fpu(struct pt_regs *, struct user_fp_struct *);
extern void inswb(unsigned int port, void *to, int len);
extern void outswb(unsigned int port, const void *to, int len);
-extern unsigned int local_bh_count[NR_CPUS];
-extern unsigned int local_irq_count[NR_CPUS];
-
extern void __bad_xchg(volatile void *ptr, int size);
/*
@@ -68,6 +66,7 @@ extern void __umodsi3(void);
extern void ret_from_exception(void);
extern void fpundefinstr(void);
extern void fp_enter(void);
+
#define EXPORT_SYMBOL_ALIAS(sym,orig) \
const char __kstrtab_##sym##[] __attribute__((section(".kstrtab"))) = \
__MODULE_STRING(##sym##); \
@@ -108,6 +107,8 @@ EXPORT_SYMBOL(__bad_xchg);
EXPORT_SYMBOL(__readwrite_bug);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(pm_idle);
+EXPORT_SYMBOL(pm_power_off);
/* processor dependencies */
#ifdef MULTI_CPU
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a077f13b9..b2c644198 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -365,7 +365,7 @@ static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
/* ebsa285 host-specific stuff */
#ifdef CONFIG_ARCH_EBSA285
-static int irqmap_ebsa285[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
+static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
{
diff --git a/arch/arm/kernel/dma-a5k.c b/arch/arm/kernel/dma-a5k.c
deleted file mode 100644
index d79013af2..000000000
--- a/arch/arm/kernel/dma-a5k.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * arch/arm/kernel/dma-a5k.c
- *
- * Copyright (C) 1998 Russell King
- *
- * DMA functions specific to A5000 architecture
- */
-#include <linux/sched.h>
-#include <linux/init.h>
-
-#include <asm/dma.h>
-#include <asm/fiq.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#include "dma.h"
-
-static struct fiq_handler fh = {
- name: "floppydma"
-};
-
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
-{
- if (channel == DMA_VIRTUAL_FLOPPY)
- return 0;
- else
- return -EINVAL;
-}
-
-void arch_free_dma(dmach_t channel, dma_t *dma)
-{
- if (channel != DMA_VIRTUAL_FLOPPY)
- printk("arch_free_dma: invalid channel %d\n", channel);
-}
-
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
-{
- if (channel != DMA_VIRTUAL_FLOPPY)
- printk("arch_dma_count: invalid channel %d\n", channel);
- else {
- struct pt_regs regs;
- get_fiq_regs(&regs);
- return regs.ARM_r9;
- }
- return 0;
-}
-
-void arch_enable_dma(dmach_t channel, dma_t *dma)
-{
- if (channel != DMA_VIRTUAL_FLOPPY)
- printk("arch_enable_dma: invalid channel %d\n", channel);
- else {
- struct pt_regs regs;
- void *fiqhandler_start;
- unsigned int fiqhandler_length;
- extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
- unsigned long port);
-
- if (dma->dma_mode == DMA_MODE_READ) {
- extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
- fiqhandler_start = &floppy_fiqin_start;
- fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
- } else {
- extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
- fiqhandler_start = &floppy_fiqout_start;
- fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
- }
- if (claim_fiq(&fh)) {
- printk("floppydma: couldn't claim FIQ.\n");
- return;
- }
- memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
- regs.ARM_r9 = dma->buf.length;
- regs.ARM_r10 = __bus_to_virt(dma->buf.address);
- regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
- set_fiq_regs(&regs);
- enable_irq(dma->dma_irq);
- }
-}
-
-void arch_disable_dma(dmach_t channel, dma_t *dma)
-{
- if (channel != DMA_VIRTUAL_FLOPPY)
- printk("arch_disable_dma: invalid channel %d\n", channel);
- else {
- disable_irq(dma->dma_irq);
- release_fiq(&fh);
- }
-}
-
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
-{
- return 0;
-}
-
-void __init arch_dma_init(dma_t *dma)
-{
- dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
-}
diff --git a/arch/arm/kernel/dma-arc.c b/arch/arm/kernel/dma-arc.c
index 53ef12b1c..5a2f93b67 100644
--- a/arch/arm/kernel/dma-arc.c
+++ b/arch/arm/kernel/dma-arc.c
@@ -3,148 +3,200 @@
*
* Copyright (C) 1998-1999 Dave Gilbert / Russell King
*
- * DMA functions specific to Archimedes architecture
+ * DMA functions specific to Archimedes and A5000 architecture
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/dma.h>
+#include <asm/fiq.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include "dma.h"
-#define DEBUG
+#define DPRINTK(x...) printk(KERN_DEBUG x)
-int arch_request_dma(dmach_t channel, dma_t *dma, const char * dev_id)
+#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
+static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma)
{
- printk("arch_request_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
- if (channel == DMA_VIRTUAL_FLOPPY0 ||
- channel == DMA_VIRTUAL_FLOPPY1)
- return 0;
- else
- return -EINVAL;
-}
-
-void arch_free_dma(dmach_t channel, dma_t *dma)
-{
-}
-
-void arch_enable_dma(dmach_t channel, dma_t *dma)
-{
- printk("arch_enable_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
- switch (channel) {
-#ifdef CONFIG_BLK_DEV_FD1772
- case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
- switch (dma->dma_mode) {
- case DMA_MODE_READ: /* read */
- {
- extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
- extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
- unsigned long flags;
-#ifdef DEBUG
- printk("enable_dma fdc1772 data read\n");
-#endif
- save_flags(flags);
- cliIF();
+ DPRINTK("arc_floppy_data_enable_dma\n");
+ switch (dma->dma_mode) {
+ case DMA_MODE_READ: { /* read */
+ extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
+ extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
+ unsigned long flags;
+ DPRINTK("enable_dma fdc1772 data read\n");
+ save_flags(flags);
+ cliIF();
- memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
- &fdc1772_dma_read_end - &fdc1772_dma_read);
- fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
- enable_irq (64);
- restore_flags(flags);
- }
- break;
-
- case DMA_MODE_WRITE: /* write */
- {
- extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
- extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
- unsigned long flags;
-
-#ifdef DEBUG
- printk("enable_dma fdc1772 data write\n");
-#endif
- save_flags(flags);
- cliIF();
- memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
- &fdc1772_dma_write_end - &fdc1772_dma_write);
- fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
- enable_irq (64);
-
- restore_flags(flags);
- }
- break;
- default:
- printk ("enable_dma: dma%d not initialised\n", channel);
- return;
- }
- }
- break;
+ memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
+ &fdc1772_dma_read_end - &fdc1772_dma_read);
+ fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
+ enable_irq (64);
+ restore_flags(flags);
+ }
+ break;
- case DMA_VIRTUAL_FLOPPY1: { /* Command end FIQ - actually just sets a flag */
- /* Need to build a branch at the FIQ address */
- extern void fdc1772_comendhandler(void);
+ case DMA_MODE_WRITE: { /* write */
+ extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
+ extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
unsigned long flags;
-
- /*printk("enable_dma fdc1772 command end FIQ\n");*/
+ DPRINTK("enable_dma fdc1772 data write\n");
save_flags(flags);
cliIF();
-
- *((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); /* B fdc1772_comendhandler */
+ memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
+ &fdc1772_dma_write_end - &fdc1772_dma_write);
+ fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
+ enable_irq (64);
restore_flags(flags);
- }
- break;
-#endif
+ }
+ break;
+ default:
+ printk ("enable_dma: dma%d not initialised\n", channel);
}
}
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
+static int arc_floppy_data_get_dma_residue(dmach_t channel, dma_t *dma)
{
- switch (channel) {
-#ifdef CONFIG_BLK_DEV_FD1772
- case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
- extern unsigned int fdc1772_bytestogo;
+ extern unsigned int fdc1772_bytestogo;
+
+ /* 10/1/1999 DAG - I presume its the number of bytes left? */
+ return fdc1772_bytestogo;
+}
+
+static void arc_floppy_cmdend_enable_dma(dmach_t channel, dma_t *dma)
+{
+ /* Need to build a branch at the FIQ address */
+ extern void fdc1772_comendhandler(void);
+ unsigned long flags;
+
+ DPRINTK("arc_floppy_cmdend_enable_dma\n");
+ /*printk("enable_dma fdc1772 command end FIQ\n");*/
+ save_flags(flags);
+ cliIF();
+
+ /* B fdc1772_comendhandler */
+ *((unsigned int *)0x1c)=0xea000000 |
+ (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4);
- /* 10/1/1999 DAG - I presume its the number of bytes left? */
- return fdc1772_bytestogo;
- };
- break;
+ restore_flags(flags);
+}
+
+static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+ /* 10/1/1999 DAG - Presume whether there is an outstanding command? */
+ extern unsigned int fdc1772_fdc_int_done;
- case DMA_VIRTUAL_FLOPPY1: { /* Command completed */
- /* 10/1/1999 DAG - Presume whether there is an outstanding command? */
- extern unsigned int fdc1772_fdc_int_done;
+ * Explicit! If the int done is 0 then 1 int to go */
+ return (fdc1772_fdc_int_done==0)?1:0;
+}
- return (fdc1772_fdc_int_done==0)?1:0; /* Explicit! If the int done is 0 then 1 int to go */
- };
- break;
+static void arc_disable_dma(dmach_t channel, dma_t *dma)
+{
+ disable_irq(dma->dma_irq);
+}
+static struct dma_ops arc_floppy_data_dma_ops = {
+ type: "FIQDMA",
+ enable: arc_floppy_data_enable_dma,
+ disable: arc_disable_dma,
+ residue: arc_floppy_data_get_dma_residue,
+};
+
+static struct dma_ops arc_floppy_cmdend_dma_ops = {
+ type: "FIQCMD",
+ enable: arc_floppy_cmdend_enable_dma,
+ disable: arc_disable_dma,
+ residue: arc_floppy_cmdend_get_dma_residue,
+};
#endif
- default:
- printk("dma-arc.c:arch_get_dma_residue called with unknown/unconfigured DMA channel\n");
- return 0;
- };
+#ifdef CONFIG_ARCH_A5K
+static struct fiq_handler fh = {
+ name: "floppydata"
+};
+
+static int a5k_floppy_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+ struct pt_regs regs;
+ get_fiq_regs(&regs);
+ return regs.ARM_r9;
+}
+
+static void a5k_floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+ struct pt_regs regs;
+ void *fiqhandler_start;
+ unsigned int fiqhandler_length;
+ extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
+ unsigned long port);
+
+ if (dma->dma_mode == DMA_MODE_READ) {
+ extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+ fiqhandler_start = &floppy_fiqin_start;
+ fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+ } else {
+ extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+ fiqhandler_start = &floppy_fiqout_start;
+ fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+ }
+ if (claim_fiq(&fh)) {
+ printk("floppydma: couldn't claim FIQ.\n");
+ return;
+ }
+ memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
+ regs.ARM_r9 = dma->buf.length;
+ regs.ARM_r10 = __bus_to_virt(dma->buf.address);
+ regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
+ set_fiq_regs(&regs);
+ enable_irq(dma->dma_irq);
}
-void arch_disable_dma(dmach_t channel, dma_t *dma)
+static void a5k_floppy_disable_dma(dmach_t channel, dma_t *dma)
{
- if (channel != DMA_VIRTUAL_FLOPPY0 &&
- channel != DMA_VIRTUAL_FLOPPY1)
- printk("arch_disable_dma: invalid channel %d\n", channel);
- else
- disable_irq(dma->dma_irq);
+ disable_irq(dma->dma_irq);
+ release_fiq(&fh);
}
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
+static struct dma_ops a5k_floppy_dma_ops = {
+ type: "FIQDMA",
+ enable: a5k_floppy_enable_dma,
+ disable: a5k_floppy_disable_dma,
+ residue: a5k_floppy_get_dma_residue,
+};
+#endif
+
+/*
+ * This is virtual DMA - we don't need anything here
+ */
+static int sound_enable_disable_dma(dmach_t channel, dma_t *dma)
{
- return 0;
}
+static struct dma_ops sound_dma_ops = {
+ type: "VIRTUAL",
+ enable: sound_enable_disable_dma,
+ disable: sound_enable_disable_dma,
+};
+
void __init arch_dma_init(dma_t *dma)
{
- dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
- dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65;
+#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
+ if (machine_is_arc()) {
+ dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
+ dma[DMA_VIRTUAL_FLOPPY0].d_ops = &arc_floppy_data_dma_ops;
+ dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65;
+ dma[DMA_VIRTUAL_FLOPPY1].d_ops = &arc_floppy_cmdend_dma_ops;
+ }
+#endif
+#ifdef CONFIG_ARCH_A5K
+ if (machine_is_a5k()) {
+ dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
+ dma[DMA_VIRTUAL_FLOPPY].d_ops = &a5k_floppy_dma_ops;
+ }
+#endif
+ dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
}
diff --git a/arch/arm/kernel/dma-dummy.c b/arch/arm/kernel/dma-dummy.c
deleted file mode 100644
index ebb9755c1..000000000
--- a/arch/arm/kernel/dma-dummy.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * arch/arm/kernel/dma-dummy.c
- *
- * Copyright (C) 1998 Philip Blundell
- * Copyright (c) 1998 Russell King
- *
- * Dummy DMA functions
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
-
-int request_dma(int channel, const char *device_id)
-{
- return -EINVAL;
-}
-
-int no_dma(void)
-{
- return 0;
-}
-
-#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
-GLOBAL_ALIAS(disable_dma, no_dma);
-GLOBAL_ALIAS(enable_dma, no_dma);
-GLOBAL_ALIAS(free_dma, no_dma);
-GLOBAL_ALIAS(get_dma_residue, no_dma);
-GLOBAL_ALIAS(get_dma_list, no_dma);
-GLOBAL_ALIAS(set_dma_mode, no_dma);
-GLOBAL_ALIAS(set_dma_count, no_dma);
-GLOBAL_ALIAS(set_dma_addr, no_dma);
-GLOBAL_ALIAS(init_dma, no_dma);
diff --git a/arch/arm/kernel/dma-footbridge.c b/arch/arm/kernel/dma-footbridge.c
index 1d2ef26c4..b9d4b62fa 100644
--- a/arch/arm/kernel/dma-footbridge.c
+++ b/arch/arm/kernel/dma-footbridge.c
@@ -15,94 +15,44 @@
#include <linux/sched.h>
#include <linux/init.h>
+#include <asm/dec21285.h>
#include <asm/dma.h>
#include <asm/io.h>
#include "dma.h"
-#include "dma-isa.h"
-#ifdef CONFIG_ISA_DMA
-static int has_isa_dma;
-#else
-#define has_isa_dma 0
-#endif
+extern void isa_init_dma(dma_t *dma);
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name)
+#if 0
+static int fb_dma_request(dmach_t channel, dma_t *dma)
{
- switch (channel) {
- case _DC21285_DMA(0):
- case _DC21285_DMA(1): /* 21285 internal channels */
- return 0;
-
- case _ISA_DMA(0) ... _ISA_DMA(7):
- if (has_isa_dma)
- return isa_request_dma(channel - _ISA_DMA(0), dma, dev_name);
- }
-
return -EINVAL;
}
-void arch_free_dma(dmach_t channel, dma_t *dma)
-{
- /* nothing to do */
-}
-
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
-{
- int residue = 0;
-
- switch (channel) {
- case _DC21285_DMA(0):
- case _DC21285_DMA(1):
- break;
-
- case _ISA_DMA(0) ... _ISA_DMA(7):
- if (has_isa_dma)
- residue = isa_get_dma_residue(channel - _ISA_DMA(0), dma);
- }
- return residue;
-}
-
-void arch_enable_dma(dmach_t channel, dma_t *dma)
+static void fb_dma_enable(dmach_t channel, dma_t *dma)
{
- switch (channel) {
- case _DC21285_DMA(0):
- case _DC21285_DMA(1):
- /*
- * Not yet implemented
- */
- break;
-
- case _ISA_DMA(0) ... _ISA_DMA(7):
- if (has_isa_dma)
- isa_enable_dma(channel - _ISA_DMA(0), dma);
- }
}
-void arch_disable_dma(dmach_t channel, dma_t *dma)
+static void fb_dma_disable(dmach_t channel, dma_t *dma)
{
- switch (channel) {
- case _DC21285_DMA(0):
- case _DC21285_DMA(1):
- /*
- * Not yet implemented
- */
- break;
-
- case _ISA_DMA(0) ... _ISA_DMA(7):
- if (has_isa_dma)
- isa_disable_dma(channel - _ISA_DMA(0), dma);
- }
}
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
-{
- return 0;
-}
+static struct dma_ops fb_dma_ops = {
+ type: "fb",
+ request: fb_dma_request,
+ enable: fb_dma_enable,
+ disable: fb_dma_disable,
+};
+#endif
void __init arch_dma_init(dma_t *dma)
{
+#if 0
+ dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
+ dma[_DC21285_DMA(1)].d_ops = &fb_dma_ops;
+#endif
#ifdef CONFIG_ISA_DMA
- has_isa_dma = isa_init_dma();
+ if (footbridge_cfn_mode())
+ isa_init_dma(dma + _ISA_DMA(0));
#endif
}
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 74967a055..f144d0436 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -1,12 +1,13 @@
/*
* arch/arm/kernel/dma-isa.c: ISA DMA primitives
*
- * Copyright (C) Russell King
+ * Copyright (C) 1999-2000 Russell King
*
* Taken from various sources, including:
* linux/include/asm/dma.h: Defines for using and allocating dma channels.
* Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen and John Boyd, Nov. 1992.
+ * High DMA channel support & info by Hannu Savolainen and John Boyd,
+ * Nov. 1992.
* arch/arm/kernel/dma-ebsa285.c
* Copyright (C) 1998 Phil Blundell
*/
@@ -18,7 +19,6 @@
#include <asm/io.h>
#include "dma.h"
-#include "dma-isa.h"
#define ISA_DMA_MODE_READ 0x44
#define ISA_DMA_MODE_WRITE 0x48
@@ -45,17 +45,7 @@ static unsigned int isa_dma_port[8][7] = {
{ 0xd4, 0xd6, 0xd8, 0x48a, 0x08a, 0xcc, 0xce }
};
-int isa_request_dma(int channel, dma_t *dma, const char *dev_name)
-{
- return 0;
-}
-
-void isa_free_dma(int channel, dma_t *dma)
-{
- /* nothing to do */
-}
-
-int isa_get_dma_residue(int channel, dma_t *dma)
+static int isa_get_dma_residue(dmach_t channel, dma_t *dma)
{
unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
int count;
@@ -66,7 +56,7 @@ int isa_get_dma_residue(int channel, dma_t *dma)
return channel < 4 ? count : (count << 1);
}
-void isa_enable_dma(int channel, dma_t *dma)
+static void isa_enable_dma(dmach_t channel, dma_t *dma)
{
if (dma->invalid) {
unsigned long address, length;
@@ -121,11 +111,18 @@ void isa_enable_dma(int channel, dma_t *dma)
outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
}
-void isa_disable_dma(int channel, dma_t *dma)
+static void isa_disable_dma(dmach_t channel, dma_t *dma)
{
outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
}
+static struct dma_ops isa_dma_ops = {
+ type: "ISA",
+ enable: isa_enable_dma,
+ disable: isa_disable_dma,
+ residue: isa_get_dma_residue,
+};
+
static struct resource dma_resources[] = {
{ "dma1", 0x0000, 0x000f },
{ "dma low page", 0x0080, 0x008f },
@@ -133,7 +130,7 @@ static struct resource dma_resources[] = {
{ "dma high page", 0x0480, 0x048f }
};
-int __init isa_init_dma(void)
+void __init isa_init_dma(dma_t *dma)
{
int dmac_found;
@@ -148,8 +145,10 @@ int __init isa_init_dma(void)
if (dmac_found) {
int channel, i;
- for (channel = 0; channel < 8; channel++)
+ for (channel = 0; channel < 8; channel++) {
+ dma[channel].d_ops = &isa_dma_ops;
isa_disable_dma(channel, NULL);
+ }
outb(0x40, 0x0b);
outb(0x41, 0x0b);
@@ -167,10 +166,9 @@ int __init isa_init_dma(void)
outb(0x10, 0xd0);
/*
- * Is this correct? According to
- * my documentation, it doesn't
- * appear to be. It should be
- * outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
+ * Is this correct? According to my documentation, it
+ * doesn't appear to be. It should be:
+ * outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
*/
outb(0x30, 0x40b);
outb(0x31, 0x40b);
@@ -185,6 +183,4 @@ int __init isa_init_dma(void)
for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++)
request_resource(&ioport_resource, dma_resources + i);
}
-
- return dmac_found;
}
diff --git a/arch/arm/kernel/dma-isa.h b/arch/arm/kernel/dma-isa.h
deleted file mode 100644
index 2640f6c3a..000000000
--- a/arch/arm/kernel/dma-isa.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Request an ISA DMA channel
- */
-int isa_request_dma(int channel, dma_t *dma, const char *dev_name);
-
-/*
- * Free an ISA DMA channel
- */
-void isa_free_dma(int channel, dma_t *dma);
-
-/*
- * Get ISA DMA channel residue
- */
-int isa_get_dma_residue(int channel, dma_t *dma);
-
-/*
- * Enable (and set up) an ISA DMA channel
- */
-void isa_enable_dma(int channel, dma_t *dma);
-
-/*
- * Disable an ISA DMA channel
- */
-void isa_disable_dma(int channel, dma_t *dma);
-
-/*
- * Initialise DMA
- */
-int isa_init_dma(void);
diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c
index f4bc97f1d..35e3c35a3 100644
--- a/arch/arm/kernel/dma-rpc.c
+++ b/arch/arm/kernel/dma-rpc.c
@@ -21,10 +21,6 @@
#include "dma.h"
-static struct fiq_handler fh = {
- name: "floppydma"
-};
-
#if 0
typedef enum {
dma_size_8 = 1,
@@ -51,7 +47,7 @@ typedef struct {
#define state_wait_a 1
#define state_wait_b 2
-static void arch_get_next_sg(dmasg_t *sg, dma_t *dma)
+static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma)
{
unsigned long end, offset, flags = 0;
@@ -90,19 +86,19 @@ static void arch_get_next_sg(dmasg_t *sg, dma_t *dma)
sg->length |= flags;
}
-static inline void arch_setup_dma_a(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_a(dmasg_t *sg, dma_t *dma)
{
outl_t(sg->address, dma->dma_base + CURA);
outl_t(sg->length, dma->dma_base + ENDA);
}
-static inline void arch_setup_dma_b(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_b(dmasg_t *sg, dma_t *dma)
{
outl_t(sg->address, dma->dma_base + CURB);
outl_t(sg->length, dma->dma_base + ENDB);
}
-static void arch_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
+static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
{
dma_t *dma = (dma_t *)dev_id;
unsigned int status = 0, no_buffer = dma->sg == NULL;
@@ -110,26 +106,26 @@ static void arch_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
do {
switch (dma->state) {
case state_prog_a:
- arch_get_next_sg(&dma->cur_sg, dma);
- arch_setup_dma_a(&dma->cur_sg, dma);
+ iomd_get_next_sg(&dma->cur_sg, dma);
+ iomd_setup_dma_a(&dma->cur_sg, dma);
dma->state = state_wait_a;
case state_wait_a:
status = inb_t(dma->dma_base + ST);
switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
case DMA_ST_OFL|DMA_ST_INT:
- arch_get_next_sg(&dma->cur_sg, dma);
- arch_setup_dma_a(&dma->cur_sg, dma);
+ iomd_get_next_sg(&dma->cur_sg, dma);
+ iomd_setup_dma_a(&dma->cur_sg, dma);
break;
case DMA_ST_INT:
- arch_get_next_sg(&dma->cur_sg, dma);
- arch_setup_dma_b(&dma->cur_sg, dma);
+ iomd_get_next_sg(&dma->cur_sg, dma);
+ iomd_setup_dma_b(&dma->cur_sg, dma);
dma->state = state_wait_b;
break;
case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
- arch_setup_dma_b(&dma->cur_sg, dma);
+ iomd_setup_dma_b(&dma->cur_sg, dma);
dma->state = state_wait_b;
break;
}
@@ -139,18 +135,18 @@ static void arch_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
status = inb_t(dma->dma_base + ST);
switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
- arch_get_next_sg(&dma->cur_sg, dma);
- arch_setup_dma_b(&dma->cur_sg, dma);
+ iomd_get_next_sg(&dma->cur_sg, dma);
+ iomd_setup_dma_b(&dma->cur_sg, dma);
break;
case DMA_ST_INT|DMA_ST_AB:
- arch_get_next_sg(&dma->cur_sg, dma);
- arch_setup_dma_a(&dma->cur_sg, dma);
+ iomd_get_next_sg(&dma->cur_sg, dma);
+ iomd_setup_dma_a(&dma->cur_sg, dma);
dma->state = state_wait_a;
break;
case DMA_ST_OFL|DMA_ST_INT:
- arch_setup_dma_a(&dma->cur_sg, dma);
+ iomd_setup_dma_a(&dma->cur_sg, dma);
dma->state = state_wait_a;
break;
}
@@ -162,167 +158,56 @@ static void arch_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
disable_irq(irq);
}
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name)
+static int iomd_request_dma(dmach_t channel, dma_t *dma)
{
unsigned long flags;
int ret;
- switch (channel) {
- case DMA_0:
- case DMA_1:
- case DMA_2:
- case DMA_3:
- case DMA_S0:
- case DMA_S1:
- save_flags_cli(flags);
- ret = request_irq(dma->dma_irq, arch_dma_handle,
- SA_INTERRUPT, dev_name, dma);
- if (!ret)
- disable_irq(dma->dma_irq);
- restore_flags(flags);
- break;
-
- case DMA_VIRTUAL_FLOPPY:
- case DMA_VIRTUAL_SOUND:
- ret = 0;
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
+ save_flags_cli(flags);
+ ret = request_irq(dma->dma_irq, iomd_dma_handle,
+ SA_INTERRUPT, dma->device_id, dma);
+ if (!ret)
+ disable_irq(dma->dma_irq);
+ restore_flags(flags);
return ret;
}
-void arch_free_dma(dmach_t channel, dma_t *dma)
+static void iomd_free_dma(dmach_t channel, dma_t *dma)
{
- switch (channel) {
- case DMA_0:
- case DMA_1:
- case DMA_2:
- case DMA_3:
- case DMA_S0:
- case DMA_S1:
- free_irq(dma->dma_irq, dma);
- break;
-
- default:
- break;
- }
+ free_irq(dma->dma_irq, dma);
}
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
-{
- int residue = 0;
-
- switch (channel) {
- case DMA_0: /* Physical DMA channels */
- case DMA_1:
- case DMA_2:
- case DMA_3:
- case DMA_S0:
- case DMA_S1:
- break;
-
- case DMA_VIRTUAL_FLOPPY: {
- struct pt_regs regs;
- get_fiq_regs(&regs);
- return regs.ARM_r9;
- }
- break;
- }
- return residue;
-}
-
-void arch_enable_dma(dmach_t channel, dma_t *dma)
+static void iomd_enable_dma(dmach_t channel, dma_t *dma)
{
unsigned long dma_base = dma->dma_base;
- unsigned int ctrl;
-
- switch (channel) {
- case DMA_0: /* Physical DMA channels */
- case DMA_1:
- case DMA_2:
- case DMA_3:
- case DMA_S0:
- case DMA_S1:
- ctrl = TRANSFER_SIZE | DMA_CR_E;
+ unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
- if (dma->invalid) {
- dma->invalid = 0;
+ if (dma->invalid) {
+ dma->invalid = 0;
- outb_t(DMA_CR_C, dma_base + CR);
- dma->state = state_prog_a;
- }
+ outb_t(DMA_CR_C, dma_base + CR);
+ dma->state = state_prog_a;
+ }
- if (dma->dma_mode == DMA_MODE_READ)
- ctrl |= DMA_CR_D;
+ if (dma->dma_mode == DMA_MODE_READ)
+ ctrl |= DMA_CR_D;
- outb_t(ctrl, dma_base + CR);
- enable_irq(dma->dma_irq);
- break;
-
- case DMA_VIRTUAL_FLOPPY: {
- void *fiqhandler_start;
- unsigned int fiqhandler_length;
- struct pt_regs regs;
-
- if (dma->dma_mode == DMA_MODE_READ) {
- extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
- fiqhandler_start = &floppy_fiqin_start;
- fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
- } else {
- extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
- fiqhandler_start = &floppy_fiqout_start;
- fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
- }
-
- regs.ARM_r9 = dma->buf.length;
- regs.ARM_r10 = __bus_to_virt(dma->buf.address);
- regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
-
- if (claim_fiq(&fh)) {
- printk("floppydma: couldn't claim FIQ.\n");
- return;
- }
-
- set_fiq_handler(fiqhandler_start, fiqhandler_length);
- set_fiq_regs(&regs);
- enable_irq(dma->dma_irq);
- }
- break;
-
- default:
- break;
- }
+ outb_t(ctrl, dma_base + CR);
+ enable_irq(dma->dma_irq);
}
-void arch_disable_dma(dmach_t channel, dma_t *dma)
+static void iomd_disable_dma(dmach_t channel, dma_t *dma)
{
unsigned long dma_base = dma->dma_base;
unsigned int ctrl;
- switch (channel) {
- case DMA_0: /* Physical DMA channels */
- case DMA_1:
- case DMA_2:
- case DMA_3:
- case DMA_S0:
- case DMA_S1:
- disable_irq(dma->dma_irq);
- ctrl = inb_t(dma_base + CR);
- outb_t(ctrl & ~DMA_CR_E, dma_base + CR);
- break;
-
- case DMA_VIRTUAL_FLOPPY:
- disable_irq(dma->dma_irq);
- release_fiq(&fh);
- break;
- }
+ disable_irq(dma->dma_irq);
+ ctrl = inb_t(dma_base + CR);
+ outb_t(ctrl & ~DMA_CR_E, dma_base + CR);
}
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
+static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
{
int tcr, speed;
@@ -364,6 +249,82 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
return speed;
}
+static struct dma_ops iomd_dma_ops = {
+ type: "IOMD",
+ request: iomd_request_dma,
+ free: iomd_free_dma,
+ enable: iomd_enable_dma,
+ disable: iomd_disable_dma,
+ setspeed: iomd_set_dma_speed,
+};
+
+static struct fiq_handler fh = {
+ name: "floppydma"
+};
+
+static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+ void *fiqhandler_start;
+ unsigned int fiqhandler_length;
+ struct pt_regs regs;
+
+ if (dma->dma_mode == DMA_MODE_READ) {
+ extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+ fiqhandler_start = &floppy_fiqin_start;
+ fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+ } else {
+ extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+ fiqhandler_start = &floppy_fiqout_start;
+ fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+ }
+
+ regs.ARM_r9 = dma->buf.length;
+ regs.ARM_r10 = __bus_to_virt(dma->buf.address);
+ regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
+
+ if (claim_fiq(&fh)) {
+ printk("floppydma: couldn't claim FIQ.\n");
+ return;
+ }
+
+ set_fiq_handler(fiqhandler_start, fiqhandler_length);
+ set_fiq_regs(&regs);
+ enable_irq(dma->dma_irq);
+}
+
+static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+ disable_irq(dma->dma_irq);
+ release_fiq(&fh);
+}
+
+static int floppy_get_residue(dmach_t channel, dma_t *dma)
+{
+ struct pt_regs regs;
+ get_fiq_regs(&regs);
+ return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+ type: "FIQDMA",
+ enable: floppy_enable_dma,
+ disable: floppy_disable_dma,
+ residue: floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static int sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+ type: "VIRTUAL",
+ enable: sound_enable_disable_dma,
+ disable: sound_enable_disable_dma,
+};
+
void __init arch_dma_init(dma_t *dma)
{
outb(0, IOMD_IO0CR);
@@ -373,21 +334,30 @@ void __init arch_dma_init(dma_t *dma)
outb(0xa0, IOMD_DMATCR);
- dma[0].dma_base = ioaddr(IOMD_IO0CURA);
- dma[0].dma_irq = IRQ_DMA0;
- dma[1].dma_base = ioaddr(IOMD_IO1CURA);
- dma[1].dma_irq = IRQ_DMA1;
- dma[2].dma_base = ioaddr(IOMD_IO2CURA);
- dma[2].dma_irq = IRQ_DMA2;
- dma[3].dma_base = ioaddr(IOMD_IO3CURA);
- dma[3].dma_irq = IRQ_DMA3;
- dma[4].dma_base = ioaddr(IOMD_SD0CURA);
- dma[4].dma_irq = IRQ_DMAS0;
- dma[5].dma_base = ioaddr(IOMD_SD1CURA);
- dma[5].dma_irq = IRQ_DMAS1;
- dma[6].dma_irq = 64;
-
- /* Setup DMA channels 2,3 to be for podules
+ dma[DMA_0].dma_base = ioaddr(IOMD_IO0CURA);
+ dma[DMA_0].dma_irq = IRQ_DMA0;
+ dma[DMA_0].d_ops = &iomd_dma_ops;
+ dma[DMA_1].dma_base = ioaddr(IOMD_IO1CURA);
+ dma[DMA_1].dma_irq = IRQ_DMA1;
+ dma[DMA_1].d_ops = &iomd_dma_ops;
+ dma[DMA_2].dma_base = ioaddr(IOMD_IO2CURA);
+ dma[DMA_2].dma_irq = IRQ_DMA2;
+ dma[DMA_2].d_ops = &iomd_dma_ops;
+ dma[DMA_3].dma_base = ioaddr(IOMD_IO3CURA);
+ dma[DMA_3].dma_irq = IRQ_DMA3;
+ dma[DMA_3].d_ops = &iomd_dma_ops;
+ dma[DMA_S0].dma_base = ioaddr(IOMD_SD0CURA);
+ dma[DMA_S0].dma_irq = IRQ_DMAS0;
+ dma[DMA_S0].d_ops = &iomd_dma_ops;
+ dma[DMA_S1].dma_base = ioaddr(IOMD_SD1CURA);
+ dma[DMA_S1].dma_irq = IRQ_DMAS1;
+ dma[DMA_S1].d_ops = &iomd_dma_ops;
+ dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
+ dma[DMA_VIRTUAL_FLOPPY].d_ops = &floppy_dma_ops;
+ dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
+
+ /*
+ * Setup DMA channels 2,3 to be for podules
* and channels 0,1 for internal devices
*/
outb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index ff8322d34..7ed4c28ca 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -1,130 +1,123 @@
/*
* linux/arch/arm/kernel/dma.c
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * Front-end to the DMA handling. You must provide the following
- * architecture-specific routines:
- *
- * int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id);
- * void arch_free_dma(dmach_t channel, dma_t *dma);
- * void arch_enable_dma(dmach_t channel, dma_t *dma);
- * void arch_disable_dma(dmach_t channel, dma_t *dma);
- * int arch_get_dma_residue(dmach_t channel, dma_t *dma);
- *
- * Moved DMA resource allocation here...
+ * Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities.
*/
+#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/sched.h>
-#include <linux/module.h>
#include <linux/mman.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
#include <asm/dma.h>
-
-/* A note on resource allocation:
- *
- * All drivers needing DMA channels, should allocate and release them
- * through the public routines `request_dma()' and `free_dma()'.
- *
- * In order to avoid problems, all processes should allocate resources in
- * the same sequence and release them in the reverse order.
- *
- * So, when allocating DMAs and IRQs, first allocate the IRQ, then the DMA.
- * When releasing them, first release the DMA, then release the IRQ.
- * If you don't, you may cause allocation requests to fail unnecessarily.
- * This doesn't really matter now, but it will once we get real semaphores
- * in the kernel.
- */
-
+#include "dma.h"
spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
-#include "dma.h"
-
-const char dma_str[] = "%s: dma %d not supported\n";
+#if MAX_DMA_CHANNELS > 0
static dma_t dma_chan[MAX_DMA_CHANNELS];
-/* Get dma list
- * for /proc/dma
+/*
+ * Get dma list for /proc/dma
*/
int get_dma_list(char *buf)
{
- int i, len = 0;
+ dma_t *dma;
+ char *p = buf;
+ int i;
- for (i = 0; i < MAX_DMA_CHANNELS; i++) {
- if (dma_chan[i].lock)
- len += sprintf(buf + len, "%2d: %s\n",
- i, dma_chan[i].device_id);
- }
- return len;
+ for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++)
+ if (dma->lock)
+ p += sprintf(p, "%2d: %14s %s\n", i,
+ dma->d_ops->type, dma->device_id);
+
+ return p - buf;
}
-/* Request DMA channel
+/*
+ * Request DMA channel
*
* On certain platforms, we have to allocate an interrupt as well...
*/
int request_dma(dmach_t channel, const char *device_id)
{
- if (channel < MAX_DMA_CHANNELS) {
- int ret;
-
- if (xchg(&dma_chan[channel].lock, 1) != 0)
- return -EBUSY;
-
- ret = arch_request_dma(channel, &dma_chan[channel], device_id);
- if (!ret) {
- dma_chan[channel].device_id = device_id;
- dma_chan[channel].active = 0;
- dma_chan[channel].invalid = 1;
- } else
- xchg(&dma_chan[channel].lock, 0);
-
- return ret;
- } else {
- printk (KERN_ERR "Trying to allocate DMA%d\n", channel);
- return -EINVAL;
- }
+ dma_t *dma = dma_chan + channel;
+ int ret;
+
+ if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ goto bad_dma;
+
+ if (xchg(&dma->lock, 1) != 0)
+ goto busy;
+
+ dma->device_id = device_id;
+ dma->active = 0;
+ dma->invalid = 1;
+
+ ret = 0;
+ if (dma->d_ops->request)
+ ret = dma->d_ops->request(channel, dma);
+
+ if (ret)
+ xchg(&dma->lock, 0);
+
+ return ret;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
+ return -EINVAL;
+
+busy:
+ return -EBUSY;
}
-/* Free DMA channel
+/*
+ * Free DMA channel
*
* On certain platforms, we have to free interrupt as well...
*/
void free_dma(dmach_t channel)
{
- if (channel >= MAX_DMA_CHANNELS) {
- printk (KERN_ERR "Trying to free DMA%d\n", channel);
- return;
- }
+ dma_t *dma = dma_chan + channel;
+
+ if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ goto bad_dma;
- if (xchg(&dma_chan[channel].lock, 0) == 0) {
- if (dma_chan[channel].active) {
- printk (KERN_ERR "Freeing active DMA%d\n", channel);
- arch_disable_dma(channel, &dma_chan[channel]);
- dma_chan[channel].active = 0;
- }
+ if (dma->active) {
+ printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
+ dma->d_ops->disable(channel, dma);
+ dma->active = 0;
+ }
- printk (KERN_ERR "Trying to free free DMA%d\n", channel);
+ if (xchg(&dma->lock, 0) != 0) {
+ if (dma->d_ops->free)
+ dma->d_ops->free(channel, dma);
return;
}
- arch_free_dma(channel, &dma_chan[channel]);
+
+ printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
+ return;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
}
/* Set DMA Scatter-Gather list
*/
void set_dma_sg (dmach_t channel, dmasg_t *sg, int nr_sg)
{
- dma_chan[channel].sg = sg;
- dma_chan[channel].sgcount = nr_sg;
- dma_chan[channel].invalid = 1;
+ dma_t *dma = dma_chan + channel;
+
+ dma->sg = sg;
+ dma->sgcount = nr_sg;
+ dma->invalid = 1;
}
/* Set DMA address
@@ -133,15 +126,16 @@ void set_dma_sg (dmach_t channel, dmasg_t *sg, int nr_sg)
*/
void set_dma_addr (dmach_t channel, unsigned long physaddr)
{
- if (dma_chan[channel].active)
- printk(KERN_ERR "set_dma_addr: altering DMA%d"
- " address while DMA active\n",
- channel);
-
- dma_chan[channel].sg = &dma_chan[channel].buf;
- dma_chan[channel].sgcount = 1;
- dma_chan[channel].buf.address = physaddr;
- dma_chan[channel].invalid = 1;
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA address while "
+ "DMA active\n", channel);
+
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.address = physaddr;
+ dma->invalid = 1;
}
/* Set DMA byte count
@@ -150,78 +144,137 @@ void set_dma_addr (dmach_t channel, unsigned long physaddr)
*/
void set_dma_count (dmach_t channel, unsigned long count)
{
- if (dma_chan[channel].active)
- printk(KERN_ERR "set_dma_count: altering DMA%d"
- " count while DMA active\n",
- channel);
-
- dma_chan[channel].sg = &dma_chan[channel].buf;
- dma_chan[channel].sgcount = 1;
- dma_chan[channel].buf.length = count;
- dma_chan[channel].invalid = 1;
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA count while "
+ "DMA active\n", channel);
+
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.length = count;
+ dma->invalid = 1;
}
/* Set DMA direction mode
*/
void set_dma_mode (dmach_t channel, dmamode_t mode)
{
- if (dma_chan[channel].active)
- printk(KERN_ERR "set_dma_mode: altering DMA%d"
- " mode while DMA active\n",
- channel);
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA mode while "
+ "DMA active\n", channel);
- dma_chan[channel].dma_mode = mode;
- dma_chan[channel].invalid = 1;
+ dma->dma_mode = mode;
+ dma->invalid = 1;
}
/* Enable DMA channel
*/
void enable_dma (dmach_t channel)
{
- if (dma_chan[channel].lock) {
- if (dma_chan[channel].active == 0) {
- dma_chan[channel].active = 1;
- arch_enable_dma(channel, &dma_chan[channel]);
- }
- } else
- printk (KERN_ERR "Trying to enable free DMA%d\n", channel);
+ dma_t *dma = dma_chan + channel;
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 0) {
+ dma->active = 1;
+ dma->d_ops->enable(channel, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
+ BUG();
}
/* Disable DMA channel
*/
void disable_dma (dmach_t channel)
{
- if (dma_chan[channel].lock) {
- if (dma_chan[channel].active == 1) {
- dma_chan[channel].active = 0;
- arch_disable_dma(channel, &dma_chan[channel]);
- }
- } else
- printk (KERN_ERR "Trying to disable free DMA%d\n", channel);
+ dma_t *dma = dma_chan + channel;
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 1) {
+ dma->active = 0;
+ dma->d_ops->disable(channel, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
+ BUG();
+}
+
+void set_dma_page(dmach_t channel, char pagenr)
+{
+ printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
}
void set_dma_speed(dmach_t channel, int cycle_ns)
{
- dma_chan[channel].speed =
- arch_set_dma_speed(channel, &dma_chan[channel], cycle_ns);
+ dma_t *dma = dma_chan + channel;
+ int ret = 0;
+
+ if (dma->d_ops->setspeed)
+ ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
+ dma->speed = ret;
}
int get_dma_residue(dmach_t channel)
{
- return arch_get_dma_residue(channel, &dma_chan[channel]);
+ dma_t *dma = dma_chan + channel;
+ int ret = 0;
+
+ if (dma->d_ops->residue)
+ ret = dma->d_ops->residue(channel, dma);
+
+ return ret;
+}
+
+void __init init_dma(void)
+{
+ arch_dma_init(dma_chan);
+}
+
+#else
+
+int request_dma(dmach_t channel, const char *device_id)
+{
+ return -EINVAL;
+}
+
+static int no_dma(void)
+{
+ return 0;
}
-EXPORT_SYMBOL(dma_str);
+#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
+GLOBAL_ALIAS(disable_dma, no_dma);
+GLOBAL_ALIAS(enable_dma, no_dma);
+GLOBAL_ALIAS(free_dma, no_dma);
+GLOBAL_ALIAS(get_dma_residue, no_dma);
+GLOBAL_ALIAS(get_dma_list, no_dma);
+GLOBAL_ALIAS(set_dma_mode, no_dma);
+GLOBAL_ALIAS(set_dma_page, no_dma);
+GLOBAL_ALIAS(set_dma_count, no_dma);
+GLOBAL_ALIAS(set_dma_addr, no_dma);
+GLOBAL_ALIAS(set_dma_sg, no_dma);
+GLOBAL_ALIAS(set_dma_speed, no_dma);
+GLOBAL_ALIAS(init_dma, no_dma);
+
+#endif
+
EXPORT_SYMBOL(enable_dma);
EXPORT_SYMBOL(disable_dma);
EXPORT_SYMBOL(set_dma_addr);
EXPORT_SYMBOL(set_dma_count);
EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_page);
EXPORT_SYMBOL(get_dma_residue);
EXPORT_SYMBOL(set_dma_sg);
EXPORT_SYMBOL(set_dma_speed);
-
-void __init init_dma(void)
-{
- arch_dma_init(dma_chan);
-}
diff --git a/arch/arm/kernel/dma.h b/arch/arm/kernel/dma.h
index 33db3b03b..6cd96ed97 100644
--- a/arch/arm/kernel/dma.h
+++ b/arch/arm/kernel/dma.h
@@ -1,13 +1,26 @@
/*
- * arch/arm/kernel/dma.h
+ * linux/arch/arm/kernel/dma.h
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998-2000 Russell King
*
* This header file describes the interface between the generic DMA handler
* (dma.c) and the architecture-specific DMA backends (dma-*.c)
*/
-typedef struct {
+struct dma_struct;
+typedef struct dma_struct dma_t;
+
+struct dma_ops {
+ int (*request)(dmach_t, dma_t *); /* optional */
+ void (*free)(dmach_t, dma_t *); /* optional */
+ void (*enable)(dmach_t, dma_t *); /* mandatory */
+ void (*disable)(dmach_t, dma_t *); /* mandatory */
+ int (*residue)(dmach_t, dma_t *); /* optional */
+ int (*setspeed)(dmach_t, dma_t *, int); /* optional */
+ char *type;
+};
+
+struct dma_struct {
dmasg_t buf; /* single DMA */
int sgcount; /* number of DMA SG */
dmasg_t *sg; /* DMA Scatter-Gather List */
@@ -24,54 +37,9 @@ typedef struct {
int dma_irq; /* Controller IRQ */
int state; /* Controller state */
dmasg_t cur_sg; /* Current controller buffer */
-} dma_t;
-
-/* Prototype: int arch_request_dma(channel, dma, dev_id)
- * Purpose : Perform architecture specific claiming of a DMA channel
- * Params : channel - DMA channel number
- * : dma - DMA structure (above) for channel
- * : dev_id - device ID string passed with request
- * Returns : 0 on success, E????? number on error
- */
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id);
-
-/* Prototype: int arch_free_dma(channel, dma)
- * Purpose : Perform architecture specific freeing of a DMA channel
- * Params : channel - DMA channel number
- * : dma - DMA structure for channel
- */
-void arch_free_dma(dmach_t channel, dma_t *dma);
-
-/* Prototype: void arch_enable_dma(channel, dma)
- * Purpose : Enable a claimed DMA channel
- * Params : channel - DMA channel number
- * : dma - DMA structure for channel
- */
-void arch_enable_dma(dmach_t channel, dma_t *dma);
-
-/* Prototype: void arch_disable_dma(channel, dma)
- * Purpose : Disable a claimed DMA channel
- * Params : channel - DMA channel number
- * : dma - DMA structure for channel
- */
-void arch_disable_dma(dmach_t channel, dma_t *dma);
-/* Prototype: int arch_get_dma_residue(channel, dma)
- * Purpose : Return number of bytes left to DMA
- * Params : channel - DMA channel number
- * : dma - DMA structure for channel
- * Returns : Number of bytes left to DMA
- */
-int arch_get_dma_residue(dmach_t channel, dma_t *dma);
-
-/* Prototype: int arch_set_dma_speed(channel, dma, cycle)
- * Purpose : Convert a cycle time to a register setting
- * Params : channel - DMA channel number
- * : dma - DMA structure for channel
- * : cycle - cycle time in NS
- * Returns : setting for 'dma->speed'
- */
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle);
+ struct dma_ops *d_ops;
+};
/* Prototype: void arch_dma_init(dma)
* Purpose : Initialise architecture specific DMA
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index b4d38e00f..5acfd9f24 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -44,12 +44,6 @@
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
-#ifdef CONFIG_ARCH_ARC
-#include <asm/arch/oldlatches.h>
-#else
-#define oldlatch_init()
-#endif
-
#ifndef CONFIG_ARCH_RPC
#define HAVE_EXPMASK
#endif
@@ -378,7 +372,8 @@ ecard_call(struct ecard_request *req)
ecard_task_reset(req);
} else {
if (ecard_pid <= 0)
- ecard_pid = kernel_thread(ecard_task, NULL, 0);
+ ecard_pid = kernel_thread(ecard_task, NULL,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
ecard_req = req;
@@ -1062,8 +1057,6 @@ void __init ecard_init(void)
{
int slot;
- oldlatch_init();
-
#ifdef CONFIG_CPU_32
init_waitqueue_head(&ecard_wait);
init_waitqueue_head(&ecard_done);
diff --git a/arch/arm/kernel/hw-sa1100.c b/arch/arm/kernel/hw-sa1100.c
index 862c3a2c4..27786cdd2 100644
--- a/arch/arm/kernel/hw-sa1100.c
+++ b/arch/arm/kernel/hw-sa1100.c
@@ -81,6 +81,24 @@ void __init get_assabet_scr(void)
#endif /* CONFIG_SA1100_ASSABET */
+/*
+ * Bitsy has extended, write-only memory-mapped GPIO's
+ */
+#if defined(CONFIG_SA1100_BITSY)
+static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
+void clr_bitsy_egpio(unsigned long x)
+{
+ bitsy_egpio &= ~x;
+ *(volatile int *)0xdc000000 = bitsy_egpio;
+}
+void set_bitsy_egpio(unsigned long x)
+{
+ bitsy_egpio |= x;
+ *(volatile int *)0xdc000000 = bitsy_egpio;
+}
+EXPORT_SYMBOL(clr_bitsy_egpio);
+EXPORT_SYMBOL(set_bitsy_egpio);
+#endif
#ifdef CONFIG_SA1111
diff --git a/arch/arm/kernel/oldlatches.c b/arch/arm/kernel/oldlatches.c
index a908241d2..3d6758ff4 100644
--- a/arch/arm/kernel/oldlatches.c
+++ b/arch/arm/kernel/oldlatches.c
@@ -3,52 +3,53 @@
*
* (c) David Alan Gilbert 1995/1996
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/hardware.h>
-#ifdef LATCHAADDR
-/*
- * They are static so that everyone who accesses them has to go through here
- */
-static unsigned char LatchACopy;
+static unsigned char latch_a_copy;
+static unsigned char latch_b_copy;
/* newval=(oldval & ~mask)|newdata */
void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
{
- LatchACopy=(LatchACopy & ~mask)|newdata;
- outb(LatchACopy, LATCHAADDR);
-#ifdef DEBUG
- printk("oldlatch_A:0x%2x\n",LatchACopy);
-#endif
+ if (machine_is_arc()) {
+ latch_a_copy = (latch_a_copy & ~mask) | newdata;
+
+ printk("Latch: A = 0x%02x\n", latch_a_copy);
+ outb(latch_a_copy, LATCHAADDR);
+ } else
+ BUG();
}
-#endif
-#ifdef LATCHBADDR
-static unsigned char LatchBCopy;
/* newval=(oldval & ~mask)|newdata */
void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
{
- LatchBCopy=(LatchBCopy & ~mask)|newdata;
- outb(LatchBCopy, LATCHBADDR);
-#ifdef DEBUG
- printk("oldlatch_B:0x%2x\n",LatchBCopy);
-#endif
+ if (machine_is_arc()) {
+ latch_b_copy = (latch_b_copy & ~mask) | newdata;
+
+ printk("Latch: B = 0x%02x\n", latch_b_copy);
+
+ outb(latch_b_copy, LATCHBADDR);
+ } else
+ BUG();
}
-#endif
-void __init oldlatch_init(void)
+static void __init oldlatch_init(void)
{
- printk("oldlatch: init\n");
-#ifdef LATCHAADDR
- oldlatch_aupdate(0xff,0xff);
-#endif
-#ifdef LATCHBADDR
- oldlatch_bupdate(0xff,0x8); /* Thats no FDC reset...*/
-#endif
- return ;
+ if (machine_is_arc()) {
+ oldlatch_aupdate(0xff, 0xff);
+ /* Thats no FDC reset...*/
+ oldlatch_bupdate(0xff, LATCHB_FDCRESET);
+ }
}
+
+initcall(oldlatch_init);
+
+EXPORT_SYMBOL(oldlatch_aupdate);
+EXPORT_SYMBOL(oldlatch_bupdate);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f281f7337..3ef5bc59d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -67,6 +67,12 @@ __setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);
/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+void (*pm_power_off)(void);
+
+/*
* The idle thread. We try to conserve power, while trying to keep
* overall latency low. The architecture specific idle is passed
* a value to indicate the level of "idleness" of the system.
@@ -79,7 +85,11 @@ void cpu_idle(void)
current->counter = -100;
while (1) {
- arch_idle();
+ void (*idle)(void) = pm_idle;
+ if (!idle)
+ idle = arch_idle;
+ while (!current->need_resched)
+ idle();
schedule();
#ifndef CONFIG_NO_PGT_CACHE
check_pgt_cache();
@@ -97,6 +107,16 @@ int __init reboot_setup(char *str)
__setup("reboot=", reboot_setup);
+void machine_halt(void)
+{
+}
+
+void machine_power_off(void)
+{
+ if (pm_power_off)
+ pm_power_off();
+}
+
void machine_restart(char * __unused)
{
/*
@@ -125,15 +145,6 @@ void machine_restart(char * __unused)
while (1);
}
-void machine_halt(void)
-{
-}
-
-void machine_power_off(void)
-{
- arch_power_off();
-}
-
void show_regs(struct pt_regs * regs)
{
unsigned long flags;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 3e6cf6cb4..4d489bcf3 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -586,7 +586,6 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
/* FALLTHRU */
default:
- lock_kernel();
sigaddset(&current->signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 2c3cabadc..6d49e1427 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -11,9 +11,8 @@
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/malloc.h>
#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index d7f6640eb..da437639f 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -30,7 +30,7 @@
extern int setup_arm_irq(int, struct irqaction *);
extern void setup_timer(void);
extern rwlock_t xtime_lock;
-extern volatile unsigned long lost_ticks;
+extern unsigned long wall_jiffies;
/* change this if you have some constant time drift */
#define USECS_PER_JIFFY (1000000/HZ)
@@ -189,7 +189,7 @@ void do_gettimeofday(struct timeval *tv)
read_lock_irqsave(&xtime_lock, flags);
usec = gettimeoffset();
{
- unsigned long lost = lost_ticks;
+ unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * USECS_PER_JIFFY;
@@ -218,7 +218,7 @@ void do_settimeofday(struct timeval *tv)
* would have done, and then undo it!
*/
tv->tv_usec -= gettimeoffset();
- tv->tv_usec -= lost_ticks * USECS_PER_JIFFY;
+ tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY;
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 188f89722..c76a95736 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -37,9 +37,6 @@ char *processor_modes[]=
"UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
};
-/* proc/system.h */
-const char xchg_str[] = "xchg";
-
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
static inline void console_verbose(void)