diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
commit | 74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch) | |
tree | 7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /arch/arm | |
parent | ee6374c8b0d333c08061c6a97bc77090d7461225 (diff) |
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to
switch to another getty like getty_ps. This commit also includes a
fix for a setitimer bug which did prevent getty_ps from working on
older kernels.
Diffstat (limited to 'arch/arm')
34 files changed, 1165 insertions, 189 deletions
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S index 65f70c727..dacad00b5 100644 --- a/arch/arm/kernel/entry-armo.S +++ b/arch/arm/kernel/entry-armo.S @@ -29,13 +29,12 @@ #include <linux/config.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/errno.h> #include <asm/hardware.h> -#include "../lib/constants.h" - .macro zero_fp -#ifdef CONFIG_FRAME_POINTER +#ifndef CONFIG_NO_FRAME_POINTER mov fp, #0 #endif .endm diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index e659b966d..145420266 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -17,19 +17,19 @@ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/errno.h> #include <asm/hardware.h> #include <asm/arch/irqs.h> #include <asm/proc-fns.h> -#include "../lib/constants.h" #ifndef MODE_SVC #define MODE_SVC 0x13 #endif .macro zero_fp -#ifdef CONFIG_FRAME_POINTER +#ifndef CONFIG_NO_FRAME_POINTER mov fp, #0 #endif .endm @@ -611,9 +611,9 @@ __und_invalid: sub sp, sp, #S_FRAME_SIZE #else wfs_mask_data: .word 0x0e200110 @ WFS/RFS .word 0x0fef0fff - .word 0x0d0d0100 @ LDF [sp]/STF [sp] - .word 0x0d0b0100 @ LDF [fp]/STF [fp] - .word 0x0f0f0f00 + .word 0x0d000100 @ LDF [sp]/STF [sp] + .word 0x0d000100 @ LDF [fp]/STF [fp] + .word 0x0f000f00 /* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8fe41f38c..1f295c8b3 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -215,7 +215,7 @@ sys_sigaltstack_wrapper: sys_mmap2: #if PAGE_SHIFT > 12 tst r5, #PGOFF_MASK - moveq r5, r5, lsr #PGOFF_SHIFT + moveq r5, r5, lsr #PAGE_SHIFT - 12 streq r5, [sp, #4] beq do_mmap2 mov r0, #-EINVAL diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 16b8e59ea..7cbec1406 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -65,9 +65,9 @@ inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index ee111801f..58106bff6 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -54,9 +54,3 @@ ifneq ($(MACHINE),ebsa110) endif include $(TOPDIR)/Rules.make - -constants.h: getconsdata.o extractconstants.pl - $(PERL) extractconstants.pl $(OBJDUMP) > $@ - -getconsdata.o: getconsdata.c - $(CC) $(CFLAGS) -c getconsdata.c diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S index d7cf6fe45..b930b613d 100644 --- a/arch/arm/lib/copy_page.S +++ b/arch/arm/lib/copy_page.S @@ -11,7 +11,7 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" +#include <asm/constants.h> .text .align 5 diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index 3799ccaec..9b5af1409 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -11,7 +11,7 @@ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/errno.h> -#include "constants.h" +#include <asm/constants.h> .text diff --git a/arch/arm/lib/extractconstants.pl b/arch/arm/lib/extractconstants.pl deleted file mode 100644 index 8c96b3f28..000000000 --- a/arch/arm/lib/extractconstants.pl +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -$OBJDUMP=$ARGV[0]; - -sub swapdata { - local ($num) = @_; - - return substr($num, 6, 2).substr($num, 4, 2).substr ($num, 2, 2).substr ($num, 0, 2); -} - -open (DATA, $OBJDUMP.' --full-contents --section=.data getconsdata.o | grep \'^ 00\' |') || - die ('Cant objdump!'); -while (<DATA>) { - ($addr, $data0, $data1, $data2, $data3) = split (' '); - $dat[hex($addr)] = hex(&swapdata($data0)); - $dat[hex($addr)+4] = hex(&swapdata($data1)); - $dat[hex($addr)+8] = hex(&swapdata($data2)); - $dat[hex($addr)+12] = hex(&swapdata($data3)); -} -close (DATA); - -open (DATA, $OBJDUMP.' --syms getconsdata.o |') || die ('Cant objdump!'); -while (<DATA>) { - /elf32/ && ( $elf = 1 ); - /a.out/ && ( $aout = 1 ); - next if ($aout && ! / 07 /); - next if ($elf && ! (/^0*0...... g/ && /.data/)); - next if (!$aout && !$elf); - - if ($aout) { - ($addr, $flags, $sect, $a1, $a2, $a3, $name) = split (' '); - $nam[hex($addr)] = substr($name, 1); - } - if ($elf) { - chomp; - $addr = substr ($_, 0, index($_, " ")); - $name = substr ($_, rindex($_, " ") + 1); - $nam[hex($addr)] = $name; - } -} -close (DATA); - -print "/*\n * *** This file is automatically generated from getconsdata.c. Do not edit! ***\n */\n"; -for ($i = 0; $i < hex($addr)+4; $i += 4) { - print "#define $nam[$i] $dat[$i]\n"; -} diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c deleted file mode 100644 index ee8040be7..000000000 --- a/arch/arm/lib/getconsdata.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/arch/arm/lib/getconsdata.c - * - * Copyright (C) 1995-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/config.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/pgtable.h> -#include <asm/uaccess.h> - -/* - * Make sure that the compiler and target are compatible - */ -#if (defined(__APCS_32__) && defined(CONFIG_CPU_26)) -#error Your compiler targets APCS-32 but this kernel requires APCS-26. -#endif -#if (defined(__APCS_26__) && defined(CONFIG_CPU_32)) -#error Your compiler targets APCS-26 but this kernel requires APCS-32. -#endif - -#undef PAGE_READONLY - -#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) -#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n) - -unsigned long TSK_SIGPENDING = OFF_TSK(sigpending); -unsigned long TSK_ADDR_LIMIT = OFF_TSK(addr_limit); -unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched); -unsigned long TSK_PTRACE = OFF_TSK(ptrace); -unsigned long TSK_USED_MATH = OFF_TSK(used_math); - -unsigned long TSS_SAVE = OFF_TSK(thread.save); -unsigned long TSS_FPESAVE = OFF_TSK(thread.fpstate.soft.save); -#ifdef CONFIG_CPU_32 -unsigned long TSS_DOMAIN = OFF_TSK(thread.domain); -#endif - -#ifdef _PAGE_PRESENT -unsigned long PAGE_PRESENT = _PAGE_PRESENT; -#endif -#ifdef _PAGE_RW -unsigned long PAGE_RW = _PAGE_RW; -#endif -#ifdef _PAGE_USER -unsigned long PAGE_USER = _PAGE_USER; -#endif -#ifdef _PAGE_ACCESSED -unsigned long PAGE_ACCESSED = _PAGE_ACCESSED; -#endif -#ifdef _PAGE_DIRTY -unsigned long PAGE_DIRTY = _PAGE_DIRTY; -#endif -#ifdef _PAGE_READONLY -unsigned long PAGE_READONLY = _PAGE_READONLY; -#endif -#ifdef _PAGE_NOT_USER -unsigned long PAGE_NOT_USER = _PAGE_NOT_USER; -#endif -#ifdef _PAGE_OLD -unsigned long PAGE_OLD = _PAGE_OLD; -#endif -#ifdef _PAGE_CLEAN -unsigned long PAGE_CLEAN = _PAGE_CLEAN; -#endif - -#ifdef PTE_TYPE_SMALL -unsigned long HPTE_TYPE_SMALL = PTE_TYPE_SMALL; -unsigned long HPTE_AP_READ = PTE_AP_READ; -unsigned long HPTE_AP_WRITE = PTE_AP_WRITE; -#endif - -#ifdef L_PTE_PRESENT -unsigned long LPTE_PRESENT = L_PTE_PRESENT; -unsigned long LPTE_YOUNG = L_PTE_YOUNG; -unsigned long LPTE_BUFFERABLE = L_PTE_BUFFERABLE; -unsigned long LPTE_CACHEABLE = L_PTE_CACHEABLE; -unsigned long LPTE_USER = L_PTE_USER; -unsigned long LPTE_WRITE = L_PTE_WRITE; -unsigned long LPTE_EXEC = L_PTE_EXEC; -unsigned long LPTE_DIRTY = L_PTE_DIRTY; -#endif - -unsigned long PAGE_SZ = PAGE_SIZE; - -unsigned long KSWI_BASE = 0x900000; -unsigned long KSWI_SYS_BASE = 0x9f0000; -unsigned long SYS_ERROR0 = 0x9f0000; -unsigned long PGOFF_SHIFT = PAGE_SHIFT - 12; -unsigned long PGOFF_MASK = (1 << (PAGE_SHIFT - 12)) - 1; diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index e652b5276..87342f299 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -11,7 +11,6 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" .text diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile new file mode 100644 index 000000000..0b6166c87 --- /dev/null +++ b/arch/arm/mach-integrator/Makefile @@ -0,0 +1,24 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +USE_STANDARD_AS_RULE := true + +O_TARGET := integrator.o + +# Object file lists. + +obj-y := arch.o irq.o mm.o time.o +obj-m := +obj-n := +obj- := + +export-objs := leds.o + +obj-$(CONFIG_LEDS) += leds.o +obj-$(CONFIG_PCI) += pci_v3.o pci.o + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c new file mode 100644 index 000000000..a31549c07 --- /dev/null +++ b/arch/arm/mach-integrator/arch.c @@ -0,0 +1,70 @@ +/* + * linux/arch/arm/mach-integrator/arch.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/amba_kmi.h> + +extern void integrator_map_io(void); +extern void integrator_init_irq(void); + +#ifdef CONFIG_KMI_KEYB +static struct kmi_info integrator_keyboard __initdata = { + base: IO_ADDRESS(KMI0_BASE), + irq: IRQ_KMIINT0, + divisor: 24 / 8 - 1, + type: KMI_KEYBOARD, +}; + +static struct kmi_info integrator_mouse __initdata = { + base: IO_ADDRESS(KMI1_BASE), + irq: IRQ_KMIINT1, + divisor: 24 / 8 - 1, + type: KMI_MOUSE, +}; +#endif + +static void __init +integrator_fixup(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_KMI_KEYB + register_kmi(&integrator_keyboard); + register_kmi(&integrator_mouse); +#endif +} + +MACHINE_START(INTEGRATOR, "ARM-Integrator") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) + BOOT_PARAMS(0x00000100) + FIXUP(integrator_fixup) + MAPIO(integrator_map_io) + INITIRQ(integrator_init_irq) +MACHINE_END diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c new file mode 100644 index 000000000..aa5ba5a43 --- /dev/null +++ b/arch/arm/mach-integrator/dma.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-integrator/dma.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/malloc.h> +#include <linux/mman.h> +#include <linux/init.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/hardware.h> + +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +} diff --git a/arch/arm/mach-integrator/irq.c b/arch/arm/mach-integrator/irq.c new file mode 100644 index 000000000..546ade980 --- /dev/null +++ b/arch/arm/mach-integrator/irq.c @@ -0,0 +1,71 @@ +/* + * linux/arch/arm/mach-integrator/irq.c + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> + +/* + * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx + * is the (PA >> 12). + * + * Setup a VA for the Integrator interrupt controller (for header #0, + * just for now). + */ +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) +#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET + +#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) + +static void sc_mask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); +} + +static void sc_unmask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); +} + +void __init integrator_init_irq(void) +{ + unsigned int i; + + for (i = 0; i < NR_IRQS; i++) { + if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { + irq_desc[i].valid = 1; + irq_desc[i].probe_ok = 1; + irq_desc[i].mask_ack = sc_mask_irq; + irq_desc[i].mask = sc_mask_irq; + irq_desc[i].unmask = sc_unmask_irq; + } + } + + /* Disable all interrupts initially. */ + /* Do the core module ones */ + __raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + + /* do the header card stuff next */ + __raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + __raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); +} diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c new file mode 100644 index 000000000..8fe7df14a --- /dev/null +++ b/arch/arm/mach-integrator/leds.c @@ -0,0 +1,94 @@ +/* + * linux/arch/arm/mach-integrator/leds.c + * + * Integrator LED control routines + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/mach-types.h> + +static int saved_leds; + +static void integrator_leds_event(led_event_t ledevt) +{ + unsigned long flags; + const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); + const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) + + INTEGRATOR_HDR_CTRL_OFFSET; + unsigned int ctrl; + unsigned int update_alpha_leds; + + // yup, change the LEDs + local_irq_save(flags); + update_alpha_leds = 0; + + switch(ledevt) { + case led_idle_start: + ctrl = __raw_readl(hdr_ctrl); + ctrl &= ~INTEGRATOR_HDR_CTRL_LED; + __raw_writel(ctrl, hdr_ctrl); + break; + + case led_idle_end: + ctrl = __raw_readl(hdr_ctrl); + ctrl |= INTEGRATOR_HDR_CTRL_LED; + __raw_writel(ctrl, hdr_ctrl); + break; + + case led_timer: + saved_leds ^= GREEN_LED; + update_alpha_leds = 1; + break; + + case led_red_on: + saved_leds |= RED_LED; + update_alpha_leds = 1; + break; + + case led_red_off: + saved_leds &= ~RED_LED; + update_alpha_leds = 1; + break; + + default: + break; + } + + if (update_alpha_leds) { + while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1); + __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET); + } + local_irq_restore(flags); +} + +static int __init leds_init(void) +{ + if (machine_is_integrator()) + leds_event = integrator_leds_event; + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-integrator/mm.c b/arch/arm/mach-integrator/mm.c new file mode 100644 index 000000000..234228c45 --- /dev/null +++ b/arch/arm/mach-integrator/mm.c @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/mach-integrator/mm.c + * + * Extra MM routines for the ARM Integrator board + * + * Copyright (C) 1999,2000 Arm Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> + +/* + * Logical Physical + * e8000000 40000000 PCI memory + * ec000000 62000000 PCI config space + * ed000000 61000000 PCI V3 regs + * ee000000 60000000 PCI IO + * ef000000 Cache flush + * f1000000 10000000 Core module registers + * f1100000 11000000 System controller registers + * f1200000 12000000 EBI registers + * f1300000 13000000 Counter/Timer + * f1400000 14000000 Interrupt controller + * f1500000 15000000 RTC + * f1600000 16000000 UART 0 + * f1700000 17000000 UART 1 + * f1800000 18000000 Keyboard + * f1900000 19000000 Mouse + * f1a00000 1a000000 Debug LEDs + * f1b00000 1b000000 GPIO + */ + +static struct map_desc integrator_io_desc[] __initdata = { + { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_KBD_BASE), INTEGRATOR_KBD_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M , DOMAIN_IO, 0, 1}, + { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M , DOMAIN_IO, 0, 1}, + { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K , DOMAIN_IO, 0, 1}, + { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K , DOMAIN_IO, 0, 1}, + LAST_DESC +}; + +void __init integrator_map_io(void) +{ + iotable_init(integrator_io_desc); +} diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c new file mode 100644 index 000000000..9339ceb1b --- /dev/null +++ b/arch/arm/mach-integrator/pci.c @@ -0,0 +1,119 @@ +/* + * linux/arch/arm/mach-integrator/pci-integrator.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * PCI functions for Integrator + */ +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/pci.h> + +/* + * A small note about bridges and interrupts. The DECchip 21050 (and + * later) adheres to the PCI-PCI bridge specification. This says that + * the interrupts on the other side of a bridge are swizzled in the + * following manner: + * + * Dev Interrupt Interrupt + * Pin on Pin on + * Device Connector + * + * 4 A A + * B B + * C C + * D D + * + * 5 A B + * B C + * C D + * D A + * + * 6 A C + * B D + * C A + * D B + * + * 7 A D + * B A + * C B + * D C + * + * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A. + * Thus, each swizzle is ((pin-1) + (device#-4)) % 4 + * + * The following code swizzles for exactly one bridge. + */ +static inline int bridge_swizzle(int pin, unsigned int slot) +{ + return (pin + slot) & 3; +} + +/* + * This routine handles multiple bridges. + */ +static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp) +{ + int pin = *pinp; + + if (pin == 0) + pin = 1; + + pin -= 1; + while (dev->bus->self) { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* + * move up the chain of bridges, swizzling as we go. + */ + dev = dev->bus->self; + } + *pinp = pin + 1; + + return PCI_SLOT(dev->devfn); +} + +static int irq_tab[4] __initdata = { + IRQ_PCIINT0, IRQ_PCIINT1, IRQ_PCIINT2, IRQ_PCIINT3 +}; + +/* + * map the specified device/slot/pin to an IRQ. This works out such + * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. + */ +static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int intnr = ((slot - 9) + (pin - 1)) & 3; + + return irq_tab[intnr]; +} + +extern void pci_v3_init(struct arm_pci_sysdata *); + +struct hw_pci integrator_pci __initdata = { + init: pci_v3_init, + swizzle: integrator_swizzle, + map_irq: integrator_map_irq, +}; diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c new file mode 100644 index 000000000..1046e2826 --- /dev/null +++ b/arch/arm/mach-integrator/pci_v3.c @@ -0,0 +1,460 @@ +/* + * linux/arch/arm/mach-integrator/pci_v3.c + * + * PCI functions for V3 host PCI bridge + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/pci.h> + +#include <asm/hardware/pci_v3.h> + +/* + * The V3 PCI interface chip in Integrator provides several windows from + * local bus memory into the PCI memory areas. Unfortunately, there + * are not really enough windows for our usage, therefore we reuse + * one of the windows for access to PCI configuration space. The + * memory map is as follows: + * + * Local Bus Memory Usage + * + * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable + * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable + * 60000000 - 60FFFFFF PCI IO. 16M + * 68000000 - 68FFFFFF PCI Configuration. 16M + * + * There are three V3 windows, each described by a pair of V3 registers. + * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2. + * Base0 and Base1 can be used for any type of PCI memory access. Base2 + * can be used either for PCI I/O or for I20 accesses. By default, uHAL + * uses this only for PCI IO space. + * + * PCI Memory is mapped so that assigned addresses in PCI Memory match + * local bus memory addresses. In other words, if a PCI device is assigned + * address 80200000 then that address is a valid local bus address as well + * as a valid PCI Memory address. PCI IO addresses are mapped to start + * at zero. This means that local bus address 60000000 maps to PCI IO address + * 00000000 and so on. Device driver writers need to be aware of this + * distinction. + * + * Normally these spaces are mapped using the following base registers: + * + * Usage Local Bus Memory Base/Map registers used + * + * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 + * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1 + * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 + * Cfg 68000000 - 68FFFFFF + * + * This means that I20 and PCI configuration space accesses will fail. + * When PCI configuration accesses are needed (via the uHAL PCI + * configuration space primitives) we must remap the spaces as follows: + * + * Usage Local Bus Memory Base/Map registers used + * + * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 + * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0 + * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 + * Cfg 68000000 - 68FFFFFF LB_BASE1/LB_MAP1 + * + * To make this work, the code depends on overlapping windows working. + * The V3 chip translates an address by checking its range within + * each of the BASE/MAP pairs in turn (in ascending register number + * order). It will use the first matching pair. So, for example, + * if the same address is mapped by both LB_BASE0/LB_MAP0 and + * LB_BASE1/LB_MAP1, the V3 will use the translation from + * LB_BASE0/LB_MAP0. + * + * To allow PCI Configuration space access, the code enlarges the + * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes + * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can + * be remapped for use by configuration cycles. + * + * At the end of the PCI Configuration space accesses, + * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window + * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to + * reveal the now restored LB_BASE1/LB_MAP1 window. + * + * NOTE: We do not set up I2O mapping. I suspect that this is only + * for an intelligent (target) device. Using I2O disables most of + * the mappings into PCI memory. + */ + +// V3 access routines +#define _V3Write16(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o)) +#define _V3Read16(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o))) + +#define _V3Write32(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o)) +#define _V3Read32(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o))) + +/*============================================================================ + * + * routine: uHALir_PCIMakeConfigAddress() + * + * parameters: bus = which bus + * device = which device + * function = which function + * offset = configuration space register we are interested in + * + * description: this routine will generate a platform dependant config + * address. + * + * calls: none + * + * returns: configuration address to play on the PCI bus + * + * To generate the appropriate PCI configuration cycles in the PCI + * configuration address space, you present the V3 with the following pattern + * (which is very nearly a type 1 (except that the lower two bits are 00 and + * not 01). In order for this mapping to work you need to set up one of + * the local to PCI aperatures to 16Mbytes in length translating to + * PCI configuration space starting at 0x0000.0000. + * + * PCI configuration cycles look like this: + * + * Type 0: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:11 Device select bit. + * 10:8 Function number + * 7:2 Register number + * + * Type 1: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:24 reserved + * 23:16 bus number (8 bits = 128 possible buses) + * 15:11 Device number (5 bits) + * 10:8 function number + * 7:2 register number + * + */ +static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED; + +#define PCI_BUS_NONMEM_START 0x00000000 +#define PCI_BUS_NONMEM_SIZE 0x10000000 + +#define PCI_BUS_PREMEM_START 0x10000000 +#define PCI_BUS_PREMEM_SIZE 0x10000000 + +#if PCI_BUS_NONMEM_START & 0x000fffff +#error PCI_BUS_NONMEM_START must be megabyte aligned +#endif +#if PCI_BUS_PREMEM_START & 0x000fffff +#error PCI_BUS_PREMEM_START must be megabyte aligned +#endif + +static unsigned long v3_open_config_window(struct pci_dev *dev, int offset) +{ + unsigned int address, mapaddress, busnr; + + busnr = dev->bus->number; + + /* + * Trap out illegal values + */ + if (offset > 255) + BUG(); + if (busnr > 255) + BUG(); + if (dev->devfn > 255) + BUG(); + + if (busnr == 0) { + int slot = PCI_SLOT(dev->devfn); + + /* + * local bus segment so need a type 0 config cycle + * + * build the PCI configuration "address" with one-hot in + * A31-A11 + * + * mapaddress: + * 3:1 = config cycle (101) + * 0 = PCI A1 & A0 are 0 (0) + */ + address = PCI_FUNC(dev->devfn) << 8; + mapaddress = 0x0a; + + if (slot > 12) + /* + * high order bits are handled by the MAP register + */ + mapaddress |= 1 << (slot - 4); + else + /* + * low order bits handled directly in the address + */ + address |= 1 << (slot + 11); + } else { + /* + * not the local bus segment so need a type 1 config cycle + * + * address: + * 23:16 = bus number + * 15:11 = slot number (7:3 of devfn) + * 10:8 = func number (2:0 of devfn) + * + * mapaddress: + * 3:1 = config cycle (101) + * 0 = PCI A1 & A0 from host bus (1) + */ + mapaddress = 0x0b; + address = (busnr << 16) | (dev->devfn << 8); + } + + /* + * Set up base0 to see all 512Mbytes of memory space (not prefetchable), this + * frees up base1 for re-use by configuration memory + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x90 | V3_LB_BASE_M_ENABLE); + + /* + * Set up base1/map1 to point into configuration space. + */ + _V3Write32(V3_LB_BASE1, (PHYS_PCI_CONFIG_BASE & 0xFFF00000) | 0x40 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, mapaddress); + + return PCI_CONFIG_VADDR + address + offset; +} + +static void v3_close_config_window(void) +{ + /* + * Reassign base1 for use by prefetchable PCI memory + */ + _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, ((PCI_BUS_PREMEM_START & 0xFFF00000) >> 16) | 0x0006); + + /* + * And shrink base0 back to a 256M window (NOTE: MAP0 already correct) + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x80 | V3_LB_BASE_M_ENABLE); +} + +static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val) +{ + unsigned long addr; + unsigned long flags; + u8 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readb(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val) +{ + unsigned long addr; + unsigned long flags; + u16 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readw(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val) +{ + unsigned long addr; + unsigned long flags; + u32 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readl(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writeb(val, addr); + __raw_readb(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_word(struct pci_dev *dev, int where, u16 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writew(val, addr); + __raw_readw(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writel(val, addr); + __raw_readl(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_v3_ops = { + read_byte: v3_read_config_byte, + read_word: v3_read_config_word, + read_dword: v3_read_config_dword, + write_byte: v3_write_config_byte, + write_word: v3_write_config_word, + write_dword: v3_write_config_dword, +}; + +static struct resource non_mem = { + name: "PCI non-prefetchable", + start: PCI_BUS_NONMEM_START, + end: PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1, + flags: IORESOURCE_MEM, +}; + +static struct resource pre_mem = { + name: "PCI prefetchable", + start: PCI_BUS_PREMEM_START, + end: PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1, + flags: IORESOURCE_MEM | IORESOURCE_PREFETCH, +}; + +/* + * V3_LB_BASE? - local bus address + * V3_LB_MAP? - pci bus address + */ +void __init pci_v3_init(struct arm_pci_sysdata *sysdata) +{ + struct pci_bus *bus; + unsigned int pci_cmd; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + + /* + * Setup window 0 - PCI non-prefetchable memory + * Local: 0x40000000 Bus: 0x00000000 Size: 256MB + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xfff00000) | 0x80 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP0, (PCI_BUS_NONMEM_START >> 16) | 0x0006); + + /* + * Setup window 1 - PCI prefetchable memory + * Local: 0x50000000 Bus: 0x10000000 Size: 256MB + */ + _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, (PCI_BUS_PREMEM_START >> 16) | 0x0006); + + /* + * Setup window 2 - PCI IO + */ +// _V3Write32(V3_LB_BASE2, (PHYS_PCI_IO_BASE & 0xff000000) | V3_LB_BASE_M_ENABLE); +// _V3Write16(V3_LB_MAP2, 0); + + spin_unlock_irqrestore(&v3_lock, flags); + + bus = pci_scan_bus(0, &pci_v3_ops, sysdata); + + if (request_resource(&iomem_resource, &non_mem)) + printk("PCI: unable to allocate non-prefetchable memory region"); + if (request_resource(&iomem_resource, &pre_mem)) + printk("PCI: unable to allocate prefetchable memory region"); + + /* + * bus->resource[0] is the IO resource for this bus + * bus->resource[1] is the mem resource for this bus + * bus->resource[2] is the prefetch mem resource for this bus + */ + bus->resource[1] = &non_mem; + bus->resource[2] = &pre_mem; + + pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + + pci_cmd |= sysdata->bus[0].features; + + _V3Write16(V3_PCI_CMD, pci_cmd); + + printk("PCI: Fast back to back transfers %sabled\n", + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? + "en" : "dis"); +} diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c new file mode 100644 index 000000000..11dbd96e5 --- /dev/null +++ b/arch/arm/mach-integrator/time.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-integrator/time.c + * + * Copyright (C) 2000 Deep Blue Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> + +#include <asm/hardware.h> + +#define RTC_DR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)) +#define RTC_MR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)) +#define RTC_STAT (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)) +#define RTC_EOI (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)) +#define RTC_LR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12)) +#define RTC_CR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16)) + +#define RTC_CR_MIE 0x00000001 + +extern int (*set_rtc)(void); + +static int integrator_set_rtc(void) +{ + RTC_LR = xtime.tv_sec; + return 1; +} + +static int integrator_rtc_init(void) +{ + RTC_CR = 0; + RTC_EOI = 0; + + xtime.tv_sec = RTC_DR; + + set_rtc = integrator_set_rtc; + + return 0; +} + +__initcall(integrator_rtc_init); diff --git a/arch/arm/mach-sa1100/arch.c b/arch/arm/mach-sa1100/arch.c index 32ac72379..89123d122 100644 --- a/arch/arm/mach-sa1100/arch.c +++ b/arch/arm/mach-sa1100/arch.c @@ -54,7 +54,7 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params, if (machine_is_assabet()) { /* * On Assabet, we must probe for the Neponset board *before* - * paging_init() has occured to actually determine the amount + * paging_init() has occurred to actually determine the amount * of RAM available. */ extern void map_sa1100_gpio_regs(void); diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index f79b618a2..b836cfe89 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -223,9 +223,9 @@ int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); fault = __do_page_fault(mm, addr, mode, tsk); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); ret: /* diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index 023fee8e0..5695b2ede 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -9,6 +9,7 @@ * * Extra MM routines for RiscPC architecture */ +#include <linux/types.h> #include <linux/init.h> #include <asm/hardware.h> diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index 54fe435c6..01e3725c8 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -199,7 +199,7 @@ pg_data_t sa1100_node_data[4] = /* * On Assabet, we must probe for the Neponset board *before* paging_init() - * has occured to actually determine the amount of RAM available. To do so, + * has occurred to actually determine the amount of RAM available. To do so, * we map the appropriate IO section in the page table here in order to * access GPIO registers. */ diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index 76377cf9c..a550ac9d8 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -14,8 +14,8 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> -#include "../lib/constants.h" /* * MEMC workhorse code. It's both a horse which things it's a pig. diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index d26a98f75..a9a682b5f 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -12,8 +12,8 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> -#include "../lib/constants.h" /* * Function: arm6_7_cache_clean_invalidate_all (void) @@ -29,10 +29,10 @@ ENTRY(cpu_arm6_cache_clean_invalidate_all) ENTRY(cpu_arm7_cache_clean_invalidate_all) ENTRY(cpu_arm6_cache_clean_invalidate_range) ENTRY(cpu_arm7_cache_clean_invalidate_range) -ENTRY(cpu_arm6_invalidate_icache_range) -ENTRY(cpu_arm7_invalidate_icache_range) -ENTRY(cpu_arm6_invalidate_icache_page) -ENTRY(cpu_arm7_invalidate_icache_page) +ENTRY(cpu_arm6_icache_invalidate_range) +ENTRY(cpu_arm7_icache_invalidate_range) +ENTRY(cpu_arm6_icache_invalidate_page) +ENTRY(cpu_arm7_icache_invalidate_page) ENTRY(cpu_arm6_dcache_clean_range) ENTRY(cpu_arm7_dcache_clean_range) ENTRY(cpu_arm6_dcache_invalidate_range) @@ -410,8 +410,8 @@ ENTRY(arm6_processor_functions) .word cpu_arm6_dcache_clean_entry /* icache */ - .word cpu_arm6_invalidate_icache_range - .word cpu_arm6_invalidate_icache_page + .word cpu_arm6_icache_invalidate_range + .word cpu_arm6_icache_invalidate_page /* tlb */ .word cpu_arm6_tlb_invalidate_all @@ -449,8 +449,8 @@ ENTRY(arm7_processor_functions) .word cpu_arm7_dcache_clean_entry /* icache */ - .word cpu_arm7_invalidate_icache_range - .word cpu_arm7_invalidate_icache_page + .word cpu_arm7_icache_invalidate_range + .word cpu_arm7_icache_invalidate_page /* tlb */ .word cpu_arm7_tlb_invalidate_all diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 77b689bdf..4cc7509c4 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -32,9 +32,9 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* * Function: arm720_cache_clean_invalidate_all (void) diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 6f1f11601..d3643c400 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -25,9 +25,9 @@ #include <linux/linkage.h> #include <linux/config.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* * This is the maximum size of an area which will be invalidated diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 45b0a31fe..3d75d7489 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -19,9 +19,9 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* This is the maximum size of an area which will be flushed. If the area * is larger than this, then we flush the whole cache diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S index 5108ce63d..d96deaae2 100644 --- a/arch/arm/nwfpe/entry26.S +++ b/arch/arm/nwfpe/entry26.S @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "../lib/constants.h" +#include <asm/constants.h> /* This is the kernel's entry point into the floating point emulator. It is called from the kernel with code similar to this: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile new file mode 100644 index 000000000..698083c67 --- /dev/null +++ b/arch/arm/tools/Makefile @@ -0,0 +1,36 @@ +# +# linux/arch/arm/tools/Makefile +# +# Copyright (C) 2001 Russell King +# + +all: $(TOPDIR)/include/asm-arm/mach-types.h \ + $(TOPDIR)/include/asm-arm/constants.h + +$(TOPDIR)/include/asm-arm/mach-types.h: mach-types gen-mach-types + awk -f gen-mach-types mach-types > $@ + +# Generate the constants.h header file using the compiler. We get +# the compiler to spit out assembly code, and then mundge it into +# what we want. + +$(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c + $(CC) $(CFLAGS) -S -o - getconstants.c | \ + sed 's/^\(#define .* \)#\(.*\)/\1\2/;/^#define/!d' | \ + cat constants-hdr - > $@.tmp + cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp + +# Build our dependencies, and then generate the constants and +# mach-types header files. If we do it now, mkdep will pick +# the dependencies up later on when it runs through the other +# directories + +dep: + $(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend + $(MAKE) all + +.PHONY: all dep + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/arch/arm/tools/constants-hdr b/arch/arm/tools/constants-hdr new file mode 100644 index 000000000..fd18d7cb8 --- /dev/null +++ b/arch/arm/tools/constants-hdr @@ -0,0 +1,5 @@ +/* + * This file is automatically generated from arch/arm/tools/getconstants.c. + * Do not edit! Only include this file in assembly (.S) files! + */ + diff --git a/arch/arm/tools/getconstants.c b/arch/arm/tools/getconstants.c new file mode 100644 index 000000000..3fd2d3e7c --- /dev/null +++ b/arch/arm/tools/getconstants.c @@ -0,0 +1,72 @@ +/* + * linux/arch/arm/tools/getconsdata.c + * + * Copyright (C) 1995-2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/pgtable.h> +#include <asm/uaccess.h> + +/* + * Make sure that the compiler and target are compatible + */ +#if (defined(__APCS_32__) && defined(CONFIG_CPU_26)) +#error Your compiler targets APCS-32 but this kernel requires APCS-26. +#endif +#if (defined(__APCS_26__) && defined(CONFIG_CPU_32)) +#error Your compiler targets APCS-26 but this kernel requires APCS-32. +#endif + +#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) + +#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off)) + +void func(void) +{ +DEFN("TSK_SIGPENDING", OFF_TSK(sigpending)); +DEFN("TSK_ADDR_LIMIT", OFF_TSK(addr_limit)); +DEFN("TSK_NEED_RESCHED", OFF_TSK(need_resched)); +DEFN("TSK_PTRACE", OFF_TSK(ptrace)); +DEFN("TSK_USED_MATH", OFF_TSK(used_math)); + +DEFN("TSS_SAVE", OFF_TSK(thread.save)); +DEFN("TSS_FPESAVE", OFF_TSK(thread.fpstate.soft.save)); + +#ifdef CONFIG_CPU_32 +DEFN("TSS_DOMAIN", OFF_TSK(thread.domain)); + +DEFN("HPTE_TYPE_SMALL", PTE_TYPE_SMALL); +DEFN("HPTE_AP_READ", PTE_AP_READ); +DEFN("HPTE_AP_WRITE", PTE_AP_WRITE); + +DEFN("LPTE_PRESENT", L_PTE_PRESENT); +DEFN("LPTE_YOUNG", L_PTE_YOUNG); +DEFN("LPTE_BUFFERABLE", L_PTE_BUFFERABLE); +DEFN("LPTE_CACHEABLE", L_PTE_CACHEABLE); +DEFN("LPTE_USER", L_PTE_USER); +DEFN("LPTE_WRITE", L_PTE_WRITE); +DEFN("LPTE_EXEC", L_PTE_EXEC); +DEFN("LPTE_DIRTY", L_PTE_DIRTY); +#endif + +#ifdef CONFIG_CPU_26 +DEFN("PAGE_PRESENT", _PAGE_PRESENT); +DEFN("PAGE_READONLY", _PAGE_READONLY); +DEFN("PAGE_NOT_USER", _PAGE_NOT_USER); +DEFN("PAGE_OLD", _PAGE_OLD); +DEFN("PAGE_CLEAN", _PAGE_CLEAN); +#endif + +DEFN("PAGE_SZ", PAGE_SIZE); + +DEFN("KSWI_BASE", 0x900000); +DEFN("KSWI_SYS_BASE", 0x9f0000); +DEFN("SYS_ERROR0", 0x9f0000); +} diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index ff7ccec77..c4f540a25 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -4,7 +4,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Mon Nov 20 22:59:11 2000 +# Last update: Fri Feb 9 22:27:32 2001 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -48,13 +48,23 @@ accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 netport SA1100_NETPORT NETPORT 38 pangolin SA1100_PANGOLIN PANGOLIN 39 yopy SA1100_YOPY YOPY 40 -sa1100 SA1100_SA1100 SA1100 41 -huw_webpanel ARCH_HUW_WEBPANEL HUW_WEBPANEL 42 +coolidge SA1100_COOLIDGE coolidge 41 +huw_webpanel SA1100_HUW_WEBPANEL HUW_WEBPANEL 42 spotme ARCH_SPOTME SPOTME 43 freebird ARCH_FREEBIRD FREEBIRD 44 ti925 ARCH_TI925 TI925 45 riscstation ARCH_RISCSTATION RISCSTATION 46 cavy SA1100_CAVY CAVY 47 +jornada720 SA1100_JORNADA720 JORNADA720 48 +omnimeter SA1100_OMNIMETER OMNIMETER 49 +edb7211 ARCH_EDB7211 EDB7211 50 +citygo SA1100_CITYGO CITYGO 51 +pfs168 SA1100_PFS168 PFS168 52 +spot SA1100_SPOT SPOT 53 +flexanet ARCH_FLEXANET FLEXANET 54 +webpal ARCH_WEBPAL WEBPAL 55 +linpda SA1100_LINPDA LINPDA 56 +anakin ARCH_ANAKIN ANAKIN 57 # The following are unallocated empeg SA1100_EMPEG EMPEG diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in index 10661f414..08544b314 100644 --- a/arch/arm/vmlinux-armv.lds.in +++ b/arch/arm/vmlinux-armv.lds.in @@ -45,18 +45,22 @@ SECTIONS *(.glue_7) *(.glue_7t) *(.kstrtab) - . = ALIGN(16); - __start___ex_table = .; /* Exception table */ + *(.got) /* Global offset table */ + + _etext = .; /* End of text section */ + } + + . = ALIGN(16); + __ex_table : { /* Exception table */ + __start___ex_table = .; *(__ex_table) __stop___ex_table = .; + } - __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { /* Kernel symbol table */ + __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; - - *(.got) /* Global offset table */ - - _etext = .; /* End of text section */ } . = ALIGN(8192); |